《Linux内核分析》课程第三周学习总结
姓名:何伟钦
学号:20135223
( *原创作品转载请注明出处*)
( 学习课程:《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
学习内容:构造一个简单的Linux系统MenuOS
第一部分:网上课程笔记
一、Linux内核源码主要结构简介
(一)内核源代码页面
、arch目录:在Linux内核源代码里占有的比重很大,因为Linux内核支持很多的体系结构,而arch目录是支持不同的CPU的源代码.arch/x86目录下的代码是重点
、Documentation目录:文档目录
、fs目录:文件系统
、init目录:内核启动相关的代码基本都在init目录下,其中的main.c代码里的start_kernel函数相当于普通C程序的main函数
、kernel/ 存放linux内核最核心的代码,用于实现系统的核心模块,包括进程管理、进程调度器、中断处理、系统时钟管理、同步机制等。 - 该目录中的代码实现这些核心模块的主体框架,独立于具体的平台和系统架构。核心模块与平台相关的代码放在arch/中。
(二)常用:Readme
介绍了什么是Linux,Linux能够在哪些硬件上运行,如何安装内核源代码;提供内核的各种编译方法、生成文件的查看方法。例如:
- INSTALLING 如何安装内核源代码
- make mrproper 清理安装时生成的中间代码
第二部分:构造一个简单的Linux系统MenuOS
(一) 运行MenuOS系统
1.在实验楼的虚拟机环境里,打击打开shell,使用下面的命令
cd LinuxKernel/
qemu -kernel linux-3.18./arch/x86/boot/bzImage -initrd rootfs.img
2.命令说明:
(1)qemu相当于打开一个虚拟机
(2)kernel启动一个Linux内核,位置由其后的文件名指定。如果在当前目录下,可以直接输入文件名,如果不是,则需要输入该内核的全路径。
(3)Linux-3.18.6是最新版本的Linux系统。rootfs是含有init函数的文件,生成的是rootfs.img
(4)initrd指令是挂了一个ramdisk虚拟硬盘,是内核的重要补充(指明一个根文件系统rootfs)
(5)rootfs是含有init函数的文件,生成的是rootfs.img
rootfs.img相当于虚拟硬盘,内有分区,然后启动的其实是其中的init文件
3.输入命令help和quit,可以看到有关help和quit命令的参数及说明
(二)使用gdb跟踪调试内核
1.使用带参数命令启动MenuOS
qemu -kernel linux-3.18./arch/x86/boot/bzImage -initrd rootfs.img -s -S
-s和-S参数说明:
# -S 在CPU初始化之前,冻结CPU
# -s 1234端口上创建一个tcp接口。若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项
2.用水平分割另外打开一个shell窗口之后,启动gdb进行调试
(gdb)file linux-3.18./vmlinux # 在gdb界面中targe remote之前加载符号表
(gdb)target remote: # 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行
(gdb)break start_kernel # 在start_kernel函数入口处设置断点
(gdb)c # 使得系统运行到start_kernel处停住
(gdb)list # 显示当前行所在位置上下的代码
(gdb)break rest_init
(gdb)c # 当前系统执行到rest_init
(gdb)list # 可以看到rest_init是在start_kernel的尾部调用的实验截图:
3.分析start_kernel(init目录下main.c的start_kernel函数)
void __init start_kernel(void)
该函数是Linux内核的入口,start_kernel()是内核的汇编与C语言的交接点,在该函数以前,内核的代码都是用汇编写的,完成一些最基本的初始化与环境设置工作。在start_kernel()中Linux将完成整个系统的内核初始化。内核初始化的最后一步就是启动init进程,这个所有进程的开始。不管分析内核那一部分都会涉及到start_kernel,因为几乎所有模块在初始化时都会调用它。
start_kernel是所有 Linux平台进入系统内核初始化后的入口函数,它主要完成剩余的与硬件平台相关的初始化工作在进行一系列与内核相关的初始化后,调用第一个用户进程-init进程并等待用户进程的执行,这样整个 Linux 内核便启动完毕。
4. init函数分析
(1)init_task:手工创建的PCB
全局变量init_task,即手工创建的PCB,0号进程初始化,0号进程就是最终的idle
(2)trap_init():初始化一些中断向量
中断向量表的初始化函数,设置了很多中断门,如set_intr_gate:设置中断门
(3)内存管理模块初始化 mm_init()
(4)调度模块初始化 sched_init()
(5)其它模块初始化 rest_init()
kernel_thread函数中的kernel_init包含一个run_init_process,创建了一号进程,即第一个用户态进程;
之后创建了kthreadd,一个内核线程来管理系统的资源。
(三)Linux内核启动过程相关的参考资料
1.
计算机的启动过程概述
(1)x86CPU启动的第一个动作CS:EIP=FFFF:0000H(换算为物理地址为000FFFF0H,因为16位CPU有20根地址线),即BIOS程序的位置。http://wenku.baidu.com/view/4e5c49eb172ded630b1cb699.html
(2)BIOS例行程序检测完硬件并完成相应的初始化之后就会寻找可引导介质,找到后把引导程序加载到指定内存区域后,就把控制权交给了引导程序。这里一般是把硬盘的第一个扇区MBR和活动分区的引导程序加载到内存(即加载BootLoader),加载完整后把控制权交给BootLoader。
(3)引导程序BootLoader开始负责操作系统初始化,然后起动操作系统。启动操作系统时一般会指定kernel、initrd和root所在的分区和目录,比如root (hd0,),kernel (hd0,)/bzImage root=/dev/ram init=/bin/ash,initrd (hd0,)/myinitrd4M.img
(4)内核启动过程包括start_kernel之前和之后,之前全部是做初始化的汇编指令,之后开始C代码的操作系统初始化,最后执行第一个用户态进程init。一般分两阶段启动,先是利用initrd的内存文件系统,然后切换到硬盘文件系统继续启动 initrd文件的功能主要有两个:
、提供开机必需的但kernel文件(即vmlinuz)没有提供的驱动模块(modules)
、负责加载硬盘上的根文件系统并执行其中的/sbin/init程序进而将开机过程持续下去
符合中国传统文化精神的内核核心代码:
道生一(start_kernel....cpu_idle),
一生二(kernel_init和kthreadd)
二生三(即前面0、1和2三个进程)
三生万物(1号进程是所有用户态进程的祖先,2号进程是所有内核线程的祖先)
学习体会:
Linux 内核是一个非常庞大的工程,清晰地了解它执行的每一个过程是件非常困难的事。但是在嵌入式开发过程中,我们并不需要十分清楚 linux的内部工作机制。通过对 linux的启动过程的分 析,我们可以看出哪些是和硬件相关的,哪些是 linux 内核内部已实现的功能。尽管对Linux有了一定的了解,但是通过这几周对Linux的学习,我仍然觉得深入了解Linux是件很有挑战性的事。。
参考资料:
(1)《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
Linux内核源代码简介;构造一个简单的Linux系统;跟踪调试Linux内核的启动Linux内核分析
(2)init进程详解
(3)Linux内核中的init_task进程和idle进程
(4)http://www.cnblogs.com/20135202yjx/p/5252102.html
《Linux内核分析》课程第三周学习总结的更多相关文章
- 《Linux内核分析》第三周学习笔记
<Linux内核分析>第三周学习笔记 构造一个简单的Linux系统MenuOS 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.stud ...
- 《Linux内核分析》第三周学习报告
<Linux内核分析>第三周学习报告 ——构造一个简单的Linux系统MenuOS 姓名:王玮怡 学号:201351 ...
- 《Linux内核分析》第三周学习小结 构造一个简单的Linux系统OS
郝智宇 无转载 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 第三周 构造一个简单的Linux系统Me ...
- 《Linux内核分析》第八周学习笔记
<Linux内核分析>第八周学习笔记 进程的切换和系统的一般执行过程 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163 ...
- 《Linux内核分析》第七周学习笔记
<Linux内核分析>第七周学习笔记 可执行程序的装载 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/co ...
- 《Linux内核分析》第六周学习笔记
<Linux内核分析>第六周学习笔记 进程的描述和创建 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/co ...
- 《Linux内核分析》第五周学习笔记
<Linux内核分析>第五周学习笔记 扒开系统调用的三层皮(下) 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.c ...
- 《Linux内核分析》第八周学习总结
<Linux内核分析>第八周学习总结 ——进程的切换和系统的一般执行过程 姓名:王玮怡 学号:20135116 ...
- 《Linux内核分析》第七周学习总结
<Linux内核分析>第七周学习总结 ——可执行程序的装载 姓名:王玮怡 学号:20135116 一.理论部分总结 (一)可执行程序的装载 ...
- 《Linux内核分析》第六周学习总结
<Linux内核分析>第六周学习总结 ——进程的描述和进程的创建 姓名:王玮怡 学号:20135116 一.理论部分 (一)进程的描述 1 ...
随机推荐
- npm WARN unmet dependency问题的解决方法
remove node_modules $ rm -rf node_modules/ run $ npm cache clean 详见这里: http://stackoverflow.com/ques ...
- sublime text3 setting-user
{ "caret_style": "smooth", "find_selected_text": true, "font_size ...
- 难度并不NOIP的NOIP模拟赛
今天老师请了前几届的学长来讲课,可是讲课为什么要考试呢... 学长说难度是NOIP,于是我就naive的跟着参加了,然而T3难度并不友好,感觉确实不是很适合我们现在做......不过课本来也不是给我们 ...
- day3-课堂笔记
函数有2种: 1种是有返回值的,不改变对象本身 1种是没有返回值的,改变对象本身 eval函数就是实现list.dict.tuple与str之间的转化(只能把类似格式的字符串进行相应转换)str函 ...
- day2-课堂笔记
#面向对象 函数=方法 系统内建函数:len().id() 对象函数
- WorldWind源码剖析系列:可渲染对象类RenderableObject
RenderableObject是WorldWind中所有需要渲染的对象的父类,继承了接口IRenderable和Icomparable.其派生类体系如下所示.RenderableObject的成员如 ...
- C语言中几种类型所占字节数
其实C标准并没有具体给出规定哪个基本类型应该是多少个字节数,而且这个也与OS.编译器有关,比如同样是在32位操作系统,VC++的编译器下int类型为4个字节,而在tuborC下则是2个字节. 下面给出 ...
- 关于javascript中对浮点加,减,乘,除的精度分析
大学专业是计算机童鞋或多或小的知道 计算机是由二进制存储和处理数字的,不能精确到处理浮点数,且javascript也没有这样的方法 所以在浏览器计算的时候也会有误差,比如说 我想用 3.3 / 1.1 ...
- JS实现 类似图片3D效果
其实这样的效果 目前很多网站上都有 其实以前也写过一个 只是当时代码只是为了实现而已,代码很乱,所以现在有业余时间研究了下,其实也并没有什么特殊地方 很类似于左右控制按钮切换图片的思路.效果如下: 可 ...
- JAVA框架 Mybaits 动态代理
一.动态代理: mybaits给咱们提供一套动态代理,我们只需要按他的要求写接口即可,mybatis帮做动态代理,相当于咱们写的接口的实现类.底层通过反射实例化代理对象,通过代理对象调用相应的方法, ...