《linux内核原理与分析》第六周作业
这个作业属于哪个课程 | 2020-2021-1 Linux内核原理与分析 |
这个作业要求在哪里 | 2020-2021-1Linux内核原理与分析第六周作业 |
这个作业的目标 | 给MenuOS添加上周实现的系统调用、使用gdb分析sys_time执行过程、了解系统调用执行过程 |
作业正文 | 本博客链接 |
目录
一.首先先将上周实现的系统调用添加到MenuOS中
二.在MenuOS中添加系统调用,代码如下:
int mygetpid(int argc,char *argv[])
{
int pid;
pid = getpid();
printf("Hello 20209324!This pid is :%d
",pid);
return 0;
}
以及在main函数中添加关于getpid的调用,如图所示:
三.用GDB来跟踪系统调用内核的函数sys_time
启动内核以及gdb,并将内核加载进gdb,通过端口1234进行调试。
详情如图所示:
发现虽然文件存在,但是在此断点处却不能进行中断,所以查看time.c的源码来进行检查。
四.寻找system_call的汇编代码并进行分析
ENTRY(system_call)
RING0_INT_FRAME //切换内核态
ASM_CLAC
pushl_cfi %eax //将系统调用号放入eax寄存器中
SAVE_ALL
GET_THREAD_INFO(%ebp) //ebp用于存放当前进程地址
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) //根据系统调用表,调取相应的系统调用处理函数,每个表项栈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 //有任务,进入system_exit_work进行进程调度
restore_all:
TRACE_IRQS_IRET //恢复现场
restore_nocheck:
RESTORE_REGS 4
irq_return:
INTERRUPT_RETURN //系统调用返回