计算机启动时, 内存(RAM)没有任何东西, 自然也无法跑操作系统. 但是可以执行固化在ROM里面的BIOS程序. 在按下电源键的一刻. CPU的cs和ip寄存器硬件被设置为0xf000和0xfff0, 于是cs:ip也就指向0xffff0这个地址, 而这个地址正是指向了ROM的BIOS范围(这里是0xfe000~0xfffff, 20根地址线全部范围0x0000~0xfffff, 这个范围包括RAM、ROM、其他map的外设).
于是cpu开始执行BIOS程序. BIOS从第一条指令开始的首要工作是,在内存最开始的位置用1KB的内存空间(0x00000~0x003FF)构建中断向量表, 在紧挨着它的位置用256字节的内存空间构建BIOS数据区(0x00400~0x004FF), 并在大约57KB以后的位置(0x0E05B~0x0FFFE)加载了8KB左右与中断向量表相应的若干中断服务程序.
中断也是程序,必须由cpu执行. 也就是说cpu的寄存器cs:ip须被设置以找到相应程序的地址. 中断分为BIOS中断和Linux中断. 后者先暂且不表, 前者是存在于实模式下的程序,它的中断调用都是建立在中断向量表基础上的。而BIOS中断都是通过软中断指令INT xxx来调用的. 中断向量表中的每个向量大小是4byte(2个byte分别cs:ip值), 有256项(共占据1KB).
然后BIOS接着会进行一些硬件自检操作, 没问题后重头戏来了: BIOS会发起一个0x19的软中断. 刚才说了, BIOS已经把中断向量表配置好了, CPU根据中断号0x19去起始于RAM 0地址的向量表找到相应的向量, 该向量指向中断服务程序的地址(该地址也指向BIOS), 去执行0x19程序. 其功能是把启动扇区(0盘面0磁道1扇区)的所在硬盘的512kb复制到内存的0x7c00位置. 这个512kb就是对应操作系统最初始的代码, 名为bootsec(引导程序)第一部分内核代码被编译成2进制放在硬盘的启动扇区里. 此外此程序还会设置cs:ip为0x7c00:0x0000让CPU去执行bootsec.
接着开始执行真正属于Linux的代码了, 虽然还是用汇编写的bootsec.
参考:
你管这破玩意叫操作系统源码 | 第一回 最开始的两行代码
《操作系统真象还原》——0.20 BIOS中断、DOS中断、Linux中断的区别-阿里云开发者社区
CPU的中断那些事儿