Linux课程3:分析Linux内核的启动过程

    xiaoxiao2021-03-25  81

    陈涛 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ” 本次课程主要是使用gdb对start_kernel()函数进行跟踪调试。

    一、启动内核

    在实验楼下命令行输入来启动内核: cd LinuxKernel/ qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img

    二、gbd基本知识

    GDB是一个由GNU开源组织发布的、UNIX/Linux操作系统下的、基于命令行的、功能强大的程序调试工具。

    gdb一些参数 r(run) 开始运行程序; c(continue) 继续运行一直到断点停止 b(break) 设置程序断点 finish 跳出函数调试,并打印返回时的信息 q(quit) 退出gdb l(list) 显示当前行后面的源程序 clear 清除全部已定义的断点 delete 删除指定的断点

    1、重新运行内核 qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S 关于-s和-S选项的说明: -S freeze CPU at startup (use ’c’ to start execution) -s shorthand for -gdb tcp::1234 若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项

    此时内核程序被冻结:

    在打开一个命令行界面: gdb (gdb)file linux-3.18.6/vmlinux # 在gdb界面中targe remote之前加载符号表 (gdb)target remote:1234 # 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行 (gdb)break start_kernel #设置断点 这时,程序运行到start_kernel()这里,用list来查看代码,如图: 在设置一个断点到rest_init(), (gdb)break rest_init (gdb)c (gdb)list

    三、start_kernel()总结

    asmlinkage void __init start_kernel(void){ ........ set_task_stack_and_magic(&init_task);//手工穿件PCB,0号进程 ....... trap_init();//设计一些终端,初始化一些终端向量 ...... mm_init();//内存管理模块 sched_init();//调度模式 ...... rest_init();//start_kernel会启动,一直存在0号进程 }

    start_kernel()是内核的汇编与C语言的交接点,在该函数以前,内核的代码都是用汇编写的,完成一些最基本的初始化与环境设置工作,比如内核代码载入内存并解压缩(现在的内核一般都经过压缩),CPU 的最基本初始化,为 C 代码的运行设置环境(C 代码的运行是有一定环境要求的,比如 stack 的设置等)。

    转载请注明原文地址: https://ju.6miu.com/read-35101.html

    最新回复(0)