随笔-145  评论-173  文章-70  trackbacks-0

选摘资料:

1.cd /usr/src/linux/include/asm-generic/
2. vim unistd.h,添加#define __NR_mysyscall  337
3.cd /usr/src/linux/arch/x86/kernel/
4. vim syscall_table_32.S 添加.long sys_mysyscall
5.cd /usr/src/linux/kernel
6.vim sys.c 添加函数
asmlinkage int sys_mysyscall(void)
{
    printk( "hello, world" );
    return 10;
}

7.编译,并且启用新内核
8.编写代码
#include <linux/unistd.h>
#include <sys/syscall.h>

#define __NR_mysyscall  337

int main(int argc, char** argv)
{
    syscall(__NR_mysyscall );
    return 0;
}

============================================================
步骤_1   添加源代码
编写添加到内核中的源程序,函数名以sys_开头。

如:mycall(int num),在/usr/src/linux/kernel/sys.c文件中添加如下代码:
 asmlinkage int sys_mycall(int number)
  {
         return number;   //该系统调用仅返回一个整型值
  }

步骤_2   连接新的系统调用
        使内核的其余部分知道该系统调用的存在。为此,需编辑两个文件:
/usr/src/linux/include/asm-i386/unistd.h——系统调用清单(为每个系统调用分配唯一号码)
                #define _NR_name nnn  
                 这里,name:系统调用名;nnn:系统调用对应的号码,不能与内核自身的系统调用号相同。

/usr/src/linux/arch/i386/kernel/entry.S——对sys_call_table[ ]进行初始化(增加新的内核函数的指针)
      .long SYMBOL_NAME(sys_mycall)


步骤_3   重建Linux内核

以root身份进入/usr/src/linux目录,重建内核
 #make config       //基于文本的传统配置界面
 #make dep     //检验内核源代码文件的依赖性和完整性
 #make clean    //清除以前编译的目标文件
 #make bzImage //编译内核,也可采用make zImage

编译生成的内核文件为
  /usr/src/linux/arch/i386/boot/bzImage


配置内核的方式
 make config              基于文本的传统配置界面
 make menuconfig    基于文本的菜单形式配置界面,字符终端下使用
 make xconfig            基于图形窗口模式的配置界面,Xwindow下使用
 
对每个配置选项,有三种选择:
 “Y”——将该功能编译进内核
 “N”——不将该功能编译进内核
 “M”——将该功能编译成可动态载入的内核模块

步骤_4   重启内核
将/usr/src/linux/arch/i386/boot/bzImage拷贝到/boot/bzImage
配置启动文件
 若采用lilo,修改/etc/lilo.conf,添加新的引导内核
image=/boot/bzImage       // 上面编译生成的内核映象
label=Linuxtest                 // 给该系统取个名字
root=/dev/hda5                 // 根目录所在的分区,可用命令df查看
read-only
 若采用grub,修改/etc/grub.conf,添加新的引导内核
title Linuxtest
root(hd0,4)
kernel /boot/bzImage ro root=/dev/hda5
initrd /boot/initrd-2.4.18-3.img
重启后,出现Linuxtest选项,选择它进入新的内核

步骤_5   使用新的系统调用

#include<stdio.h>
#include</usr/src/linux-2.4/
           include/asm/unistd.h>
#include<errno.h>
_syscall1(int, mycall, int, ret)

int main(int argv, char *argc[])
{   int a = mycall(100);
    printf(“%d\n”,a);
    return 0;



下面是我的亲身经历,实测,最终成功的生成了bzImage文件,可以引导:
修改的文件有:
1。/usr/src/linux/kernel/sys.c
添加:
 asmlinkage int sys_mycall(int number)
  {
         return number;   //该系统调用仅返回一个整型值
  }
2。/usr/src/linux/include/asm-x86/unistd_32.h  
添加#define _NR_name nnn  
貌似修改asm-x86和asm文件夹下面的都一样,最终都会修改到上面的unistd_32.h文件。
还有,也不存在修改总数的操作,直接添加一个你的那个号就可以了。
3。/usr/src/linux/arch/x86/kernel/syscall_table_32.S
添加 .long sys_mysyscall
应该是:.long SYSMBOL_NAME(sys_mysyscall)吧?
特别注意,前后的名称要一致。
4。make menuconfig
具体的参数不需要改变,只需要保存下,生成一个config文件就可以了,便于后面的bzImage的创建。

一切成功,OK。

附记:发现VBOX有一个BUG,如果长期不用的话,内外的剪切板不能共享,即,内部copy的数据,在外部不能使用。
而如果注销后,重新启动,就可以了。。上面的一段就是从虚拟机中导出来的,成功了。。

posted on 2010-03-03 23:48 deercoder 阅读(1576) 评论(1)  编辑 收藏 引用 所属分类: Unix/Linux

评论:
# re: 如何在Linux 2.6.27.45内核上添加新的系统调用[未登录] 2013-07-07 12:27 | dd
好  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理