《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、简单总结

这次实验比较容易理解,但操作起来有点麻烦,在输入代码时还出现了几次错误导致时间大大增加,好在完成了。回顾整个实验,系统在进入内核态的同时先保护了中断地址和环境,然后调用系统函数,通过中断向量表将每一个系统调用和相关的函数关联起来,执行完系统函数,恢复中断环境,继续执行程序。

时间: 2024-10-26 11:17:05

《Linux内核分析》 第五节 扒开系统调用的三层皮(下)的相关文章

linux内核分析 第五周 扒开系统调用的三层皮(下)

rm menu -rf 强制删除原menu文件 git clone http://github.com/mengning/menu.git 从github中克隆 cd menu 在test.c中增加上周编写的两个函数:Getpid()和GetpidAsm(),修改test.c中的main函数,添加两行代码MenuConfig make rootfs这一步之后会打开menu,输入help后可以看到当前的系统调用: 分别执行刚加进去的两个系统调用: 插入断点进行调试: 从system_call开始到

《Linux内核分析》第四周 扒开系统调用的“三层皮”

[刘蔚然 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] WEEK FOUR(3.14——3.20)扒开系统调用的“三层皮” SECTION 1 用户态.内核态和中断处理过程 1.用户态.内核态区别 在高级别的状态下,代码可以执行特权指令,访问任意的物理地址: 在相应的低级别执行状态下,代码的掌控范围会受到限制. 为什么会有这种级别划分? 没有访问权限划分容易使得系统混乱(毕竟普通程序

20135201李辰希 《Linux内核分析》第四周 扒开系统调用的“三层皮”

李辰希无转载 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.用户态.内核态和中断处理过程 1.我们与系统调用打交道是通过库函数的方式 2.一般现代CPU都有几种不同的指令执行级别 因为如果所有程序员写的代码都可以有特权指令的话,系统就会很容易崩溃. 3.区别: 在高级别的状态下,代码可以执行特权指令,访问任意的物理地址. 在相应的低级别执行状态下,代码的掌控范围会受到限制. Intel x86 CPU有四

Linux内核及分析 第五周 扒开系统调用的三层皮(下)

实验内容: 1.执行rm menu -rf命令,强制删除原有的menu 2.使用git命令 git clone https://github.com/mengning/menu.git 克隆新的menu 3.在test.c中,在main函数中增加两个MenuConfig 4.增加对应的GetPid函数和GetPidAsm函数 5.通过脚本 make rootfs,编译并运行Menu 6.设置断点使用gdb跟增系统调用内核函数sys_time 系统调用是一种中断: 1. 保存现场 在系统调用时,我

第五周 扒开系统调用的三层皮(下)

给MenuOS增加time和time-asm命令 更新menu代码到最新版 在main函数中增加MenuConfig 增加对应的Time函数和TimeAsm函数 make rootfs 使用gdb跟踪系统调用内核函数sys_time 一直按n单步执行会进入schedule函数 sys_time返回后进入汇编代码处理gdb无法继续跟踪 执行int 0x80之后执行system_call对应的代码 系统调用在内核代码中的处理过程 1.系统调用在内核代码中的工作机制和初始化 2.系统调用机制的初始化

实验五:扒开系统调用的三层皮(下)

实验五:扒开系统调用的三层皮(下) 王朝宪20135114 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.给MenuOS增加time和time-asm命令 1. 通过内核的方式(跟踪调试系统调用)来理解并使用系统调用. rm menu -rf //强制删除当前menu git clone http://github.com/mengning/menu.git //重新克隆新版本的m

20135201李辰希 《Linux内核分析》第五周 扒开系统调用的“三层皮”(下)

李辰希  原创作品转载请注明出处 <Linux内核分析> MOOC课程http://mooc.study.163.com/course/USTC-100002900 一.给MenusOS增加time和time-asm命令 1.操作步骤 进入实验楼 首先,强制删除当前的menu 克隆一个新的menu 进入menu之后,输入make rootfs,就可以自动编译 输入help,可以发现系统支持更多的命令: help version quit time time-asm 那么,time和time-a

20135327郭皓--Linux内核分析第四周 扒开系统调用的三层皮(上)

Linux内核分析第四周 扒开系统调用的三层皮(上) 郭皓 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 一.用户态.内核态和中断 用户态:当进程在执行用户自己的代码时,则称其处于用户态,即此时处理器在特权级最低的(3级)用户代码中运行. 内核态:当一个进程执行系统调用而陷入内核代码中执行时,我们就称进程处于内核态,此时处理器处于特权级最高的(0级)内核代码中执行. PS:CPU指令

《Linux内核分析》第四周笔记 扒开系统调用的三层皮(上)

扒开系统调用的三层皮(上) 一.用户态.内核态和中断 库函数将系统调用封装起来. 1.什么是用户态和内核态 一般现代CPU都有几种不同的指令执行级别. 在高执行级别下,代码可以执行特权指令,访问任意的物理地址,这种CPU执行级别就对应着内核态. 而在相应的低级别执行状态下(用户态),代码的掌控范围会受到限制.只能在对应级别允许的范围内活动.系统容易崩溃. 在intel X86CPU有四种不同的执行级别0,1,2,3,linux只使用了0级和3级分别来表示内核态和用户态. 2.在linux内核代码