《Linux内核分析》 第五节 扒开系统调用的三层皮(下)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《Linux内核分析》 第五节 扒开系统调用的三层皮(下)相关的知识,希望对你有一定的参考价值。
摘要:范闻泽
原创作品转载请注明出处
《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
1.实验环境是使用本课程配置的实验楼虚拟机环境,打开命令行客户端,cd LinuxKernel目录,使用命令rm -rf menu 删除原来的代码,使用git clone https://github.com/mengning/menu.git获取menu的最新代码,然后cd menu进入menu子文件夹,使用vi test.c打开文件,将上周实验的代码拷贝入test.c中,构造成两个函数,成为menu的两个菜单项。
cd LinuxKernel
rm menu -rf
git clone https://github.com/mengning/menu.git
cd menu
make rootfs
运行结果见截图
2、在test.c中增加2个函数代码 vi test.c
int menufork(int argc, char *argv[])
{
pid_t fpid;
int count = 0;
fpid = fork();
if (fpid < 0)
printf("error in fork!");
else if (fpid == 0) {
printf("i am the child process, my process id is %d\\n",getpid());
count++;
}
else {
printf("i am the parent process, my process id is %d\\n",getpid());
count++;
}
printf("count: %d\\n",count);
return 0;
}
int menuforkAsm(int argc, char *argv[])
{
pid_t fpid;
int count = 0;
asm volatile (
"mov $0, %%ebx\\n\\t"
"mov $0x2, %%eax\\n\\t"
"int $0x80\\n\\t"
"mov %%eax, %0\\n\\t"
: "=m" (fpid)
);
if (fpid < 0)
printf("error in fork!");
else if (fpid == 0) {
printf("i am the child process, my process id is %d\\n",getpid());
count++;
}
else {
printf("i am the parent process, my process id is %d\\n",getpid());
count++;
}
printf("count: %d\\n",count);
return 0;
}
在main()函数中添加两行命令
输入两个函数(输错了好几次)
3、运行2个新函数menufork, menufork-asm
函数编译完成后,意味着出现了两个进程,父进程和子进程,而两个进程返回的结果是不同的,子进程返回的函数值是0,父进程返回的是子进程的ID,所以可以通过函数值来判断是子进程还是父进程。
4、用gdb调试代码
gdb
file linux-3.18.6/vmlinux 加载调试用的符号表
target remote:1234
b start_kernel 设置断点
c
b sys_fork
在sys_getpid上打上断点。
最后无法继续跟踪调试代码,system_call()不是普通的函数,gdb不能在此停下。
5、简单总结
这次实验比较容易理解,但操作起来有点麻烦,在输入代码时还出现了几次错误导致时间大大增加,好在完成了。回顾整个实验,系统在进入内核态的同时先保护了中断地址和环境,然后调用系统函数,通过中断向量表将每一个系统调用和相关的函数关联起来,执行完系统函数,恢复中断环境,继续执行程序。
以上是关于《Linux内核分析》 第五节 扒开系统调用的三层皮(下)的主要内容,如果未能解决你的问题,请参考以下文章