学号256,原创作品转载请注明出处 + https://github.com/mengning/linuxkernel/
一:编译内核5.0
1.首先我们需要先下载好linux5.0.1内核并解压
为了实验的方便,我们先在桌面建立一个文件夹,并将源码解压到该文件夹中。命令如下:
- david-wang
- david-wang
david-wang:
$ tar -zxvf linux-5.0.1.tar.gz
之后我们进入到该文件夹中,由于对Linux还处在初学阶段,所以选择了简单的配置内核方法,即make menuconfig。在终端输入make menuconfig,等待几秒后,终端变成图形化的内核配置界面。进行配置时,大部分选项使用其缺省值,只有一小部分需要根据不同的需要选择。,如图所示:
之后我们就需要在文件夹中输入make命令,等待编译的进行。在这个编译过程中,会有许多报错,这时候我们就需要根据提示,一个一个的进行安装,之后就安装完成了。
再之后,我们就需要制作根文件目录。输入如下命令:
1 mkdir rootfs 2 git clone https://github.com/mengning/menu.git 3 cd menu 4 gcc -pthread -o init linktable.c menu.c test.c -m32 -static 5 cd ../rootfs 6 cp ../menu/init ./ 7 find . | cpio -o -Hnewc |gzip -9 > ../rootfs.img
之后启动MenuOS,输入如下命令:qemu-system-i386 -kernel linux-5.0.1/arch/x86/boot/bzImage -initrd rootfs.img。得到如下界面:
启动跟踪调试内核:
qemu-system-i386 -kernel linux-5.0.1/arch/x86/boot/bzImage -initrd rootfs.img -S -s -append nokaslr
最后我们打开一个新终端,输入如下命令:
gdb (gdb)file linux-5.0.1/vmlinux # 在gdb界面中targe remote之前加载符号表 (gdb)target remote:1234 # 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行 (gdb)break start_kernel # 断点的设置可以在target remote之前,也可以在之后
得到如下界面,至此,内核编译完成。
二:选择系统调用号与序号后两位相同的调用号进行分析(学号256,后两位为56)
我们首先在在/usr/include/asm/unistd_32.h中查找到对应的系统调用
在test.c中增加函数,setgroupstest(),并重新编译rootfs.img,如下:
int setgroupstest(int argc, char *argv[]) { gid_t list[500]; int x = getgroups(0,list); int flag; getgroups(x,list); flag = setgroups(x,list); printf("%d\n",flag); return 0; } int main() { PrintMenuOS(); SetPrompt("MenuOS>>"); MenuConfig("version","MenuOS V1.0(Based on Linux 3.18.6)",NULL); MenuConfig("quit","Quit from MenuOS",Quit); MenuConfig("time","Show System Time",Time); MenuConfig("time-asm","Show System Time(asm)",TimeAsm); MenuConfig("setgrouptest","Show setgrouptest",setgroupstest); ExecuteMenu(); }
之后重新编译执行,当执行的返回值为0,说明setgroups执行成功。 系统调用的工作机制是:当用户态进程调用一个系统调用时,CPU切换到内核态并开始执行一个内核函数,由API、中断向量和中断处理程序协调完成。
三:实验总结
中断有两个重要的属性,中断号和中断处理程序。中断号用来标识不同的中断,不同的中断具有不同的中断处理程序。在操作系统内核中维护着一个中断向量表(Interrupt Vector Table)。这个数组存储了全部中断处理程序的地址,而中断号就是对应中断在中断向量表中的偏移量。