两个月Linux内核的学习过程,让我理解了Linux的基本工作原理,掌握了Linux的常用命令,但仍感其路漫漫,需更加深入领会。
一、学习目录
第一周《计算机是如何工作的?》 http://www.cnblogs.com/Nancy5104/p/5215595.html
第二周《操作系统是如何工作的?》 http://www.cnblogs.com/Nancy5104/p/5244715.html
第三周《构建一个简单的操作系统MenuOS》 http://www.cnblogs.com/Nancy5104/p/5267189.html
第四周 《扒开操作系统的“三层皮”(上)》 http://www.cnblogs.com/Nancy5104/p/5286555.html
第五周《扒开操作系统的“三层皮”(下)》 http://www.cnblogs.com/Nancy5104/p/5313150.html
第六周《进程的描述与创建》 http://www.cnblogs.com/Nancy5104/p/5338062.html
第七周《可执行程序的装载》 http://www.cnblogs.com/Nancy5104/p/5338062.html
第八周《进程的切换和系统的一般执行过程》 http://www.cnblogs.com/Nancy5104/p/5389990.html
二、知识点梳理
1.计算机是如何工作的?
寻址方式
直接寻址:movl $0x123,%eax
立即数寻址:movl 0x123,%eax
变址寻址:movl 4(%ebx),%edx ebx的值加4之后作为一个地址,将其指向的数据赋给%edx
重要的汇编指令:
enter指令相当于在原来的堆栈上再建一个新的空堆栈,leave指令与enter相反,相当于撤销函数调用堆栈
存储程序计算机工作模型:冯诺依曼体系结构
X86汇编基础:CPU的寄存器(通用寄存器、段寄存器、标志寄存器)、常见汇编指令、堆栈
汇编一个简单的C程序分析其汇编指令执行过程
2.操作系统是如何工作的?
三个法宝:
存储程序计算机:所有计算机基础性的逻辑框架
堆栈:高级语言的起点,函数调用需要堆栈机制
中断机制:多道系统的基础,是计算机效率提升的关键
3.构建一个简单的操作系统MenuOS
构造一个简单的Linux系统
cd LinuxKernel/ qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img
qemu命令是模拟内核启动虚拟机,启动Linux内核需要三个参数(kernel、initrd、root所在的分区和目录),执行的第一个文件是init。
-kernel指明内核文件名
-initrd指明根文件系统,启动其中的init文件。(menuOS源代码编译->init->rootfs.img)其中rootfs.img 为根文件系统,目前只支持help、version、quit功能。
启动过程为:启动内核->启动init->启动进程
跟踪调试Linux内核的启动过程
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
4.扒开操作系统的“三层皮”(上)
用户态、内核态和中断处理过程:
内核态:一般现代CPU有几种指令执行级别。在高执行级别下,代码可以执行特权指令,访问任意的物理地址,这种CPU执行级别对应着内核态。
用户态:在相应的低级别执行状态下,代码的掌控范围有限,只能在对应级别允许的范围内活动。
中断处理是从用户态进入内核态的主要方式,中断/int指令会在堆栈上保存一些寄存器的值:如用户态栈顶地址、当前的状态字、当时cs:eip的值(当前中断程序的入口)。
系统调用概述:
系统调用是操作系统为用户态进程与硬件设备进行交互提供的一组接口。
系统调用概述和系统调用的三层皮:xyz(API)、system_ call(中断向量)、sys_xyz(中断向量对应的中断服务程序)。
5.扒开操作系统的“三层皮”(下)
给MenuOS增加time和time-asm命令
rm menu -rf //首先删除当前的menu git clone http://github.com/mengning/menu.git //克隆新版本的menu,需联网下载 cd menu ls make rootfs vi test.c //进入test.c文件 MenuConfig("getpid","Show Pid",Getpid); MenuConfig("getpid_asm","Show Pid(asm)",GetpidAsm); //向main函数写MenuConfig() int Getpid(int argc,char *argv[]); int GetpidAsm(int argc,char *argv[]); //增加Getpid和GetpidAsm make rootfs
使用gdb跟踪系统调用内核函数sys_time
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S gdb (gdb)file linux-3.18.6/vmlinux (gdb)target remote:1234 //首先应连接到需要调试的MenuOS (gdb)b start_kernel //设置断点 (gdb)c list //可查看start_kernel的代码 (gdb)b sys_time //13号系统调用对应的内核处理函数时sys_time (gdb)c
系统调用在内核代码中的工作机制和初始化