这个作业属于哪个课程 | <2020-2021-1Linux内核原理与分析)> |
---|---|
这个作业要求在哪里 | <2020-2021-1Linux内核原理与分析第六周作业> |
这个作业的目标 | <写上具体方面> |
作业正文 | ... https://www.cnblogs.com/mazhuhong/p/13900080.html |
系统调用的三层机制(下)
给MenuOS增加命令
LinuxKernel文件夹,删除menu,克隆一个新版本的menu。代码如下:
rm -rf menu
git clone https://github.com/mengning/menu.git
cd menu
make rootfs
这里注意make rootfs需要在menu目录下执行,在LinuxKernel目录下执行会失败。(这里有疑问,不知道为什么rootfs在LinuxKernel目录里但却要在menu里执行)
输入
make rootf
help
打开menu景象,查看该Linux内核支持的命令,其中已经增加了time和time-asm
给MenuOS增加新的命令,打开menu目录下的test.c,增加getpid()函数,然后使用MenuConfig命令增加新的命令,添加的代码如下:
int mypid(int argc, char *argv[])
{
int pid;
pid=getpid();
printf("Hello 20209314!Pid is :%d
",pid);
return 0;
}
重新执行脚本后输入help,显示已经成功添加命令。
使用gdb跟踪系统调用内核函数sys_time
输入代码
qemu -kernel linux-3.18.6/arch/x86/boot/bzImge -initrd rootfs.img -S -s
启动内核
新打开一个shell窗口,启动gdb,将3.18.6加载进来:
file linux-3.18.6/vmlinux
target remote:1234
设置断点,测试:
这里出现问题,设置断点后输入time命令我的gdp没有在断点处停下来,time命令直接执行完毕,问题尚未解决。
暂不清楚问题出在哪里,在实验楼环境是实验没有问题
使用s进行单步执行:
设置断点在system_call处,由于system_call是一段特殊的汇编代码,gdb无法对其进行跟踪。
上面输入time命令时出现的问题和这里的意义,猜测内部堆栈出现问题。
system_call汇编代码分析
ENTRY(system_call)
RINGO_INT_FRAME
ASM_CLAC
push1_cfi %eax /*保存系统调用号*/
SAVE_ALL /*保存现场,将用到的所有CPU寄存器保存到栈中*/
GET_THREAD_INFO(%ebp) /*ebp用于存放当前进程thread_info结构的地址*/
test1 $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
jnz syscall_trace_entry
cmp1 $(nr_syscalls),%eax /*检查系统调用号(系统调用号应小于NR_syscalls)*/
jae syscall_badsys /*不合法,跳入异常处理*/
syscall_call:
call *sys_call_table(,%eax,4) /*合法,对照系统调用号在系统调用表中寻找相应的系统调用的内核处理函数*/
movl %eax,PT_EAX(%esp) /*保存返回值到栈中*/
syscall_exit:
testl $_TIF_ALLWORK_MASK, %ecx /*检查是否需要处理信号*/
jne syscall_exit_work /*需要,进入 syscall_exit_work*/
restore_all:
TRACE_IRQS_IRET /*不需要,执行restore_all恢复,返回用户态*/
irq_return:
INTERRUPT_RETURN /*相当于iret*/