簡介
x86的開機流程為BIOS->POST->MBR->Boot sector->OS,先介紹MBR。MBR是硬碟的第一個sector,每個sctor是512 bytes。這 512 bytes由3個部分組成:
1. Boot Partition Loader (Pre-loader or Pre-boot): 共446 bytes,其功能就是將可啟動的作業系統分割區 (boot sector)載入,並將控制權交給其boot sector,多重開機選單就是在這邊做的。
2. partition table: 共64 bytes,4個partition,每個16 bytes,這也限制了一顆硬碟只能有4個partition。每個byte代表的意義見最註1。
3. 結束符號: 共2 bytes,其值為55AA,用來讓BPL驗證是否為MBR。
MBR壞掉,意謂著硬碟沒救了
The sectors
一顆硬碟上的第一個sector是MBR,也就是所謂的stage1,其結構如前所述。接下來有62個sectors,是用來放 stage 1.5,62個的原因見下圖:
BIOS將BPL載入後,PBL先把stage 1.5載入,這樣才可以存取在filesystem上的stage2。stage1.5即存放有關filesystem的識別,只有62個sectors (31K)可用,因此通常只載入某一格式的file system。stage2是grub的核心功能所在,大小有一百多K,因此只能放在固定路徑的file system內,以便stage 1.5找的到。
接著去partition table尋找可開機的分割區 (每個分割區的第1個byte為80),並將其boot sector載入。此時有兩種可能:
1. 直接指向: 此時boot sector為空 (值為0),直接載入kernel/ramdisk (根據menu.lst)。
2. chainloader: 將控制權交給該分割區的boot sector。
開始
知道了這些,就可以開始來玩玩看。
root:/home/latrell/temp# dd if=/dev/sdb of=sdb.mbr bs=512 count=1
1+0 records in
1+0 records out
512 bytes (512 B) copied, 0.000108953 s, 4.7 MB/s
root:/home/latrell/temp# hexdump -C sdb.mbr
可看到partition table如下,表示此usb只有一個partition。
:
:
000001b0 00 02 90 c7 12 00 80 00 00 00 00 00 a8 01 00 01 |................|
000001c0 01 00 06 7b fe f9 3e 00 00 00 92 6b 77 00 00 00 |...{..>....kw...|
000001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
這樣表示用usb可開機,看到MBR字樣。
再來把MBR毀了
root:/home/latrell/temp# dd if=/dev/zero of=/dev/sdb bs=512 count=1
1+0 records in
1+0 records out
512 bytes (512 B) copied, 0.0149138 s, 34.3 kB/s
只剩0了
root:/home/latrell/temp# hexdump -C sdb.mbr
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000200
拿來一開,果然fail。再把他裝回去
root:/home/latrell/temp# install-mbr /dev/sdb --force
就又可以了。記得要在umount的情況下弄,或是弄完要umount,不然不會生效。
Bootloader
MBR是要載入Bootsector,利用syslinux來做一個。syslinux需要FAT,見如下操作:
root:/home/latrell/temp# fdisk /dev/sdb
Command (m for help): p
Disk /dev/sdb: 4009 MB, 4009754624 bytes
124 heads, 62 sectors/track, 1018 cylinders
Units = cylinders of 7688 * 512 = 3936256 bytes
Disk identifier: 0x00000000
Device Boot Start End Blocks Id System
/dev/sdb1 * 1 1018 3913161 6 FAT16
Command (m for help): d
Selected partition 1
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-1018, default 1):
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-1018, default 1018):
Using default value 1018
Command (m for help): t
Selected partition 1
Hex code (type L to list codes): 6
Changed system type of partition 1 to 6 (FAT16)
Command (m for help): a
Partition number (1-4): 1
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table.
The new table will be used at the next reboot.
WARNING: If you have created or modified any DOS 6.x
partitions, please see the fdisk manual page for additional
information.
Syncing disks.
再來格式化:
root:/home/latrell/temp# mkfs.vfat -F 16 /dev/sdb1
mkfs.vfat 2.11 (12 Mar 2005)
安裝syslinux
root:/home/latrell/temp# syslinux -sf /dev/sdb1
這樣就可以開進syslinux,看到boot:
USB install Key
再來,可以來做一支usb install key,拿ubuntu當例子:
root:/home/latrell/temp# mount -oloop ubuntu-9.10-netbook-remix-i386.iso /mnt/iso/
利用rsync將整張光碟幹進去剛剛建好的partition:
root:/home/latrell/temp# rsync -av /mnt/iso/ /media/disk/
之前用cp -af一直失敗,搞了好久弄不出來,一直停在busybox的shell(initramfs),只好call 兔哥 for help。在兔哥的大力贊助下,發現是UUID比對失敗,而這個UUID是存在iso的.disc裡。換言之,是個隱藏檔,cp沒有複製過去。因此使用rsync好像比較保險! 記得不要用/mnt/iso/*,不然隱藏檔會co不過去。
再來還是syslinux版本的問題。如果是3.7版,則是要用syslinux這個名字。前版則是用isolinux。這裡是指ubuntu iso裡的syslinux/isolinux。要改的地方有兩個,一個是folder裡的isolinux.cfg改成syslinux.cfg,再來是把folder name也改成syslinux。不然會看到找不到kernel等錯誤!
接下來,用這個開機,就可以裝ubuntu了。
註1:
----------------------------------------------------------------------------
|位移值|大小 | 說明 |
+------+-------------------------------------------------------------------+
| 00 |Byte | BOOT ID - 若為可開機的分割區則為 80h ~ FFh, 否則為 00h。 |
| | | 80h = C, 81h = D, 82h = E ... 以此類推 |
| | | 以 fdisk 來說,若第一顆硬碟的分割區設為 Active 則 ID = 80h。 |
| | | 4 個分割表中, 只能有一個被設為可開機, 否則將會發生錯誤。 |
+------+-----+-------------------------------------------------------------+
| 01h |Byte | 此分割開始之磁頭編號 |
+------+-----+-------------------------------------------------------------+
| 02h |Byte | 此分割開始之磁區編號 (6 bits) |
| | | 最高的 2 個 bits(bit6-7), 為磁柱編號的 bit8-9 |
+------+-----+-------------------------------------------------------------+
| 03h |Byte | 此分割開始之磁柱編號 (10 bits) |
| | | bit8-9 放在位移值 02h 的 bit 6-7 |
+------+-----+-------------------------------------------------------------+
| 04h |Byte | 作業系統識別碼 |
| | | 00 None |
| | | 01 DOS FAT-12 bits |
| | | 02 XENIX root |
| | | 03 XENIX usr |
| | | 04 DOS FAT-16 bits < 32M |
| | | 05 Extended |
| | | 06 DOS FAT-16 bits > 32M |
| | | 07 HPFS/NTFS |
| | | 08 AIX |
| | | 09 AIX bootable |
| | | 0A OS/2 Boot Manager |
| | | 0B DOS FAT-32 bits (Int 13h extensions) |
| | | 0C DOS FAT Cylinder > 1024 (Int 13h extensions) |
| | | 0E DOS FAT System (Int 13h extensions) |
| | | 0F DOS BigExtended (Int 13h extensions) |
| | | 20 SPF Boot manager |
| | | 40 Venix 80286 |
| | | 41 PPC PReP Boot |
| | | 51 Novell |
| | | 52 Microport |
| | | 63 GNU HURD |
| | | 64 Novell Netware |
| | | 65 Novell Netware |
| | | 75 PC/IX |
| | | 80 Old MINIX |
| | | 81 Linux/MINIX |
| | | 82 Linux swap |
| | | 83 Linux native |
| | | 85 Linux extended |
| | | 93 Amoeba |
| | | 94 Amoeba BBT |
| | | A5 FreeBSD |
| | | A6 Open BSD |
| | | A7 NETSTEP |
| | | A9 NetBSD |
| | | B7 BSDI fs |
| | | B8 BSDI swap |
| | | C7 Syrinx |
| | | DB CP/M |
| | | E1 DOS access |
| | | E3 DOS R/O |
| | | EB BeOS fs |
| | | F2 DOS secondary |
| | | FF BBT |
+------+-----+-------------------------------------------------------------+
| 05h |Byte | 此分割結束之磁頭編號 |
+------+-----+-------------------------------------------------------------+
| 06h |Byte | 此分割結束之磁區編號 (6 bits) |
| | | 最高的 2 個 bits(bit6-7), 為磁柱編號的 bit8-9 |
+------+-----+-------------------------------------------------------------+
| 07h |Byte | 此分割結束之磁柱編號 (10 bits) |
| | | bit8-9 放在位移值 06h 的 bit 6-7 |
+------+-----+-------------------------------------------------------------+
| 08h |DWord| 此分割區前之磁區總數 |
+------+-----+-------------------------------------------------------------+
| 12h |DWord| 此分割之磁區總數 |
+------+-----+-------------------------------------------------------------+
partition table 的entry (一個parititon) 的structure 定義在 COMMON\OAK\INC\bootpart.h
typedef struct _PARTENTRY {
BYTE Part_BootInd; // If 80h means this is boot partition
BYTE Part_FirstHead; // Partition starting head based 0
BYTE Part_FirstSector; // Partition starting sector based 1
BYTE Part_FirstTrack; // Partition starting track based 0
BYTE Part_FileSystem; // Partition type signature field
BYTE Part_LastHead; // Partition ending head based 0
BYTE Part_LastSector; // Partition ending sector based 1
BYTE Part_LastTrack; // Partition ending track based 0
DWORD Part_StartSector; // Logical starting sector based 0
DWORD Part_TotalSectors; // Total logical sectors in partition
} PARTENTRY;
Part_BootInd 的value 也定義在 bootpart.h;
// Flags for Part_BootInd
#define PART_IND_ACTIVE 0x1
#define PART_IND_READ_ONLY 0x2
#define PART_IND_HIDDEN 0x4
其中Filesystem 定義在 COMMON\OAK\INC\bootpart.h
#define PART_UNKNOWN 0
#define PART_DOS2_FAT 0x01 // legit DOS partition
#define PART_DOS3_FAT 0x04 // legit DOS partition
#define PART_EXTENDED 0x05 // legit DOS partition
#define PART_DOS4_FAT 0x06 // legit DOS partition
#define PART_DOS32 0x0B // legit DOS partition (FAT32)
#define PART_DOS32X13 0x0C // Same as 0x0B only "use LBA"
#define PART_DOSX13 0x0E // Same as 0x06 only "use LBA"
#define PART_DOSX13X 0x0F // Same as 0x05 only "use LBA"
// CE only partition types for Part_FileSystem
#define PART_CE_HIDDEN 0x18
#define PART_BOOTSECTION 0x20
#define PART_BINFS 0x21 // BINFS file system
#define PART_XIP 0x22 // XIP ROM Image
#define PART_ROMIMAGE 0x22 // XIP ROM Image (same as PART_XIP)
#define PART_RAMIMAGE 0x23 // XIP RAM Image
#define PART_IMGFS 0x25 // IMGFS file system
#define PART_BINARY 0x26 // Raw Binary Data
Reference
http://www.pczone.com.tw/vbb3/thread/39/50519/
MBR and partition table
留言列表