Upon starting, a personal computer's x86 CPU runs the instruction located at the memory location F000:FFF0 (on 286s and 386SXs, the base of the code segment is actually 0xFF0000 and on 386s it is 0xFFFF0000) of the BIOS. This memory location is close to the end of system memory. It contains a jump instruction that transfers execution to the location of the BIOS start-up program. This program runs a power-on self test (POST) to check that devices the computer will rely on are functioning; it also initializes these devices. Then, the BIOS goes through a preconfigured list of non-volatile storage devices ("boot device sequence") until it finds one that is bootable. A bootable device is one such that it can be read from and the last two bytes of the first sector contain the word 0xAA55 (also known as the boot signature). On IBM PCs and derivatives made by IBM, if it finds no such device, control is transferred to IBM Cassette BASIC. On other IBM PC compatibles, an error message is generated and the boot process stops.
Once BIOS has found a bootable device, BIOS loads the bootsector to hexadecimal Sector:Offset address 0000:7C00 and transfers execution to the boot sector. In the case of a hard drive, this is referred to as the master boot record (MBR) and is often not operating system specific. The conventional MBR code checks the MBR's partition table for an active partition(the one with active flag set)[1]. If one is found, the MBR code loads that partition's boot sector and executes it. The boot sector is often operating system specific, however in most operating systems its main function is to load and execute the operating system kernel, which continues startup. If there is no active partition or the active partition's boot sector is invalid, the MBR may load a secondary boot loader and pass control to it and this secondary boot loader will select a partition (often via user input) and load its boot sector, which usually loads the corresponding operating system kernel.
这里有一段,from《Linux开机过程研讨--许景华》:http://linux.chinaunix.net/bbs/viewthread.php?tid=182383但是有一点(a little bit trivial,though)有问题的:下文提到的是刚刚power up的时候,CS=FFFFh IP=0000h,然而wikipedia上的是CS=F000h IP=FFF0h,
不过结果都是一样的(CS:IP = FFFF0h),因此这里不深入探究。(觉得下文的比较make sense)
想必各位都知道 , 在刚开机时 , 由于 80x86 的特性 , CS ( Code Segment )
这个寄存器中全部都放着 1 , 而 IP ( Instruction Pointer ) 这个寄存器
中全部都放着 0 , 换句话说 , CS=FFFF 而 IP=0000 , 此时 , CPU 就依据
CS 及 IP 的值 , 到 FFFF0H 去执行那个地方所放的指令 . 这时候 , 由于
FFFF0H 已经到了高位址的顶端 , 所以 , FFFF0H 这个地方 , 总是会放一个
JMP 指令 , 跳到比较低的位址 . 接著 , ROM BIOS 就会作一些检查的动作
像内存 , 键盘 等...... 并在我们俗称的 UMB ( Upper Memory Block )
之中扫描 , 看看是否有合法的 ROM 存在 ( 比如 SCSI 卡上的 ROM ) .
假如有 , 就到里面去执行一些东西 , 执行完之后再继续刚才的行程 . 到了
最后 , 读取硬盘上的第一个 sector . 在这里 , 我假设各位由硬盘启动
因此 , 就硬盘的构造而言 , 它的第一个 sector 称为 MBR ( Master Boot
Record ) . 因为一个 sector 是 512 bytes , 而 MBR 这 512 bytes 可分
为两个部份 , 第一个部份为 Pre-Boot 区 , 占了 446 bytes ; 第二部份
是 Partition Table , 占了 66 bytes . Pre-Boot 区的作用之一 , 就是
去看看那个 Partition 被标成 Active , 然後去读那个 Partition 的 Boot
区 .
在 Linux 的启动方面 , 一般人最常把 LILO 放在 MBR 或 Superblock
假如你把 LILO 放在 MBR , 那很明显的 , 当读取到 MBR 的时候 , LILO
就被执行 , 此时 , 你的屏幕上会出现 boot: 接着 , 就进行 Load Kernel
的动作 . 在另一方面来说 , 假如你把 LILO 安装在 Superblock , 通常你
还会有一个管理开机的程序 , 也许是放在 MBR ( 像 OSBS ) 或者是放在一
个单独的 Partition ( 像 OS/2 的 Boot Manager ) . 再由这个管理开机
的程式去读取 LILO , 进而做 Load Kernel 的动作 .
我的总结如下:
POWER-ON -> BIOS program(POST) -> check non-volatile storage ->
CS:IP=FFFF0h,jmp check hardware... (precedence set in BIOS, e.g. ZIP,HDD,CDROM,...) (after found)
load MBR to 0000:7C00 -> 1st stage loads 2nd stage -> show GRUB menu -> boot into operating system
(GRUB 1st stage begin) (select a kernel) (initrd, bzimage,init,upstart...)
MBR有512B,preboot区有446B,partition table有64B,最后的两个字节是0xAA55(注意顺序:little-endian)
GRUB就装在那446B里面。
可以从这里下载一个最简单的"os",其实就是一个MBR记录。
它的作用是,启动后显示"Hello world"
No comments:
Post a Comment