使用bochs和grub建立可引導硬盤鏡像

bochs,發音同box,是我非常喜歡的虛擬機,靈活易用方便配置,功能極強,用來調試Linux內核是非常合適的。這篇博文主要講解如何建立硬盤鏡像,並且將grub安裝上去,最後的結果就是bochs啓動後能進入到grub引導界面。下一篇博客再講解如何在鏡像上安裝Linux內核。


硬盤基礎知識

硬盤的專業術語中有:柱面,磁頭,扇區,每磁道扇區數這幾個概念。

  1. 每個盤片有兩個磁頭,分別位於兩面上,從0開始依次編號,英語中稱爲Heads,漢語中一般翻譯爲0面、1面......一般來說硬盤有16個盤面(磁頭)

  2. 每個面都有很多同心圓軌道稱爲磁道,從外向內依此編號爲0道、1道......,英語中稱爲Tracks

  3. 所有盤面上半徑相同的磁道正好組成一個圓柱面,稱爲柱面,和磁道編號相同,英語中稱爲Cylinders

  4. 每個磁道上劃分出很多扇形區域,稱爲扇區,每個磁道上的扇區都從1開始編號,每個扇區512字節,英語中稱爲Sectors。一個磁道一般有63個扇區。

  5. 磁盤定位使用CHS,即柱面、磁頭、扇區,或稱爲磁道、盤面、扇區。通常所說的0面0道1扇區指的就是第0面(第0號磁頭)、第0磁道(柱面)、第1扇區。

  6. 一個需要注意的地方:每磁道扇區編號從1開始,全硬盤絕對扇區編號從0開始。

  7. 整塊硬盤可以分爲很多分區,每個分區可以格式化爲不同的文件系統。每個分區的第1扇區(相對該分區開始來講),叫做引導扇區(Boot Sector)。在全硬盤的第0扇區,也有一塊引導扇區,爲了以示區別,將之稱爲主引導扇區(Master Boot Sector,MBR)。MBR裏面前446字節是引導程序,後面緊跟64字節的分區表,再加上2字節的引導標誌正好是512字節。每個分區的分區表表項爲16字節,整個分區表可以記錄四個分區的信息,所以一塊硬盤只能有4個主分區。引導扇區一共5個(4個分區的+1個MBR)

  8. 每個柱面的扇區數爲:63x16,又因爲每個扇區512字節,所以一個柱面共計63x16x512=516096B

製作空白硬盤鏡像

我們製作一個50M左右的鏡像,16個磁頭,每磁道扇區數63,即一個柱面516096個字節,大約需要100個柱面。

dd if=/dev/zero of=hd.img bs=516096c count=100

if是輸入,of是輸出,516096c後面的字母c表示單位是1,即516096個字節,寫入100次,每次516096個字節。 空白鏡像製作完畢。

初始化磁盤並分區

fdisk -u -C100 -S63 -H16 hd.img

指定好柱面數、每磁道扇區數、磁頭數。 這個命令的操作如下:

Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel with disk identifier 0x49b37849.
Changes will remain in memory only, until you decide to write them.

After that, of course, the previous content won't be recoverable.
Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)

WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
     switch off the mode (command 'c').

Command (m for help): c #關閉DOS Compatibility flag,不關閉也沒事
DOS Compatibility flag is not set

Command (m for help): n #新建分區
Command action
e   extended
p   primary partition (1-4)
p   #類型爲主分區
Partition number (1-4): 1   #該分區是第一個分區,實際上我們就建立這一個分區
First sector (1-100799, default 1): 63  #該分區從硬盤絕對第63扇區開始,留下前面的0-62扇區給grub等引導程序,這是DOS時代留下來的約定。
Last sector, +sectors or +size{K,M,G} (63-100799, default 100799): #直接回車,讓該分區直至硬盤最後的扇區結束
Using default value 100799

Command (m for help): w #寫入分區數據並退出
The partition table has been altered!

Syncing disks.

掛載硬盤鏡像

losetup -o 32256 /dev/loop0 hd.img

-o 32256是跳過63x512=32256個字節再掛載,還記得第一分區是從硬盤鏡像絕對第63扇區開始的吧,這一步就是跳過0-62分區,即跳過32256個字節,直接把第一分區掛載到loop0上。 這一步之所以不用mount是因爲mount是用來掛載文件系統的,現在硬盤鏡像第一分區裏還沒有文件系統。losetup命令用來將硬盤分區掛載到loop0設備上。

格式化文件系統

mkfs.ext3 /dev/loop0

將掛到loop0上的分區格式化爲ext3文件系統

掛載文件系統

現在文件系統已經建立,是時候將之掛載了

mount -t ext3 /dev/loop0 /mnt

這命令我就不解釋了,很簡單。

建立boot和grub目錄

mkdir -p /mnt/boot/grub

將當前系統上的grub程序文件複製進去,

cp /boot/grub/stage1 /boot/grub/stage2 /boot/grub/e2fs_stage1_5 /mnt/boot/grub/

這一步你也可以自己下載grub源碼編譯,編譯完後也會出現stage1、stage2、e2fsstage15這幾個文件,這是grub的核心程序,stage1待會兒會被放到MBR裏,開機時BIOS會把MBR裏的stage1取到內存裏執行,之後stage1會取出stage2文件執行,然後是e2fsstage15。

我們這裏不自己編譯了,直接使用宿主系統CentOS 6.4的文件。

創建grub.conf文件

cp /boot/grub/grub.conf /mnt/boot/grub/

配置文件依然借用宿主系統CentOS 6.4的。

ln -s /mnt/boot/grub/grub.conf /mnt/boot/grub/menu.lst

這個軟鏈接如果不建立,待會兒開機進入grub時不會出現啓動項選擇界面

卸載文件系統

umount /mnt/

卸載硬盤分區

losetup -d /dev/loop0

最終安裝grub

grub --device-map=/dev/null

運行後依次輸入下面的內容敲回車。

grub> device (hd0) hd.img
grub> geometry (hd0) 100 16 63  #柱面數、磁頭數、每磁道扇區數
grub> root (hd0,0)
grub> setup (hd0)
grub> quit

啓動bochs

在bochs裏設置好,然後啓動就行了 應該會看到如下提示:

ata0 master: Generic 1234 ATA-6 Hard-Disk (  49 MBytes)

Press F12 for boot menu.

Booting from Hard Disk...
failed to read p_w_picpath
Press any key to enter the menu


Booting CentOS (2.6.32-358.el6.i686) in 0 seconds...
Error 15: File not found

Press any key to continue...

這界面很正常,畢竟我們只裝了grub,操作系統根本不存在,它能找到文件就怪了。按下任意鍵,就能看到grub啓動項選擇界面了。因爲我們的grub程序文件和配置文件全部來自於宿主系統,所以這裏看到的啓動項也和宿主系統一樣是CentOS 6.4,只不過這個啓動項所指定的內核文件不存在而已。

這篇博文就寫到這裏,下一篇我們將內核鏡像寫入硬盤鏡像,這樣就能啓動內核了,不過要想真正運行Linux系統還是很麻煩的,因爲後面還要向硬盤鏡像內寫入文件系統裏面的主要文件,比如/bin/sh之類的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章