linux 内核解析

[toc]

linux学习原因

最近有点闲,只能慢慢学习一下以前了解不深的地方,一条有梦想的闲鱼

linux内核实现的艺术, linux内核设计与实现

bios

linux系统启动前的硬件等设备自检环节,加载系统等

  • 为什么要使用bios
    在按下开机键的时候 内存里面什么也没有,如何把程序放入内存,如何执行肯定是有规范的.那么bios就做了一个规范,先启动bios,bios把程序加入到内存中,那如何启动bios呢,我们规定从0xFFFFF0开始执行bios程序,这是确定死的地方.不用再设置其他的了,硬件规定的地方. CS:IP会指向这个地方

  • bios在内存中加载中断向量表和中断服务:在0x00000到0x003ff一共1kb的长度一个中断4个字节一个256个中断,由于cs:ip要四个. 然后在0x00400用256个字节到0x00500构建数据区,然后用56kb加载服务

  • 然后执行把操作系统加载到内存中,分三批加载,第一批由bios中断int 0x19把第一扇区bootsect的内容加载到内存,第二批和第三批在bootsect的指挥下进行.
    • 0x19中断是把第一扇区的程序加载到内存的指定位置0x07c00: bootsect加载完毕
    • 现在就加载第二批第三批系统程序了:bootsect先规划内存(高级语言都是编译器和操作系统帮我们规划好了,但是bios是汇编语言,要考虑好内存问题),在实模式下寻址范围是1mb(实模式是20位的寻址寄存器),
    • 复制bootsect从内存0x07c00复制到0x9000 一共512b.
    • 将setUP程序加载到内存中: 要借用int 0x13中所指的中断服务进行.
    • 第三步加载system模块,使用int 0x13 加载240扇区120kb空间

实模式转向32位

  • 关中断: EFLAGS的if标志位为0,然后将system移动到内存地址为0x00000 的地方 原来是bios的中断向量处所以要关中断.(破旧立新)因为实模式是16位的 要转成32位的
  • 设置中断描述表和全局描述表: setUP程序自身提供数据信息对中断描述表IDTR和全局描述表GDTR进行初始化设置.
    • 16位中断是中断向量表从0x00000 , 而32位是中断描述符表IDT其位置是不固定的.
  • 打开A20,实现32位寻址,实模式是20位寻址,32位是4GB. 在实模式中当超过0xfffff 地址会回滚到0开始的地方继续寻找,a20实际上是删除了回滚机制
  • 为保护模式下执行head.s 做准备,重新设置中断 0x00 到0x1f设为内部中断,或异常中断.CR0寄存器的pe位为1是保护模式,为0是实模式.
  • 执行head.s,先将head.s汇编成目标代码,将用C语言写的内核程序编译成目标代码然后链接成system模块,head就是在开始的ox000000处属于system,head还创建了内核分页,并且创建的东西把自身执行完了的内存代码覆盖掉,这样然后就去执行main. head+main就是system

main函数

目的就是让用户程序能以进程的方式运行,
– 第一阶段: 创建进程0,让进程0具备在32位保护模式下在主机运算的能力
– 第二阶段: 以进程0为母本创建进程1,让进程1不仅仅具备0的所有能立,还能以文件形式与外设交互
– 第三阶段: 以进程1为母本,使2具有1的能力且支持”人机交互”,进程2是用户进程.

第一阶段:开中断之前的准备

在保护模式下 实模式转换时已经关中断了,
linux是一个多进程的系统,进程自身的边界保证进程之间的资源不相互干扰.这套边界就是系统为进程提供的进程管理信息
包含: 进程管理结构task_struct , 进程槽task[64],全局描述符表GDT. task_struct是每个进程独有的结构,包含进程的各项属性值(剩余时间片,进程执行状态,局部数据描述符表LDT,任务状态),task[64]和GDT是为了管理多进程设置的,task[64]中存储每个进程的task指针,GDT存储着对所有进程的索引.


评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注