从北京做完项目回来,老师也没安排做新项目,趁着这段自由时间学习一下linux内核。我参考的是赵炯的《linux内核完全注释》,源码是linux0.11.
首先不得不佩服intel,没有intel的cpu硬件设计,不可能有操作系统的出现,intel cpu提供了访问接口,中断控制,没有这些底层的基础,上层的代码就算再牛B也不可能控制底层的硬件。
linux 内核体系结构
linux作为一个操作系统,无非要包含内存管理,进程调度,文件系统,设备驱动这几个必不可少的模块。
linux 引导启动
以前一直不明白计算机的启动过程,为什么只要一按电源,系统就自动加载好了,计算机究竟做了哪些事?学了 linux引导启动后明白了点。linux的引导启动包含bootsect.s,setup.s,head.s三个文件,linux引导启动的任务就是把linux内核从硬盘读到内存中,设置全局变量描述符表和中断描述符表,最后把启动任务交给init/main.c。这三个文件都是用汇编语言写的,前两个是intel 汇编,后一个是AT & T汇编,幸好本科的时候还学过《80X86汇编语言程序设计》,有点汇编语言的功底,看源码也不是很费劲。这部分最难的是要知道cpu,8259等芯片的接口设计,对硬件知识要求较高。要我自己写这些代码那是难为我,要看明白还凑合。
bootsect.s
通过BIOS把bootsect.s读到内存的0x7c00处,当bootsect.s被执行时,它把自己移到0x90000处,并且把setup.s读到0x90200处,把内核的其他模块读到从0x10000开始到0x90000的内存空间。利用的都是BIOS中断,移动内存用rep movw 汇编命令。
setup.s
利用BIOS中断获取系统的数据,比如磁盘、显卡、内存等信息,保存到0x90000开始的位置,接下来把system代码模块从0x10000 ~0x90000空间移动到0x00000~0x80000空间。接下来加载全局描述符表寄存器和中断描述符表寄存器。最后设置CR0(机器状态字),进入保护模式。跳转到head.s.
head.s
加载各个数据段寄存器,重新设置中断描述符表idt,重新设置全局描述符表gdt。接下来设置管理内存的分页处理机制,内存分页处理机制包含一个页目录表和4个页表。页目录表有4个表项,每个表项描述一个也表的信息,每个页表的表项描述一页内存的信息。这4个页表是供内核使用的。最后运行main()程序。
实模式 和保护模式
实际上这两种模式的不同之处就在于寻址方式不同,实模式使用段地址和偏移地址来寻址,DS中保存的就是段的地址,只有16位,所以段的大小不能超过16KB,寻址范围不超过1M。
保护模式引进了一个段描述表,段描述符表项中记录的是段的信息:地址,长度...在保护模式中DS中保存的是某个描述符表项相对于这个表的偏移量,也就是要寻址的描述符表项。保护模式能过寻址的范围大得多,32位的可以达到64T。
阅读(464) | 评论(0) | 转发(0) |