这段时间,学校要做操作系统课程设计,任务如下:
1、编写一个新系统调用的响应函数,函数的名称和功能由实验者自行定义。把新的系统调用函数嵌入到Linux内核中
2、编写应用程序以测试新的系统调用并输出测试结果
要实现以上设计任务,就必须要独立编译内核进行测试,然而要编译内核需要一些配置,让我们来看看有哪些配置:
第一步,下载linux内核源码并解压:
1 |
|
第二步,安装依赖并运行图形化配置菜单
1 |
|
中途需要编译一段时间,如果出现问题,可能是因为缺少相关依赖,使用apt安装即可。
第三步,让我们看看图形化配置

注意,第一次进入的界面的配置是根据当前kali系统的配置文件.config自动生成的。这个配置介于命令make allyesconfig和make allnoconfig之间,如果按照这个配置编译,系统内核大约有300M400M之间,且编译的时间大概需要6个小时,不利于我们的编译和调试,如果按照make allnoconfig配置,12分钟之间可以编译好,系统内核也只有500k,但很多功能用不了,显然是不切实际的,所以我们要根据自己的需求,不断去除和添加自己想要的功能。最简便的方法是根据当前配置不断地删减功能,直到不能再减小为止(这样的目的是保留系统的verbose报错功能,输出启动日志以便后续调试,如果一开始就make allnoconfig 虽然系统最小,但很多配置不全,不如使用原系统默认配置,然后一项项删减。)。比如启动日志遇到/bin/sh exists but can’t execute,意味着可执行文件执行遇到问题,就需要把excutable file format里面的kernel support for elf binaries启用以及64bit kernel启动,遇到permission denied 就说明可能把自制内核按照在发行版内核同一个分区里导致冲突,因此需要把自制内核安装在另一个分区里。如果遇到can’t udev的问题,说明守护程序udev没有打开或者硬盘驱动没有安装,就需要我们安装相应的硬盘驱动,步骤如下:
键入modinfo mptbase,提示如下信息:
1 |
|
可见硬盘驱动为 Fusion MPT base driver
配置PCI总线驱动,依次选”Bus Option”-“Pci support”:
前面看到我的磁盘是Scsi类型,因此需要配置Scsi,依次选”Device Drivers”-“Scsi device support”–”Scsi device support”,”Scsi disk support”
Scsi磁盘需要Sata控制器,这一步比较关键,要从不同厂商的控制器驱动中挑选出合适的驱动。根据前面udevadm的输出我的虚拟机,使用的是Fusion LSI磁盘驱动:依次选取1)”Device Driver”-“Serial ATA and Parallel ATA driver”-“AHCI SATA support”;2)”Device Driver”-“Fusion MPT device support”-“Fusion MPT ScsiHost driver for SPI”;
3)”Device Driver”-“Scsi device support”-“SCSI low-level drivers”-“LSI MPT Fusion SAS 2.0 Device Driver”
设备驱动配置完毕,需要再配置内核支持的文件系统和ELF文件格式。为了方便起见,我们不设置内核支持initramfs,直接用busybox启动。
选取”File Systems”-“The Extend 4(ext4) filesystem”
选取”Executable file formats”-“kernel support for ELF binaries”
“Kernel support for scripts starting with #!”
其他设置:
[*]64 bit kernel
Processor type and features —>
Processor family () —>
[*] Generuc x86 support
Bus options (PCI etc.) —>
[*] PCI support
PCI access mode (Any) —>
Executable file formats / Emulations —>
[*] Kernel support for ELF binaries
[*] Write ELF core dumps with partial segments
[*] Enable the block layer #这步很重要,不然无法启用SCSI
Device Drivers —>
[*] Block devices —>
<*> Loopback device support
SCSI device support —>
<*> SCSI device support
[*] legacy /proc/scsi/ support (NEW)
<*> SCSI disk support
input device support—>
[*]Generic input interface
[*]event interface
[*]event debugging
*Input Device Drivers
[*]keyboards—–>
[*]AT keyboard
[*]……keyboard #键盘驱动可以都选上
Hardware I/O Ports—>
[*]Serial I/O support
…… #这里可以全选
[*]character devices —>
[*]enable tty
[*] Fusion MPT device support —>
<*> Fusion MPT ScsiHost drivers for SPI
<*> Fusion MPT ScsiHost drivers for FC
<*> Fusion MPT ScsiHost drivers for SAS
<*> Fusion MPT misc device (ioctl) driver
File systems —>
[*] The extended 4(ext4) filesystem
[*] Use ext4 for ext2 filesystem
[*] Ext4 POSIX Access Control Lists
[*] Ext4 Security Labels
[*] Ext4 Encryption
设置完成后,选择save,命名为‘.config’, 然后选择exit退出。
第四步、在原系统编译内核
时间不长,大概五六分钟(前提是你精简过),系统编译完大概有2M大小
1 |
|
第六步、添加硬盘并分区
在vmware里面添加一块大概500MB的SCSI硬盘,重启后执行
1 |
|
可以看到/dev/sdb装置
进一步分区
1 |
|
输入n后分区形成/dev/sdb1
格式化
1 |
|
挂载分区
1 |
|
编译busybox
1 |
|
下面是需要编译进busybox的功能选项。
General Configuration应该选的选项
Don’t use /usr
这个选项一定要选,否则make install 后busybox将安装在原系统的/usr下,这将覆盖掉系统原有的命令。
Build Options
Build BusyBox as a static binary (no shared libs)
这个选项也是一定要选择的,这样才能把busybox编译成静态链接的可执行文件,运行时才独立于其他函数库.否则必需要其他库文件才能运行,在单一个linux内核不能使它正常工作。
其它选项都是一些linux基本命令选项,自己需要哪些命令就编译进去,一般用默认的就可以了,配置好后退出并保存。
编译并安装busybox
1 |
|
make install后会在busybox目录下生成一个叫_install的目录,里面有busybox和指向它的链接。
1 |
|
第七步、更新grub
打开grub配置文件
1 |
|
在末尾添加如下信息
1 |
|
更新grub
1 |
|
重启系统,在grub菜单选择My Linux-4.19.11如果看到类似以下界面说明编译成功

第八步、添加系统调用
回到原系统,更改linux源码以下文件:
1 |
|
添加如下两个系统调用,注意这两种系统调用的形式不太一样,主要是为了传参,后面会讲到。

修改头文件,添加如下两个函数原型
1 |
|

修改sys.c源文件,添加如下函数定义
1 |
|
1 |
|
注意以上函数定义是不一样的,前者是直接定义,后者是通过宏来定义,之后sys_add会被编译器自动替换为__x64_sys_add目的是为了让系统调用实现传参,相当于一个接口。SYSCALL_DEFINE2意思是有两个参数,int a,int b。
之后重新编译内核并复制到新硬盘。
第九步、编写测试程序
目的是为了手动实现系统调用,使用gcc编译好并输出为test1 文件
1 |
|
复制test1到新硬盘
1 |
|
目前在新系统里执行test1是不行的,所以需要分析test1的文件类型
1 |
|

由输出信息可见,执行该文件需要The GNU C Library的部分库,所以要从原系统复制过去
1 |
|
注意除了两个.so结尾的文件,其余复制过去的都是软连接,软连接指向那两个文件,如果软连接发生故障可以用ln -s 修复。
重启进入自制系统,如果测试成功,会有如下结果:

至此,系统调用完成。
配置文件:
https://github.com/fjh1997/vmware-linux-minimize-kernel-student/blob/master/.config
参考:
VMware中打造最小Linux系统(一)——构建内核&文件系统 - yejingx的专栏 - CSDN博客
https://blog.csdn.net/yejingx/article/details/6525405
制作最小linux内核(1) - lixiangminghate的专栏 - CSDN博客
https://blog.csdn.net/lixiangminghate/article/details/55224412
linux添加系统调用总结(内核版本4.4.4) - sinat_28750977的博客 - CSDN博客
https://blog.csdn.net/sinat_28750977/article/details/50837996
Linux系统调用之SYSCALL_DEFINE - 柠檬C的专栏 - CSDN博客
https://blog.csdn.net/hxmhyp/article/details/22699669
ubuntu18.04 编译内核 学习记录 - Hynn01的博客 - CSDN博客
https://blog.csdn.net/weixin_38180645/article/details/82856407
说些什么吧!