2020-2021-1 20209326 《Linux内核原理与分析》第六周作业
作业信息
这个作业属于哪个课程 | <2020-2021-1Linux内核原理与分析)> |
---|---|
这个作业要求在哪里 | <2020-2021-1Linux内核原理与分析第六周作业> |
这个作业的目标 | <使用gdb跟踪分析一个系统调用内核函数> |
作业正文 | <本博客链接> |
目录
一、实验内容
1. 给MenuOS增加命令
修改test.c文件,新增creat功能。
rm -rf menu
git clone https://github.com/mengning/menu.git
cd menu
make rootfs
2. 用GDB来跟踪系统调用内核的函数sys_time
//启动内核
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage/ -initrd rootfs.img -S -s
//新打开一个shell窗口,启动gdb
file linux-3.18.6/vmlinux
target remote:1234
//加入断点
b start_kernel//代码会在start_kernel()处停下来
b sys_time //调试time系统调用
b sys_creat //调试creat系统调用
查看了linux-3.18.6/fs/open.c和linux-3.18.6/kernel/time/time.c文件。因为系统调用是用宏来定义的,所以无法直接调试。
3.在linux-3.18.6/arch/x86/kernel/entry_32.S查看system_call源码
一旦执行int 0x80,CPU就直接跳转到system_call这个位置来执行,即系统调用的工作机制在start_kernel这里初始化之后,CPU一遇到int 0x80就会立即跳转到sys_call的位置,system_call中断服务程序的入口这段会变代码的处理过程是非常重要的,它是系统调用的处理过程,而系统调用是一个特殊的中断,在中断过程中有保护现场和恢复现场,这段代码里面同样也有保护现场SAVE_ALL和恢复现场restore_all的过程。
# system call handler stub
ENTRY(system_call)
RING0_INT_FRAME # can't unwind into user space anyway
ASM_CLAC
pushl_cfi %eax # save orig_eax//保存系统调用号
SAVE_ALL //保存现场,将用到的所有CPU寄存器保存到栈中
GET_THREAD_INFO(%ebp) //ebp用于存放当前进程thread_info结构的地址
# system call tracing in operation / emulation
testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
jnz syscall_trace_entry
cmpl $(NR_syscalls), %eax //检查系统调用号(系统调用号应小于NR_syscalls)
jae syscall_badsys //不合法,跳入异常处理
syscall_call:
call *sys_call_table(,%eax,4) //合法,对照系统调用号在系统调用表中寻找相应的系统调用的内核处理函数
syscall_after_call:
movl %eax,PT_EAX(%esp) # store the return value//保存返回值到栈中
syscall_exit:
LOCKDEP_SYS_EXIT
DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt
# setting need_resched or sigpending
# between sampling and the iret
TRACE_IRQS_OFF
movl TI_flags(%ebp), %ecx
testl $_TIF_ALLWORK_MASK, %ecx # current->work//检查是否需要处理信号
jne syscall_exit_work //需要,进入 syscall_exit_work
restore_all:
TRACE_IRQS_IRET //不需要,执行restore_all恢复,返回用户态
restore_nocheck:
RESTORE_REGS 4 # skip orig_eax/error_code
irq_return:
INTERRUPT_RETURN //相当于iret
二、总结
1.系统调用过程
2.系统调用处理过程的理解
通过本实验的学习,知道了:系统调用时,首先通过save_all来保存现场,然后进行系统调用,并将返回值放入寄存器eax中,然后确认有没有其他的中断进入,以便设置返回信号。如果没有就从系统调用返回,并通过函数restore_all恢复现场;如果有就进入函数syscall_exit_work,查看有没有挂起的任务,有就转入函数work_pending进行任务调度,没有就返回,并恢复现场。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· DeepSeek智能编程
· 精选4款基于.NET开源、功能强大的通讯调试工具
· [翻译] 为什么 Tracebit 用 C# 开发
· 腾讯ima接入deepseek-r1,借用别人脑子用用成真了~
· DeepSeek崛起:程序员“饭碗”被抢,还是职业进化新起点?