{"id":6170,"date":"2017-03-01T09:56:06","date_gmt":"2017-03-01T14:56:06","guid":{"rendered":"http:\/\/appcrawler.com\/wordpress\/?p=6170"},"modified":"2017-03-02T07:26:32","modified_gmt":"2017-03-02T12:26:32","slug":"adding-a-system-call-to-linux","status":"publish","type":"post","link":"http:\/\/appcrawler.com\/wordpress\/2017\/03\/01\/adding-a-system-call-to-linux\/","title":{"rendered":"Adding a system call to Linux"},"content":{"rendered":"<p>These are *old* notes (2010 or so).  I remember doing this, and it was interesting enough that I thought I should post it.  It may be easier now.<\/p>\n<p>I experimented with the following on CentOS 5.1 running on an i686 machine.<\/p>\n<p>Firstly, I visited http:\/\/www.kernel.org\/pub\/linux\/kernel\/v2.6\/ and explored available kernel source codes and decided to download 2.6.18.8. gcc was already installed on my system, so I skipped that step.<\/p>\n<p>In the terminal&#8230;<\/p>\n<pre>\r\n#cd \/usr\/src\r\n#tar -xjvf linux-2.6.18.8.tar.bz2\r\n<\/pre>\n<p>The source code was uncompressed into the directory \/usr\/src\/linux-2.6.18.8.  I used the configuration of my current kernel as a basis of my new kernel. So, I copied the existing configuration to \/usr\/src\/linux-2.6.18.8 by&#8230;<\/p>\n<pre>\r\n#cd \/usr\/src\/linux-2.6.18.8\r\n#make clean && make mrproper\r\n#cp \/boot\/config-`uname -r` .\/.config\r\n<\/pre>\n<p>I also could have used&#8230;<\/p>\n<pre>\r\n#cp \/boot\/config-2.6.18-53.el5 .\/.config\r\n<\/pre>\n<p>&#8230;instead of the last command.<\/p>\n<p>I chose to use menuconfig out of three possibilities: menuconfig, xconfig, gconfig<\/p>\n<pre>\r\n#make menuconfig\r\n<\/pre>\n<p>&#8230;which brought up the kernel configuration menu. I selected the option &#8220;Load an Alternate Configuration File&#8221;, typed &#8220;.config&#8221; and confirmed this (this is the .config file we copied from our current kernel&#8217;s configuration file).<br \/>\nThen I selected &#8220;General setup&#8221;, &#8220;Local version &#8211; append to kernel release&#8221;, respectively and typed &#8220;-blm334&#8221; which would be appended to the end of my newly created kernel. Then I exited by saving this new kernel configuration.<\/p>\n<p>Next was modifying the source code to add the system call &#8220;helloworld&#8221;.<br \/>\nI opened the file \/usr\/src\/linux-2.6.18.8\/include\/asm-i386\/unistd.h and added the line:<\/p>\n<pre>\r\n\"#define __NR_helloworld 318\"\r\n<\/pre>\n<p>Additionally, I incremented the number of system calls. I changed <\/p>\n<pre>\r\n\"#define NR_syscalls 318\" as \"#define NR_syscalls 319\"\r\n<\/pre>\n<p>I opened the file \/usr\/src\/linux-2.6.18.8\/arch\/i386\/kernel\/syscall_table.S and appended the line:<\/p>\n<pre>\r\n\" .long sys_helloworld\"\r\n<\/pre>\n<p>Then I needed to choose a place for my system call source code. Although it was not reasonable, since fs\/ includes the calls about the file system, I chose to insert it into \/usr\/src\/linux-2.6.18.8\/fs\/.<\/p>\n<p>I created a file &#8220;helloworld.c&#8221; and inside it, I wrote:<\/p>\n<pre>\r\n#include <linux\/linkage.h>\r\n#include <linux\/kernel.h>\r\n\r\nasmlinkage int sys_helloworld() {\r\n  printk( KERN_EMERG \"hello world!\" );\r\n  return 1;\r\n} \r\n<\/pre>\n<p>There was just one thing left before compiling the new kernel, modifying the Makefile, at which I got stuck indeed. I appended &#8220;helloworld.o&#8221; to the obj-y list so that it was finally:<\/p>\n<pre>\r\nobj-y := open.o read_write.o file_table.o buffer.o bio.o super.o \\\r\nblock_dev.o char_dev.o stat.o exec.o pipe.o namei.o fcntl.o \\\r\nioctl.o readdir.o select.o fifo.o locks.o dcache.o inode.o \\\r\nattr.o bad_inode.o file.o filesystems.o namespace.o aio.o \\\r\nseq_file.o xattr.o libfs.o fs-writeback.o mpage.o direct-io.o \\\r\nioprio.o pnode.o drop_caches.o splice.o sync.o helloworld.o\r\n<\/pre>\n<p>I returned to the terminal, inside the directory \/usr\/src\/linux-2.6.18.8<\/p>\n<pre>\r\n#make\r\n#make modules\r\n#make modules_install\r\n#make install\r\n<\/pre>\n<p>&#8230;which built the kernel, built the kernel modules, installed the kernel modules and installed the kernel, respectively. After hours of waiting for the compilation process, and relatively short installation process, I had the files<\/p>\n<pre>\r\n-rw-r--r-- 1 root root 64551 Nov 12 09:46 config-2.6.18-53.el5\r\ndrwxr-xr-x 2 root root 4096 Mar 21 00:32 grub\r\n-rw------- 1 root root 2410234 Mar 20 22:30 initrd-2.6.18-53.el5.img\r\n-rw------- 1 root root 2343918 Mar 21 00:23 initrd-2.6.18.8-blm334.img\r\n-rw-r--r-- 1 root root 80032 Nov 23 01:24 message\r\n-rw-r--r-- 1 root root 87586 Nov 12 09:46 symvers-2.6.18-53.el5.gz\r\nlrwxrwxrwx 1 root root 32 Mar 21 00:21 System.map -> \/boot\/System.map-2.6.18.8-blm334\r\n-rw-r--r-- 1 root root 903969 Nov 12 09:46 System.map-2.6.18-53.el5\r\n-rw-r--r-- 1 root root 862365 Mar 21 00:21 System.map-2.6.18.8-blm334\r\nlrwxrwxrwx 1 root root 29 Mar 21 00:21 vmlinuz -> \/boot\/vmlinuz-2.6.18.8-blm334\r\n-rw-r--r-- 1 root root 1791540 Nov 12 09:46 vmlinuz-2.6.18-53.el5\r\n-rw-r--r-- 1 root root 1610994 Mar 21 00:21 vmlinuz-2.6.18.8-blm334\r\n<\/pre>\n<p>under \/boot\/<\/p>\n<p>So, the files to boot the newly created kernel were ready. I was supposed to modify the content of the file \/boot\/grub\/grub.conf. However, when I opened it I realized that it was automatically modified for me. The lines added were:<\/p>\n<pre>\r\ntitle CentOS (2.6.18.8-blm334)\r\nroot (hd0,1)\r\nkernel \/boot\/vmlinuz-2.6.18.8-blm334 ro root=LABEL=\/ rhgb quiet\r\ninitrd \/boot\/initrd-2.6.18.8-blm334.img\r\n<\/pre>\n<p>I rebooted the system<\/p>\n<pre>\r\n#reboot\r\n<\/pre>\n<p>And selected to boot my newly created kernel from the booting menu. When the system was up, I checked it by<\/p>\n<pre>\r\n#uname -r\r\n2.6.18.8-blm334\r\n<\/pre>\n<p>Finally, I wrote a test program to see whether my system call was working properly. Inside hello.c:<\/p>\n<pre>\r\n#include <linux\/errno.h>\r\n#include <linux\/unistd.h>\r\n#include <sys\/syscall.h>\r\n#include <stdio.h>\r\n#define __NR_helloworld 318\r\n\r\nint main()\r\n{\r\nprintf( \"%d\\n\", syscall( __NR_helloworld ) );\r\n\r\nreturn 0;\r\n} \r\n<\/pre>\n<p>And I compiled it<\/p>\n<pre>\r\n#cd \/root\/Desktop\r\n#gcc -o hello.o hello.c\r\n#.\/.hello.o\r\n<\/pre>\n<p>Inside \/var\/log\/messages was<\/p>\n<pre>\r\nMar 21 01:41:36 localhost kernel: hello world!\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>These are *old* notes (2010 or so). I remember doing this, and it was interesting enough that I thought I should post it. It may be easier now. I experimented with the following on CentOS 5.1 running on an i686&hellip;<\/p>\n<p class=\"more-link-p\"><a class=\"more-link\" href=\"http:\/\/appcrawler.com\/wordpress\/2017\/03\/01\/adding-a-system-call-to-linux\/\">Read more &rarr;<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false,"footnotes":""},"categories":[28,27],"tags":[],"_links":{"self":[{"href":"http:\/\/appcrawler.com\/wordpress\/wp-json\/wp\/v2\/posts\/6170"}],"collection":[{"href":"http:\/\/appcrawler.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/appcrawler.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/appcrawler.com\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/appcrawler.com\/wordpress\/wp-json\/wp\/v2\/comments?post=6170"}],"version-history":[{"count":8,"href":"http:\/\/appcrawler.com\/wordpress\/wp-json\/wp\/v2\/posts\/6170\/revisions"}],"predecessor-version":[{"id":6181,"href":"http:\/\/appcrawler.com\/wordpress\/wp-json\/wp\/v2\/posts\/6170\/revisions\/6181"}],"wp:attachment":[{"href":"http:\/\/appcrawler.com\/wordpress\/wp-json\/wp\/v2\/media?parent=6170"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/appcrawler.com\/wordpress\/wp-json\/wp\/v2\/categories?post=6170"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/appcrawler.com\/wordpress\/wp-json\/wp\/v2\/tags?post=6170"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}