2019-2020-20199316《Linux内核原理与分析》第四周作业
构造一个简单的Linux内核
如何构建一个Linux系统
在实验楼的虚拟机中,两个简单的命令就可以把linux系统和简单的文件系统运行起来。
cd LinuxKernel/
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img
-
备注 :qemu需要创建窗口,他在纯命令系统下无法工作。
-
注解:qemu仿真kernel;bzImage是vnLinux经过gzip压缩后的文件,是压缩的镜像内核,“b”代表的是“big”(bzImage适用于大内核,zImage适用于小内核)。vmLinux是编译出来的最原始的内核ELF文件;根文件系统一般包括内存根文件系统和磁盘文件系统。initrd是“initial ramdisk”的简写,普通Linux用户一般感受不到这个内存根文件系统的存在,因为普通Linux系统在启动时,是boot loader将存储介质中的initrd文件加载到内存,内核启动时先访问initrd文件系统(内存根文件系统),然后在切换到磁盘文件系统。
-
打开shell
-
用-S -s的方法暂停运行
-
然后再另外打开一个shell窗口,用Ctrl+Shift+O实现水平分割,启动gdb,把内核加载进来,建立连接。
-
然而,打开gdb汇编时遇到了问题- -,连接超时.......
-
因为可能上述问题不太常见,所以并没有找到解决方法,后来发现是因为我关闭了qemu窗口,所以导致连接不上。重写qemu代码后即可,并且设置断点start_kerenl 和 rest_init:
start_kernel分析
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();
.............
/* Do the rest non-__init'ed, we're now alive */
rest_init();
}
- 分析:start_kernel()相当于c语言中的main函数,是一切的起点,在此函数被调用之前,内核代码主要是用汇编语言写的,用于完成硬件系统的初始工作。
内核源码目录
- arch:用于存放CPU体系结构代码。
- block:存放Linux存储体系中关于块设备管理的代码。
- Documentation:存放一些文档。
- drivers:驱动目录。
- fs:文件系统,存放了Linux支持的各文件系统。
- include:头文件目录。。
- init:存放Linux内核启动时的初始化代码。
- lib:存放Linux的共用库文件。
- mm:内存管理。
- net:存放网络的相关代码。