linux-kernel – 在实时Debian Wheezy上实现一个系统调用
出于教育目的,我想在Debian Wheezy中实现系统调用.我希望在
linux-image-3.2.0 – rt-amd64包中的内核上实现它.以下是我尝试过的概述:
要获取内核源代码: apt-get source linux-image-3.2.0-4-rt-amd64 从那里,我得到以下文件/目录我执行的目录: linux_3.2.41.orig.tar.xz linux_3.2.41-2+deb7u2.dsc linux_3.2.41-2+deb7u2.debian.tar.xz 以及: linux_3.2.41 其中包含内核的源代码. 然后,为了进行必要的更改以添加系统调用,我基本上遵循了这个页面: 以下是修改后的指令的精简版本,以反映我所做的更改. ?文件1:linux-x.x.x / vpart_syscalls / vpart_syscalls.c #include <linux/linkage.h> #include <linux/kernel.h> asmlinkage long insert_partition(char*dest,const char* src) { printk("<--- the syscall has been called!"); return 0; } >文件2:linux-x.x.x / vpart_syscalls / Makefile.在上面创建的同一个测试目录中创建一个Makefile,并在其中加入以下行: obj-y:= vpart_syscalls.o .long insert_partition 在此文件中,所有系统调用的名称将与唯一编号相关联.在最后一个系统调用号对后,添加一行 #define __NR_insert_partition 349 然后替换NR_syscalls值,说明系统调用的总数(现有数字加1),即在这种情况下NR_syscalls应该是338并且新值是339. #define NR_syscalls 350 >文件5:linux-x.x.x / include / linux / syscalls.h 在文件中附加我们函数的原型. asmlinkage long insert_partition(int lenTicks,int vpid); 就在文件中的#endif行之前. >文件6:Makefile位于源目录的根目录. 打开Makefile并找到定义core-y的行,并将目录test添加到该行的末尾. core-y += kernel/ mm/ fs/ test/ vpart_syscalls/ 然后我继续以与那里描述的不同的方式构建内核: make localmodconfig make menuconfig (making no changes) make-kpkg clean fakeroot make-kpkg --initrd --append-to-version=+tm kernel_image kernel_headers cd .. dpkg -i linux-image-3.8.* dpkg -i linux-headers-3.8.* 安装的内核启动很好.我制作了以下c程序来测试系统调用: #include <stdio.h> #include <linux/unistd.h> #include <sys/syscall.h> int main(){ printk("Calling the new syscall!n"); int ret = 100; ret = syscall(349,1,2); printf("call return value: %in",ret); return 0; } 当我编译并运行该程序时,我得到的返回值为-1.我使用dmesg检查消息,并且没有证据表明我的printk被调用了.. 如果有人知道我的问题在哪里,我真的很开心!我应该说我在改变和构建内核方面没有太多经验,但我已经学到了很多东西.我阅读了Robert Loves的书 – linux内核开发和网上的几个指南. 解决方法
我认为,对于64位内核,步骤3和4可能不正确:
File 3: linux-x.x.x/arch/x86/kernel/syscall_table_32.S. File 4: linux-x.x.x/arch/x86/include/asm/unistd_32.h 这里有两个文件:http://lxr.linux.no/linux+v3.2.41/arch/x86/kernel/ syscall_64.c 668 2008-12-24 14:26:58 -0800 syscall_table_32.S 8659 2012-01-04 14:55:50 -0800 第一个使用C文件定义64位模式的系统调用表内容,使用unistd_64.h定义宏操作 #define __SYSCALL(nr,sym) [nr] = sym,const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = { .... #include <asm/unistd_64.h> }; asm / unistd_64.h的位置 #define __NR_read 0 __SYSCALL(__NR_read,sys_read) 等等. 第二个,你改变了 – 是32位模式,使用asm文件和标签(.long sys_call_name)编写. 因此,您为32位模式定义了syscall,并且您使用的是linux-image-3.2.0-4-rt-amd64,它主要用于“64位PC”. 我认为您将测试程序编译为gcc test.c,默认为64位模式.您可以尝试使用gcc:gcc -m32 test.c的-m32选项来获取32位应用程序(这只有在32位版本具有正确的交叉环境时才有效)或者在某些32位Linux上编译此测试. 或者另一个选择是创建步骤“4a”:编辑arch / x86 / include / asm / unistd_64.h以添加两行: #define __NR_insert_partition YOUR_NUMBER __SYSCALL(__NR_insert_partition,insert_partition) 我不确定定义64位的NR_syscalls的位置和方式.它可能在构建期间生成. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |