跟踪分析Linux内核的启动过程
来源:互联网 发布:惠州市干部网络 编辑:程序博客网 时间:2024/05/16 09:02
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
张磊+ 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
使用实验楼虚拟机打开 shell
cd LinuxKernel/qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img运行结果如图所示:
内核启动进入 menu 程序。
下面是用 gbd 来跟踪内核的启动过程:
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
另开一个 shell 窗口
gdb(gdb)file linux-3.18.6/vmlinux # 在gdb界面中targe remote之前加载符号表(gdb)target remote:1234 # 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行(gdb)break start_kernel # 断点的设置可以在target remote之前,也可以在之后如图加 断点后程序运行停止在了 start_kernel 处。
这个函数在init/main.c:
asmlinkage __visible void __init start_kernel(void){char *command_line;char *after_dashes;/* * Need to run as early as possible, to initialize the * lockdep hash: */lockdep_init();set_task_stack_end_magic(&init_task);smp_setup_processor_id();debug_objects_early_init();
首先是调用 lockdep_init函数 :
void lockdep_init(void){int i;/* * Some architectures have their own start_kernel() * code which calls lockdep_init(), while we also * call lockdep_init() from the start_kernel() itself, * and we want to initialize the hashes only once: */if (lockdep_initialized)return;for (i = 0; i < CLASSHASH_SIZE; i++)INIT_LIST_HEAD(classhash_table + i);for (i = 0; i < CHAINHASH_SIZE; i++)INIT_LIST_HEAD(chainhash_table + i);lockdep_initialized = 1;}
注释写得很清楚,有些体系结构有自己的start_kernel也会调用lockdep_init,这里只会调用一次,来初始化hash表。
其它函数就不在这里一一描述了,当执行到init 函数时,init是第一个调用的使用标准C库编译的程序。在此之前,还没有执行任何标准的C应用程序。在桌面Linux系统上,第一个
启动的程序通常是/sbin/init,它的进程号为1。init进程是所有进程的发起者和控制者,它有两个作用:
(1)扮演终结父进程的角色:所有的孤儿进程都会被init进程接管。
(2)系统初始化工作:如设置键盘、字体,装载模块,设置网络等。
小结:
x86架构的Linux内核启动过程分为6大步,分别为:
(1)实模式的入口函数_start():在header.S中,这里会进入众所周知的main函数,它拷贝bootloader的各个参数,执行基本硬件设置,解析命令行参数。
(2)保护模式的入口函数startup_32():在compressed/header_32.S中,这里会解压bzImage内核映像,加载vmlinux内核文件。
(3)内核入口函数startup_32():在kernel/header_32.S中,这就是所谓的进程0,它会进入体系结构无关的start_kernel()函数,即众所周知的Linux内核启动函数。start_kernel()会
做大量的内核初始化操作,解析内核启动的命令行参数,并启动一个内核线程来完成内核模块初始化的过程,然后进入空闲循环。
(4)内核模块初始化的入口函数kernel_init():在init/main.c中,这里会启动内核模块、创建基于内存的rootfs、加载initramfs文件或cpio-initrd,并启动一个内核线程来运行其中
的/init脚本,完成真正根文件系统的挂载。
(5)根文件系统挂载脚本/init:这里会挂载根文件系统、运行/sbin/init,从而启动众所周知的进程1。
(6)init进程的系统初始化过程:执行相关脚本,以完成系统初始化,如设置键盘、字体,装载模块,设置网络等,最后运行登录程序,出现登录界面。
如果从体系结构无关的视角来看,start_kernel()可以看作时体系结构无关的Linux main函数,它是体系结构无关的代码的统一入口函数,这也是为什么文件会命名为init/main.c的
原因。这个main.c粘合剂把各种体系结构的代码“粘合”到一个统一的入口处。
- 跟踪分析Linux内核的启动过程
- 跟踪分析Linux内核的启动过程
- 跟踪分析Linux内核的启动过程
- 跟踪分析Linux内核的启动过程
- 跟踪分析内核的启动过程(Linux)
- 跟踪分析Linux内核的启动过程
- 跟踪分析Linux内核的启动过程
- 跟踪分析Linux内核的启动过程
- 跟踪分析Linux内核的启动过程
- 跟踪分析Linux内核的启动过程
- 跟踪分析Linux内核的启动过程
- 跟踪分析Linux内核的启动过程
- Linux内核分析:跟踪分析Linux内核的启动过程
- Linux内核分析------跟踪分析Linux内核的启动过程
- 学习笔记3-跟踪分析Linux内核的启动过程
- 实验三:跟踪分析Linux内核的启动过程
- 实验三:跟踪分析Linux内核的启动过程
- 利用gdb跟踪分析Linux内核的启动过程
- Zend Studio 安装Aptana插件 (html,css,js代码提示功能)
- 梯度下降法
- 娃儿好玩儿
- P51页第6题
- 移植FreeRTOS,出现No space in execution regions溢出错误。
- 跟踪分析Linux内核的启动过程
- 从淘宝美工跳槽到web前端开发
- linux启动过程
- iOS多线程编程技术之NSThread、Cocoa NSOperation、GCD
- 娃儿好玩儿
- 这种设计谁说不能打动你?
- Mac OS X 10.10.2 安装包下载 , 免App Store , 官方原 ...
- [转]C语言中通过分隔符来截取字符串
- protel99中为什么有的区域铺不上铜?