系统调用的三个层次(下)
一、给MenuOS增加time和time-asm命令
1、克隆并自动编译
MenuOS rm menu -rf 强制删除原menu文件
git clone https://github.com/mengning/menu.git 从github中克隆
cd menu
make rootfs 运行自动编译脚本,生成根文件系统,启动MenuOS
2、给MenuOS增加time和time-asm命令
- 更新menu代码到最新版
- test.c中main函数里
- 增加MenuConfig
- 增加对应的两个函数:Time和TimeAsm make rootfs
二、使用gdb跟踪系统调用内核函数sys_time
使用gdb跟踪调试内核
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S # 关于-s和-S选项的说明:
另开一个shell窗口gdb
(gdb)file linux-3.18.6/vmlinux # 在gdb界面中targe remote之前加载符号表(gdb)target remote:1234 # 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行 加载符号表
三、系统调用在内核代码中的处理过程
1、系统调用在内核代码中的工作机制和初始化
- SYSCALL_VECTOR:系统调用的中断向量
- &system_call:汇编代码入口
- 一执行int 0x80,系统直接跳转到system_call
四、分析理解system_call代码
490ENTRY(system_call) //执行int Ox80后的下一条指令
491 RING0_INT_FRAME # can't unwind into user space anyway
492 ASM_CLAC
493 pushl_cfi %eax # save orig_eax
494 SAVE_ALL //保存系统寄存器信息
495 GET_THREAD_INFO(%ebp) //获取thread_info结构的信息
496 # system call tracing in operation / emulation
497 testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp) //测试是否有系统跟踪
498 jnz syscall_trace_entry
499 cmpl $(NR_syscalls), %eax //比较eax中的系统调用号和最大syscall,超过则无效
500 jae syscall_badsys //无效的系统调用 直接返回
501syscall_call:
502 call *sys_call_table(,%eax,4) //系统调用表,eax存放系统调用号
503syscall_after_call: //保存返回值并退出
504 movl %eax,PT_EAX(%esp) # store the return value
505syscall_exit: //检测是否有待处理任务
506 LOCKDEP_SYS_EXIT
507 DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt
508 # setting need_resched or sigpending
509 # between sampling and the iret
510 TRACE_IRQS_OFF
511 movl TI_flags(%ebp), %ecx
512 testl $_TIF_ALLWORK_MASK, %ecx # current->work //判断当前的任务是否需要进程调度
513 jne syscall_exit_work
514
515restore_all:
516 TRACE_IRQS_IRET
517restore_all_notrace: //iret 从系统调用返回
五、对系统调用流程的分析
六、遇到的问题
如下图,第一次克隆失败,后经检查发现是因为网址中的https误输成了http,经改正后成功克隆。