!!! 在操作前一定记得使用虚拟机的快照,保存未实验前的状态,方便随时回退。
B站视频-【操作系统实验七】自己编译内核
内核源文件-linux-2.6.39.tar.gz
实验使用的操作系统下载-CentOS-6.10-i386-bin-DVD1.iso
解压内核源码压缩包到/usr/src目录下
在源码目录运行解压命令:
$ sudo tar -zxvf linux-2.6.39.tar.gz -C /usr/src
切换目录到内核源码:
$ cd /usr/src/linux-2.6.39
1.修改内核文件
第一个文件名地址:arch/x86/kernel/syscall_table_32.S
在最后添加:
.long sys_mycall
第二个文件地址:arch/x86/include/asm/unistd_32.h
可以看到原有的最后一个系统调用为:
#define __NR_syncfs 344
在后面添加自己的系统调用:
#define __NR_mycall 345
同时,修改总的系统调用数:
#define NR_syscalls 346

x86_64的CentOS需要多修改一个文件,才能正确调用: arch/x86/include/asm/unistd_64.h
#define __NR_mycall 307
__SYSCALL(__NR_mycall, sys_mycall)

第三个文件地址:include/linux/syscalls.h
添加增加的系统调用的声明:
asmlinkage long sys_mycall(int num);
第四个文件地址:kernel/sys.c
添加系统调用函数:
SYSCALL_DEFINE1(mycall, int, num)
{
printk("This is my syscall from kernel.\n");
printk("current pid is: %d.\n", current->pid);
return (long)num;
}
2.编译内核同时安装到系统中
配置内核:
$ make localmodconfig
编译内核:
$ make bzImage -j4
编译模块:
$ make modules
安装模块:
$ sudo make modules_install
安装内核:
$ sudo make install
3.测试新内核
首先,确认新内核安装状态
cat /boot/grub/menu.lst
在当中看到2.6.39,即安装成功
32位系统测试程序
#include <stdio.h>
int main()
{
printf("The return value is: %d.\n", syscall(345, 5));
return 0;
}
64位系统测试程序
#include <stdio.h>
int main()
{
printf("The return value is: %d.\n", syscall(307, 5));
return 0;
}
保存后编译
gcc -o test test.c
执行
./test
运行结果
The return value is 5.

查看内核调用信息
dmesg | tail -n 2

4.实验7第4题
#include <stdio.h>
int main()
{
int i, j;
i = 100;
j = 0;
printf("This is the result of new kernel\n");
printf("%d\n", syscall(345, i)); //345是mycall的增加的系统调用
return 0;
}
2.6.3内核移除了_syscall1()这个宏,需要使用syscall()对进行系统调用