翼度科技»论坛 云主机 LINUX 查看内容

操作系统启动的过程

11

主题

11

帖子

33

积分

新手上路

Rank: 1

积分
33
目录

操作系统,启动!

大致过程

​        计算机的工作方式是取指执行,而执行其的前提是内存中有代码。操作系统刚开始并不是在内存中,而是在磁盘上,因此第一步需要将其以一定的方式从磁盘读入内存。
(1)x86PC刚开机时CPU处于实模式(和保护模式对应),寻址方式为CS左移四位+IP
(2)开机时,CS = 0xFFFF;IP = 0X0000
(3)寻址0xFFFF0(ROM BIOS映射区)
开机时内存中唯一有代码的地方
(4)检查RAM,键盘,显示器,软硬磁盘
(5)将磁盘0磁道0扇区(引导扇区,操作系统的第一段代码bootsect.s)读入0x7c00处
一个扇区512字节
.s 汇编代码
(6)设置cs = 0x7c0,ip = 0x0000
以下摘自《Linux内核完全注释》
​        这里先总的说明一下 Linux 操作系统启动部分的主要执行流程。当 PC 的电源打开后,80x86 结构的 CPU 将自动进入实模式,并从地址 0xFFFF0 开始自动执行程序代码,这个地址通常是 ROM-BIOS 中的 地址。PC 机的 BIOS 将执行某些系统的检测,并在物理地址 0 处开始初始化中断向量。此后,它将可启 动设备的第一个扇区(磁盘引导扇区,512 字节)读入内存绝对地址 0x7C00 处,并跳转到这个地方。启 动设备通常是软驱或是硬盘。这里的叙述是非常简单的,但这已经足够理解内核初始化的工作过程了。
​        Linux 的最最前面部分是用 8086 汇编语言编写的(boot/bootsect.s),它将由 BIOS 读入到内存绝对地 址 0x7C00(31KB)处,当它被执行时就会把自己移到绝对地址 0x90000(576KB)处,并把启动设备中后 2kB 字节代码(boot/setup.s)读入到内存 0x90200 处,而内核的其它部分(system 模块)则被读入到从地址 0x10000 开始处,因为当时 system 模块的长度不会超过 0x80000 字节大小(即 512KB),所以它不会覆 盖在 0x90000 处开始的 bootsect 和 setup 模块。后面 setup 程序将会把 system 模块移动到内存起始处,这 样 system 模块中代码的地址也即等于实际的物理地址,便于对内核代码和数据的操作。图 3-1 清晰地显 示出 Linux 系统启动时这几个程序或模块在内存中的动态位置。其中,每一竖条框代表某一时刻内存中各程序的映像位置图。在系统加载期间将显示信息"Loading..."。然后控制权将传递给 boot/setup.s 中的代 码,这是另一个实模式汇编语言程序。

重要程序

bootsect.s
  1. .globl begtext,begdata,begbss,endtext,enddata,endbss
  2. .text        //文本段
  3. begtext:
  4. .data        //数据段
  5. begdata:
  6. .bss        //未初始化数据段
  7. begbss:
  8. entry start        //关键字entry告知链接器,程序从start标号开始执行
  9. start:
  10.         mov ax, #BOOTSEG        //将ds段寄存器置为0x07c0
  11.         mov ds, ax
  12.         mov ax, #INITSEG        //将es段寄存器置为0x9000
  13.         mov es, ax
  14.         mov cx, #256                //移动计数值=256字
  15.         sub si, si                        //源地址        ds:di = 0x07c0:0x0000
  16.         sub di, di                        //目标地址        es:si = 0x9000:0x0000
  17.         rep
  18.         movw
  19.         jmpi go, INITSEG        //间接跳转,cs=0x9000,ip=go
  20.        
  21. go:        mov ax, cs                        //cs=0x9000
  22.         mov ds, ax
  23.         mov es, ax
  24.         mov ss, ax
  25.         mov sp, #0xFF00                //由于代码移动过了,所以要重新设置堆栈段的位置。sp只要指向远大于512偏移(即地址0x90200)处都可以。因为从0x90200地址开始处还要放置setup程序,而此时setup程序大约为4个扇区,因此sp要指向大于(0x200+0x200*4+堆栈大小)处
  26.        
  27. load_setup:
  28.         mov dx, #0x0000
  29.         mov cx, #0x0002
  30.         mov bx, #0x0200
  31.         mov ax, #0x0200+SETUPLEN
  32.         int 0x13                        //利用BIOS中断INT 0x13将setup模块从磁盘第二个扇区开始读到0X90200处,共读4个扇区。如果读出错,则复位驱动器,并重试
  33.         jnc ok_load_setup
  34.         mov dx, #0x0000
  35.         mov ax, #0x0000        //复位
  36.         int 0x13
  37.         j load_setup        //重读
  38.        
  39. ok_load_setup:
  40.         mov dl, #0x00
  41.         mov ax, #0x0800
  42.         int 0x13
  43.         mov ch, #0x00
  44.         seg cs
  45.         mov sectors, cx
  46.         mov ah, #0x03                //显示一些信息('Loading system...'共24个字符)
  47.         xor bh, bh                //读光标位置
  48.         int 0x10
  49.         mov cx, #24                //共24个字符
  50.         mov bx, #0x0007        //显示属性
  51.         mov bp, #msg1        //指向要显示的字符串
  52.         mov ax, #0x1301
  53.         int 0x10                //显示字符
  54.         mov ax, #STSSEG                //0x1000
  55.         mov es, ax
  56.         call read_it                //读入system模块
  57.         jmpi 0, SETUPSEG        //跳转到0x9020:0000(setup.s程序的开始处)
复制代码
setup.s

head.s


来源:https://www.cnblogs.com/Elysiaiii/p/18272106
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具