钟晶晶+ 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
获取到MenuOS源码后修改test.c文件,加入getuid系统调用函数源码,Getuid为调用C API版本,GetuidAsm为内嵌汇编语言版本
启动内核
结束qmeu,以调试方式启动,在LinuxKernel目录下执行
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
另开一个终端,启用gdb调试
接下来我们分析一下system_call的具体调用过程,详细代码见/kernel/entry_32.S
总结
通过系统调用号查找系统调用表sys_call_table,软中断指令INT 0x80执行时,系统调用号会被放入 eax 寄存器中,system_call函数可以读取eax寄存器获取,然后将其乘以4,生成偏移地址,然后以sys_call_table为基址,基址加上偏移地址,就可以得到具体的系统调用服务例程的地址了!然后就到了系统调用服务例程了。需要说明的是,系统调用服务例程只会从堆栈里获取参数,所以在system_call执行前,会先将参数存放在寄存器中,system_call执行时会首先将这些寄存器压入堆栈。system_call退出后,用户可以从寄存器中获得(被修改过的)参数。