现在的位置: 首页 > 综合 > 正文

Linux内核(5)——系统调用与内核编译实验

2013年03月03日 ⁄ 综合 ⁄ 共 3616字 ⁄ 字号 评论关闭

今天在做Linux系统调用与内核编译的实验,主要任务有两个:

1)添加一个新的系统调用:mysyscall,功能仅为打印一条语句。

2)编译内核。

 

 

 

实验步骤如下:

1.在官网(www.kernel.org)上下载最新的内核压缩包,本次实验版本为:linux-2.6.36.2.tar.bz2

 

2.root登录,将内核包复制到usr/src下:cp linux-2.6.36.tar.bz2 /usr/src

 

3.解压:tar -xjvf linux-2.6.36.2.tar.bz2

 

4.修改以下文件夹下的3个文件:

  ①编辑/usr/src/ linux-2.6.36.2/kernel/sys.c文件,添加系统调用函数:

SYSCALL_DEFINE1(mysyscall,int, number)

{

             printk("call number is %d/n",number);

             return number;

}

  ②编辑/usr/src/linux-2.6.36.2/arch/x86/kernel/syscall_table_32.S,在文件最后加上一行:

.long sys_mysyscall             /* 341 */

    从这个文件来确定mysyscall的系统调用号,mysyscall的系统调用号等于最后一行的系统调用号+1。如最后行对应的系统调用号是340mysyscall的系统调用号为341

③修改/usr/src/linux-2.6.36.2/arch/x86/include/asm/unistd_32.h,添加一行将mysyscall与确定的系统调用号对应起来:#define __NR_mysyscall 341

 

5.重新编译内核

       在终端输入命令,进入源代码文件夹:cd /usr/src/linux-2.6.36.2 ,执行如下命令:

make mrproper

  ①配置内核(两种方法)

1)手动:make menuconfig(出现菜单配置界面)

2)采用内核的配置选项:

make allyesconfig

尽可能地使用''y''设置特征值,来建立一个配置文件,得到一份最详细的代码

make allmodconfig

尽可能地使用''m''设置特征值,来建立一个配置文件       

make allnoconfig

尽可能地使用''n''设置特征值,来建立一个配置文件 ,得到一份精简的代码

  关于是直接编进内核还是编译成模块的一点参考:若是内核一定需要的功能,不用多说直接编进内核;可能在将来会用到的功能,尽量编译成模块;完全不了解的内核功能就保留默认值。

  首页的几个选项介绍:

   (1)General setup

     Linux最相关的程序互动、内核版本说明、是否使用开发中程序代码等信息都在这里设置的。基本上,保留默认值即可。不要随便取消下面的任何一个选项,可能造成某些程序无法被同时执行的困境。

   (2)Processor type and features

     挑选主机的实际CPU形式。

   (3)Power management and ACPI options

     系统电源管理机制。

   (4)Executable file formats/Emulations

     编译成可执行文件的格式,是给Linux内核运行可执行文件之用的数据。

   (5)Networking support

     内核的网络功能,包含了防火墙的相关选项,就是防火墙iptables这个数据。建议编成模块。

   (6)Device Drivers

     各项设备的驱动程序,这是所有硬件设备的驱动程序库。

   (7)Security OptionsCryptographic API

     信息安全、密码应用

 

②编译内核(结果文件会放到源代码所在目录)

make  bzImage      (耗时很长)

以上命令执行完毕后,会在当前目录下生成一个名为System.map的文件,会在/usr/src/linux-2.6.36.2/arch/x86/boot/下生成一个bzImage文件。

③编译模块(结果文件会放到/lib目录下)

make modules

实际上,只要直接执行make命令就会同时编译内核和模块,模块编译完成后执行make modules_install更新模块和驱动程序。

 

④拷贝内核文件到/boot下,在终端执行以下命令:

cp /usr/src/linux-2.6.36.2/arch/x86/boot/bzImage  /boot/vmlinuz-2.6.36.2  (拷贝内核镜像)

cp /usr/src/linux-2.6.36.2/System.map  /boot/System.map-2.6.36.2        (拷贝符号表)

 

   ⑤建立ramfsramdisk

cd /boot       (进入/boot目录)

生成ramfsmkinitrd initramfs-2.6.36.2.img 2.6.36.2

生成ramdiskmkinitrd initrd-2.6.36.2.img 2.6.36.2

(注:ramfsramdisk选一个就行,下面grub.conf文件里initrd对应生成的文件)

     注:这一步可能会提示一些错误,不过不影响后面的实验~

 

⑥编辑启动配置文件grub

编辑/boot/grub/grub.conf。在grub.conf文件中,每一个title标签表示一个启动项,仿照第一段title的写法,编写新内核的启动项,其中kernelinitrd使用新拷贝过来的vmlinz—版本号文件和initrd-2.6.36.2.img文件。

原来的grub.conf文件:

default=0

timeout=0

splashimage=(hd0,0)/grub/splash.xpm.gz

hiddenmenu

title Fedora (2.6.33.3-85.fc13.i686)

        root (hd0,0)

        kernel /vmlinuz-2.6.33.3-85.fc13.i686 ro root=/dev/mapper/vg_fedora13-lv_root rd_LVM_LV=vg_fedora13/lv_root rd_LVM_LV=vg_fedora13/lv_swap rd_NO_LUKS rd_NO_MD rd_NO_DM LANG=zh_CN.UTF-8 KEYTABLE=us rhgb quiet

        initrd /initramfs-2.6.33.3-85.fc13.i686.img

 

修改后的grub.conf文件:

default=1

timeout=15

splashimage=(hd0,0)/grub/splash.xpm.gz

#hiddenmenu

title Fedora (2.6.33.3-85.fc13.i686)

        root (hd0,0)

        kernel /vmlinuz-2.6.33.3-85.fc13.i686 ro root=/dev/mapper/vg_fedora13-lv_root rd_LVM_LV=vg_fedora13/lv_root rd_LVM_LV=vg_fedora13/lv_swap rd_NO_LUKS rd_NO_MD rd_NO_DM LANG=zh_CN.UTF-8 KEYTABLE=us rhgb quiet

        initrd /initramfs-2.6.33.3-85.fc13.i686.img

title Fedora(2.6.36.2)

          root(hd0,0)

          kernel /vmlinuz-2.6.36.2 ro root=/dev/mapper/vg_fedora13-lv_root rd_LVM_LV=vg_fedora13/lv_root rd_LVM_LV=vg_fedora13/lv_swap rd_NO_LUKS rd_NO_MD rd_NO_DM LANG=zh_CN.UTF-8 KEYTABLE=us rhgb quiet

        initrd /initramfs-2.6.36.2.img

 

⑦重新启动系统,使用新生成的内核。

 

⑧编写测试程序testcall.c,测试新系统调用。

     1)新建文件testcall.c:

//testcall.c

int main()      

{

  syscall(341,100);  /*341是新添加的系统调用号,100是测试参数*/

  return 0;

}

2)终端编译 gcc –o testcall testcall.c

3)运行 ./testcall

4)查看结果 :终端运行命令dmesg,会看到在最后一行输出 call number is 100

 

 

抱歉!评论已关闭.