中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
我的黑群暉 NAS 折騰日記

本文發(fā)自 http://www.binss.me/blog/build-hack-synology/,轉載請注明出處。

折騰硬件

一直以來我都對 NAS 無感。在我看來,機械硬盤這種一通電就嘎嘎嘎響的設備早就應該退出歷史舞臺,在我新組裝的 PC 上,直接上了雙塊 m2 接口的 nvme SSD。猛然想起就快要畢業(yè)了,我?guī)啄陙硇量鄰膶W校 PT 上拖下來各種視頻需要打包帶走才行。我把目光轉到了 NUC 上,這臺小巧的機器上裝著一塊 2TB 的 2.5 寸 SSHD 作為數(shù)據(jù)盤,連上 df 一看,發(fā)現(xiàn)已經住滿了大姐姐。看著實驗室機器中將近 10 TB 的文件,再看看干癟的錢包,此時的我只能說句:機械硬盤真香。轉身就在亞馬遜上海淘了一塊 10T 硬盤。

實際上我購買的是 西數(shù)的 10TB Elements 桌面硬盤,里面是一塊型號為 WD100EMAZ 的氦氣盤,完稅到手 1565,比單獨買硬盤便宜多了。我最開始的想法是 NUC 通過 USB 3.0 連接外置硬盤,將其作為擴展存儲。然而硬盤還沒到手就被土豪同學吐槽了:既然買了 3.5 寸盤,當然上 NAS 啊。你看我的群暉巴拉巴拉多方便。的確,NAS 是更優(yōu)的解決方案。一來硬盤直接通過 SATA 線相連,傳輸速度比 USB 3.0 更快。二來 NAS 能夠控制硬盤智能啟停,更有利于減少硬盤損耗。三來就是老生常談的問題了:低耦合,NUC 掛掉或重啟時,NAS 依然能夠提供服務。嗯,那就上 NAS 吧。

提起 NAS,群暉的大名就如雷貫耳了。然而網上一搜,被群暉的高昂的價格嚇尿了。2000 以下的兩盤位機器甚至不是 Intel 的 CPU,唯一覺得還行的采用 Intel J3455 CPU 的 DS918+,售價高達 4680。要知道 Intel 自家配備 J3455 CPU 的 NUC 才賣 800,群暉何德何能賣那么貴?只能說打擾了。這時在電工論壇上發(fā)現(xiàn)有人在開車:原價 5999 的暴風播酷云,不要 999,也不要 599,只需 590!

為什么會有此等好事?乘著區(qū)塊鏈的東風,國內很多廠商都搞出了各種“礦機”用來挖自己的山寨幣。典型的有迅雷的玩客云、極路由的極路由X、暴風的暴風播酷云等等等等。這些“礦機”的典型特征就是高價低配,但由于虛擬貨幣的火熱,不斷有新韭菜入場,因此“礦機”出現(xiàn)了供不應求的現(xiàn)象,一上架就被哄搶而空。二道販子倒手賺差價,礦老板收機器開 farm,“投資者”哄炒挖出來的山寨幣,一副欣欣向榮的景象。然而,隨著下半年虛擬貨幣市場的遇冷,各大虛擬幣開始暴跌,即使是虛擬貨幣始祖比特幣也享受到 1 年內 80% OFF 的暴跌。于是乎,挖礦的收益趕不上電費,礦老板們開始賣礦機了。

暴風播酷云,正是礦機中的一員。但區(qū)別于其他礦機,其本身具有較高的使用價值。它由知名 NAS 機箱廠商萬由代工,采用了華擎的 J3455-ITX,內有金士頓 8G 內存一條,具有 4 個 SATA 口,除了可抽拉的兩塊 3.5 寸硬盤外,內部還能裝下兩塊 2.5 寸硬盤。這批機器在今年 2 月左右出廠,如今礦老板將硬盤拆出單賣后,就把“外殼”放到咸魚出掉,順豐到付 590。配置比 DS918+ 還高,價格卻還不到群暉的 1/7,要啥自行車,于是我上車了。

到貨后,拆機清灰,清掉 BIOS 密碼,內部塞上兩塊 2.5 寸的 256G SSD,兩個盤位插進 2TB 的老硬盤和剛購入的 10TB 氦氣盤,硬件上就折騰完了。

折騰軟件

為 NAS 裝什么系統(tǒng)呢?最省事當然是上和 NUC 一樣的 Ubuntu 18.04,但 NAS 嘛,就要上 NAS 的系統(tǒng)。于是我折騰了 openmediavault,發(fā)現(xiàn)不怎么好用。正當我準備老老實實裝回 Ubuntu 時,看到網上的黑群暉教程。

黑群暉,顧名思義的就是安裝群暉的系統(tǒng)。群暉的系統(tǒng)鏡像在其官網能夠下載到,雖然它是基于 debian 的 Linux ,然而安裝方式卻不同于常規(guī)。這個系統(tǒng)鏡像是沒有引導的,而是需要在群暉通電后,按照流程通過瀏覽器上傳安裝。而群暉的引導是燒在主板的 ROM 上的。根據(jù) IFIXIT 的拆解,DS918+ 的主板上帶有“Flash memory with pre-loaded DSM 6.1 kernel to allow the NAS to boot before full installation of the OS”,就在下圖綠框的部分:

不愧是專業(yè)的,這塊主板的體積比我的 j3455-itx 小巧得多。顯然這里面存放的就是群暉的引導了。那么對于黑群暉來說,沒有這個 ROM 來引導怎么辦呢?沒關系,我們可以 U 盤引導。這個網上有很多教程,我采用的是 nasyun 論壇上老驥伏櫪的教程。前后折騰了兩天,在此分享整個折騰過程的筆記。

制作啟動盤

這里選用 ds3617xs 的鏡像。在一切開始之前,請確保用于安裝系統(tǒng)的硬盤被清空,最后是通過重建分區(qū)表的形式格掉,并使用 msdos 分區(qū)表

  1. 通過 rescuecd 盤啟動,運行 startx 啟動圖形界面
  2. 運行 gparted,重建分區(qū)表為 msdos,會強制格盤
  3. 創(chuàng)建兩個分區(qū),第一個占大空間,格式為 fat32。第二個大于 32M,格式為 fat16
  4. 上傳 ds3617xs_v612b.img ,可通過新 U 盤傳入也可以將其拷貝到第一個分區(qū)里
  5. 掛載 boot 鏡像 mount ds3617xs_v612b.img /mnt,執(zhí)行安裝腳本 cd /mnt./usb_inst.sh /dev/sdd2,將數(shù)據(jù)寫到 sdd2 分區(qū)
  6. 掛載 /dev/sdd2mount /dev/sdd2 /boot
  7. 查詢 cat /sys/kernel/debug/usb/devices,得到 U 盤的 vid 和 pid
  8. 修改 /boot/boot/grub/grub.cfg 中的 vid 和 pid 為 U 盤的 vid 和 pid
  9. 如果需要安裝更新版本的系統(tǒng),需要用最新版鏡像中的 checksum.syno / grub_cksum.syno / zImage / rd.gz 替換掉 /boot/boot/grub/DS3617xs/ 中相應的文件
  10. umount /boot,拔出 U 盤,啟動 U 盤制作完成

安裝系統(tǒng)

  1. 插入 U 盤,從 U 盤啟動,進入 grub 后選擇第一個啟動黑群暉選項,看到 Booting kernel 代表系統(tǒng)已啟動
  2. 使用群暉助手連接設備或路由器查看設備 ip,然后通過 http://ip:5000 訪問
  3. 按界面上傳系統(tǒng)鏡像(pat后綴),安裝,如果發(fā)現(xiàn)安裝到一半失敗,請:(1) 確保當前機器和黑群暉機器處于同一子網下 (2)將系統(tǒng)盤通過重建分區(qū)表的形式格掉
  4. 安裝完后,黑群暉機器自動重啟,此時記得選擇從 U 盤來引導,看到 Booting kernel 代表系統(tǒng)已啟動
  5. 由于系統(tǒng)需要初始化工作,此時繼續(xù)觀察上傳界面的倒計時。一旦系統(tǒng)就緒,倒計時頁面將跳轉到創(chuàng)建賬號等的初始化界面,完成初始化后,系統(tǒng)安裝完成

硬盤自引導

由于安裝方式的原因,安裝群暉的系統(tǒng)盤上沒有引導,因此每次都要從 U 盤啟動來引導,十分麻煩,為此希望能夠 U 盤自引導。

在制作之前,需要確保之前系統(tǒng)是通過以上方式安裝的,尤其是系統(tǒng)盤在安裝系統(tǒng)前通過重建分區(qū)表的形式格掉并使用 msdos 分區(qū)表,否則可能無法硬盤自引導,出現(xiàn) error file: /boot/grub/i386-pc/normal.mod not found 的問題。

  1. 創(chuàng)建 RAID Group,用系統(tǒng)盤創(chuàng)建一個類型為 BASIC 的 Group,然后在其之上創(chuàng)建一個 Volume,文件系統(tǒng)隨便。Volume 初始化完成后,創(chuàng)建一個 Shared Folder,比如 boot,給予當前用戶讀寫權限。
  2. 在 File Station 中打開該文件夾,上傳 ds3617xs_v612b.img (剛剛做引導盤的那個鏡像)和 disk_setboot.sh 。如果安裝的系統(tǒng)鏡像版本新于引導鏡像,則將最新版引導鏡像中的 checksum.syno / grub_cksum.syno / zImage / rd.gz 也上傳到該目錄
  3. Control Panel - Terminal & SNMP 中開啟 ssh
  4. 使用群暉賬號密碼 ssh 登陸,通過 sudo -i 切換到 root
  5. cd 到剛剛創(chuàng)建的文件夾,一般為 /volume1/boot,確保文件存在的情況下,執(zhí)行:

    chown root:root ds3617xs_v612b.img
    chown root:root disk_setboot.sh
    chmod 666 ds3617xs_v612b.img
    chmod 777 disk_setboot.sh
  6. 找到系統(tǒng)盤設備路徑(如 /dev/sdd),執(zhí)行 ./disk_setboot.sh /dev/sdd ./ds3617xs_v612b.img

  7. 如果腳本執(zhí)行成功,通過 parted --script /dev/sdd p free 檢查系統(tǒng)盤是否新增了一個 flags 為 boot + lba 的分區(qū),假設為 /dev/sdd4
  8. 掛載該設備 mount /dev/sdd4 /mnt
  9. cd 到 /mnt/boot/grub/DS3617xs,用剛上傳的 checksum.syno / grub_cksum.syno / zImage / rd.gz 替換掉該目錄下的相應文件
  10. 完成。拔出引導 U 盤,重啟,選擇從硬盤啟動

思考

看著黑群暉歡快地跑著,我卻高興不起來。為何老驥伏櫪的方法可以引導呢?他是如何實現(xiàn)的?

雖然老驥伏櫪在帖子里給出了一些解釋,但我卻看的一頭霧水。根據(jù)老驥伏櫪帖子中的說法,其實現(xiàn)的引導流程主要是這樣的:硬盤引導 - 硬盤分區(qū)引導 - 群暉系統(tǒng),其中硬盤分區(qū)引導使用 GRUB 。因此,在對 GRUB 引導流程進行復習,總結出 Linux啟動流程:從啟動到 GRUB 后,我開始了對群暉引導流程的分析。

硬盤引導流程

我目前的硬盤已經按照上述流程安裝了群暉的系統(tǒng)并做了硬盤引導。先來研究第一步:硬盤引導。

在 Legacy mode 中,存儲在硬盤第一個扇區(qū)中的 MBR 用于決定在啟動時磁盤中那部分的代碼會被加載運行。其構成如下:

  • 0-445(0x1bd) :Bootstrap Code,又稱 bootloader
  • 446(0x1be)-509(0x1fd) :磁盤分區(qū)表(Disk Partition table),共四項,每個項 16 byte
  • 510(0x1fe)-511(0x1ff) :MBR 結束標志。如果值為 0x55 0xaa,表明該設備可以用于啟動,否則 BIOS 會將控制權轉交給啟動順序中的下一個設備

我們把黑群暉硬盤的 MBR dump 出來看:

sudo dd if=/dev/sda of=mbr bs=512 count=1

dump 出來內容如下:

binss@g1:~/work$ od -x mbr
00000000 fa b8 00 10 8e d0 bc 00 b0 b8 00 00 8e d8 8e c0 |................|
00000010 fb be 00 7c bf 00 06 b9 00 02 f3 a4 ea 21 06 00 |...|.........!..|
00000020 00 be be 07 38 04 75 0b 83 c6 10 81 fe fe 07 75 |....8.u........u|
00000030 f3 eb 16 b4 02 b0 01 bb 00 7c b2 80 8a 74 01 8b |.........|...t..|
00000040 4c 02 cd 13 ea 00 7c 00 00 eb fe 00 00 00 00 00 |L.....|.........|
00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000001b0 00 00 00 00 00 00 00 00 a0 0e 7b 0e 00 00 00 20 |..........{.... |
000001c0 21 00 fd 25 6f 36 00 08 00 00 00 ff 4b 00 00 25 |!..%o6......K..%|
000001d0 70 36 fd 3a bf 3b 00 07 4c 00 00 00 40 00 00 6f |p6.:.;..L...@..o|
000001e0 a5 4b fd fe ff ff 00 00 90 00 60 39 89 1c 80 3f |.K........`9...?|
000001f0 85 3b 0e 53 95 3f 00 08 8c 00 01 00 01 00 55 aa |.;.S.?........U.|
00000200

因此分區(qū)表內容為:

00 20 21 00 fd 25 6f 36 00 08 00 00 00 ff 4b 00
00 25 70 36 fd 3a bf 3b 00 07 4c 00 00 00 40 00
00 6f a5 4b fd fe ff ff 00 00 90 00 60 39 89 1c
80 3f 85 3b 0e 53 95 3f 00 08 8c 00 01 00 01 00

分區(qū)表項定義如下:

  • 0 :flag,如果為0x80,就表示該分區(qū)是活動分區(qū)(一塊硬盤上只可以有一個活動分區(qū)),可引導
  • 1 :分區(qū)起始磁頭號(HEAD)
  • 2-3 :分區(qū)起始扇區(qū)號(SECTOR, bit 0-5) 和 起始柱面號(CYLINDER, 6-15)
  • 4 :分區(qū)文件系統(tǒng)。0b 為 FAT32 with CHS,0e 為 FAT16B with LBA,07 為 NTFS,fd 為 LINUX RAID
  • 5 :分區(qū)結束磁頭號(HEAD)
  • 6-7 :分區(qū)結束扇區(qū)號(SECTOR, bit 0-5) 和 結束柱面號(CYLINDER, 6-15)
  • 8-11 :分區(qū)起始相對扇區(qū)號
  • 12-15 :分區(qū)總的扇區(qū)數(shù)

CHS(Cylinder-Head-Sector) 和 LBA(Logical Block Addressing) 是扇區(qū)的編址方式。前者直接使用 (c,h,s) 來表示一個扇區(qū)的位置。扇區(qū)號(s)從1開始,柱面號(c)和磁頭(h)從 0 開始,因此CHS編址的起始地址為 (0, 0, 1),只能尋址約 8 GB (255, 1024, 64) = 255 * 1024 * 64 sector。后者的 (c, h, s) 表示的位置為 (c * 硬盤中的磁頭數(shù)目 + h) * 每條磁道上可以劃分的最大的扇區(qū)數(shù) + (s - 1),其中扇區(qū)號從 0 開始。

因此對于上述分區(qū)表,最后一項說明了它是活動分區(qū),文件系統(tǒng)為 FAT16B with LBA,大小約為 32 MB(0x10001(65537) sectors)

在 parted 中解析為:

Number Start End Size Type File system Flags
1 1049kB 2551MB 2550MB primary raid
2 2551MB 4699MB 2147MB primary raid
4 4699MB 4732MB 33.6MB primary boot, lba
3 4832MB 250GB 245GB primary raid

當 BIOS 發(fā)現(xiàn)該磁盤的第一個扇區(qū)以 55 aa 結束,確定它是一個 MBR,于是會執(zhí)行存放在 byte 0-455 的 bootloader 。

bootloader

硬盤第一個扇區(qū) MBR 中的 bootloader 好像并非是 GRUB stage 1 的代碼。經過實驗,發(fā)現(xiàn)是 gparted 在初始化磁盤時所創(chuàng)建。

把它們粘到 ODA 中,架構選 16位(i8086),得到匯編如下:

.data:00000000 fa cli
.data:00000001 b8 00 10 mov $0x1000,%ax
.data:00000004 8e d0 mov %ax,%ss
.data:00000006 bc 00 b0 mov $0xb000,%sp
.data:00000009 b8 00 00 mov $0x0,%ax
.data:0000000c 8e d8 mov %ax,%ds
.data:0000000e 8e c0 mov %ax,%es
.data:00000010 fb sti
.data:00000011 be 00 7c mov $0x7c00,%si
.data:00000014 bf 00 06 mov $0x600,%di
.data:00000017 b9 00 02 mov $0x200,%cx
.data:0000001a f3 a4 rep movsb %ds:(%si),%es:(%di)
.data:0000001c ea 21 06 00 00 ljmp $0x0,$0x621
.data:00000021 be be 07 mov $0x7be,%si
.data:00000024 38 04 cmp %al,(%si)
.data:00000026 75 0b jne 0x00000033
.data:00000028 83 c6 10 add $0x10,%si
.data:0000002b 81 fe fe 07 cmp $0x7fe,%si
.data:0000002f 75 f3 jne 0x00000024
.data:00000031 eb 16 jmp 0x00000049
.data:00000033 b4 02 mov $0x2,%ah
.data:00000035 b0 01 mov $0x1,%al
.data:00000037 bb 00 7c mov $0x7c00,%bx
.data:0000003a b2 80 mov $0x80,%dl
.data:0000003c 8a 74 01 mov 0x1(%si),%dh
.data:0000003f 8b 4c 02 mov 0x2(%si),%cx
.data:00000042 cd 13 int $0x13
.data:00000044 ea 00 7c 00 00 ljmp $0x0,$0x7c00
.data:00000049 eb fe jmp 0x00000049
.data:0000004b 00 00 add %al,(%bx,%si)
.data:0000004d 00 00 add %al,(%bx,%si)
.data:0000004f 00 .byte 0x0

這里在關中斷環(huán)境下設置 ss = 0x1000,sp = 0xb000,ax = ds = es = 0x0。隨后通過循環(huán)將位于 0x0:0x7c00 的 512 byte 代碼(也就是當前正在執(zhí)行的 MBR 區(qū)域代碼)拷貝到 0x0:0x600,然后跳轉過去執(zhí)行后續(xù)代碼。檢查 0x7be (MBR 的 1be,位于 MBR 分區(qū)表的第一項)地址是否為 0,如果不為 0,表示第一分區(qū)是活動分區(qū),跳轉到后續(xù)代碼執(zhí)行。否則將地址加 16 后比較下一個表項。如果比較完 4 個表象都沒找到目標,則執(zhí)行 jmp 0x00000049 自己跳轉自己無限 busy loop。假設找到了活動分區(qū),看后續(xù)代碼:

.data:00000033 b4 02 mov $0x2,%ah
.data:00000035 b0 01 mov $0x1,%al
.data:00000037 bb 00 7c mov $0x7c00,%bx
.data:0000003a b2 80 mov $0x80,%dl
.data:0000003c 8a 74 01 mov 0x1(%si),%dh
.data:0000003f 8b 4c 02 mov 0x2(%si),%cx
.data:00000042 cd 13 int $0x13
.data:00000044 ea 00 7c 00 00 ljmp $0x0,$0x7c00

這里發(fā)送了 0x13 號中斷,ah = 2 為 Read Sectors From Drive,al = 1 指定要讀的扇區(qū)數(shù)為 1,Drive 為 0x80,讀取位置 (c,h,s) 為活動分區(qū)表項中指定的那些,將其讀取到 0x0:0x7c00。隨后跳轉過去執(zhí)行代碼。

根據(jù)文檔,磁盤分區(qū)中起引導作用的第一個扇區(qū)稱為 VBR(Volume Boot Record)。因此這段 MBR bootloader 代碼的本質目的是找到活動分區(qū),然后執(zhí)行它的 VBR。

研究老驥伏櫪提供的 disk_setboot.sh 腳本,發(fā)現(xiàn)其中有一行:

/mnt/grub-install --force-lba --root-directory=/mnt $1$(echo 4)

發(fā)現(xiàn)是把 grub 裝到第四個分區(qū)(在我這里為 /dev/sdd4 )去了。因此接下來執(zhí)行的是 /dev/sdd4 第一個扇區(qū)的代碼。

硬盤分區(qū)引導階段

我們把 /dev/sdd4 的第一個扇區(qū) dump 出來看看:

00000000 eb 48 90 6d 6b 66 73 2e 66 61 74 00 02 04 01 00 |.H.mkfs.fat.....|
00000010 02 00 02 00 00 f8 40 00 3f 00 ff 00 00 30 02 00 |......@.?....0..|
00000020 00 00 01 00 80 01 29 0c fe a6 53 20 20 20 20 20 |......)...S |
00000030 20 20 20 20 20 20 46 41 54 31 36 20 20 20 03 02 | FAT16 ..|
00000040 ff 01 00 80 4d 86 8c 00 00 08 fa 90 90 f6 c2 80 |....M...........|
00000050 75 02 b2 80 ea 59 7c 00 00 31 c0 8e d8 8e d0 bc |u....Y|..1......|
00000060 00 20 fb a0 40 7c 3c ff 74 02 88 c2 52 be 7f 7d |. ..@|<.t...R..}|
00000070 e8 34 01 f6 c2 80 74 54 b4 41 bb aa 55 cd 13 5a |.4....tT.A..U..Z|
00000080 52 72 49 81 fb 55 aa 75 43 a0 41 7c 84 c0 75 05 |RrI..U.uC.A|..u.|
00000090 83 e1 01 74 37 66 8b 4c 10 be 05 7c c6 44 ff 01 |...t7f.L...|.D..|
000000a0 66 8b 1e 44 7c c7 04 10 00 c7 44 02 01 00 66 89 |f..D|.....D...f.|
000000b0 5c 08 c7 44 06 00 70 66 31 c0 89 44 04 66 89 44 |\..D..pf1..D.f.D|
000000c0 0c b4 42 cd 13 72 05 bb 00 70 eb 7d b4 08 cd 13 |..B..r...p.}....|
000000d0 73 0a f6 c2 80 0f 84 ea 00 e9 8d 00 be 05 7c c6 |s.............|.|
000000e0 44 ff 00 66 31 c0 88 f0 40 66 89 44 04 31 d2 88 |D..f1...@f.D.1..|
000000f0 ca c1 e2 02 88 e8 88 f4 40 89 44 08 31 c0 88 d0 |........@.D.1...|
00000100 c0 e8 02 66 89 04 66 a1 44 7c 66 31 d2 66 f7 34 |...f..f.D|f1.f.4|
00000110 88 54 0a 66 31 d2 66 f7 74 04 88 54 0b 89 44 0c |.T.f1.f.t..T..D.|
00000120 3b 44 08 7d 3c 8a 54 0d c0 e2 06 8a 4c 0a fe c1 |;D.}<.T.....L...|
00000130 08 d1 8a 6c 0c 5a 8a 74 0b bb 00 70 8e c3 31 db |...l.Z.t...p..1.|
00000140 b8 01 02 cd 13 72 2a 8c c3 8e 06 48 7c 60 1e b9 |.....r*....H|`..|
00000150 00 01 8e db 31 f6 31 ff fc f3 a5 1f 61 ff 26 42 |....1.1.....a.&B|
00000160 7c be 85 7d e8 40 00 eb 0e be 8a 7d e8 38 00 eb ||..}.@.....}.8..|
00000170 06 be 94 7d e8 30 00 be 99 7d e8 2a 00 eb fe 47 |...}.0...}.*...G|
00000180 52 55 42 20 00 47 65 6f 6d 00 48 61 72 64 20 44 |RUB .Geom.Hard D|
00000190 69 73 6b 00 52 65 61 64 00 20 45 72 72 6f 72 00 |isk.Read. Error.|
000001a0 bb 01 00 b4 0e cd 10 ac 3c 00 75 f4 c3 00 00 00 |........<.u.....|
000001b0 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.|

這段代碼就是為我們熟悉的 GRUB 2 boot.img 了,把 GRUB 2 clone 下來,對應代碼位于 grub-core/boot/i386/pc/boot.S

這里的邏輯和上述的 bootloader 很像,只是容錯性更強,考慮了很多 BIOS 有 bug 的情況并進行相應處理。它將 diskboot.img 拷貝到 0x0:GRUB_BOOT_MACHINE_KERNEL_ADDR 并跳轉。后續(xù)流程就很常規(guī)了,和 Linux啟動流程:從啟動到 GRUB 分析的一樣, grub.cfg 中的腳本會被解析執(zhí)行。

該腳本加載了各種文件系統(tǒng)的驅動,設置了成噸的環(huán)境變量。隨后用戶將選擇菜單第一項啟動:

menuentry '啟動DS3617xs黑群暉 6.1,2版' --unrestricted {
set img=$prefix/DS3617xs
savedefault
loadlinux 3617 usb
loadinitrd
}

其主要調用的幾個函數(shù)也同樣在 grub.cfg 中:

function loadlinux {
set model=$1
set bootdev=$2
shift 2
if [ -n $vid -a -n $pid ]; then
set usb_args='vid=$vid pid=$pid'
fi
eval 'set common_args=\'\$common_args_$model\''
eval 'set extra_args=\'\$extra_args_$model\''
eval 'set bootdev_args=\'\${bootdev}_args\''
common_add_option_ex rootdev root
common_add_option sn
if common_add_option mac1; then set netif_num=1; fi
if common_add_option mac2; then set netif_num=2; fi
if common_add_option mac3; then set netif_num=3; fi
if common_add_option mac4; then set netif_num=4; fi
common_add_option netif_num
if [ -z $zImage ]; then
set zImage=zImage
fi
linux $img/$zImage $common_args $bootdev_args $extra_args $@
}
function loadinitrd {
if [ -s $img/$info ]; then
cat $img/$info
fi
showtips
if [ -s $img/$extra_initrd ]; then
initrd $img/rd.gz $img/$extra_initrd
else
initrd $img/rd.gz
fi
}

loadlinux 執(zhí)行的是 linux command。其參數(shù)展開后如下:

linux /boot/grub/DS3617xs/zImage root=/dev/md0 sn=A8ODN01234 mac1=0011322CA785 netif_num=1 vid=0x1234 pid=0x1234

因此群暉的 kernel 位于 /boot/grub/DS3617xs/zImage,而 /dev/md0 將被掛載為根目錄。相比 Ubuntu 引導項的 linux command,多了 sn=A8ODN01234 mac1=0011322CA785 netif_num=1 vid=1234 pid=1234 這一串參數(shù),估計是群暉的 kernel 在啟動時需要對這些參數(shù)進行校驗,猜測如果校驗失敗,那么就無法啟動。

loadinitrd 執(zhí)行的是 initrd command,GRUB 會將其傳入的 initrd 文件讀入到內存中,并將地址和大小填到 linux_kernel_params,這樣 kernel 啟動后,就知道去哪里加載 initrd 了。相比 Ubuntu 的 initrd 只有一個 initrd.img-XXX 文件,群暉有兩個,分別為 /boot/grub/DS3617xs/rd.gz 和 /boot/grub/DS3617xs/extra.lzma 。將兩者解壓,得到目錄結構。

rd.gz 是典型的 initrd :

$ tree rd -L 2
rd
├── bin -> usr/bin
├── dev
│   └── net
├── etc
│   ├── AHAtasks
│   ├── VERSION
│   ├── avahi
│   ├── crontab
│   ├── dhclient
│   ├── dhcpc
│   ├── extensionPorts
│   ├── fstab
│   ├── ftpusers
│   ├── group
│   ├── group_desc
│   ├── host.conf
│   ├── hosts
│   ├── hosts.allow
│   ├── hosts.deny
│   ├── inetd.conf
│   ├── mke2fs.conf
│   ├── modules.conf
│   ├── mtab
│   ├── nsswitch.conf
│   ├── passwd
│   ├── profile
│   ├── protocols
│   ├── rc
│   ├── rc.fan
│   ├── rc.network
│   ├── rc.network_dualhead
│   ├── rc.network_routing
│   ├── rc.sas
│   ├── rc.scanusbdev
│   ├── rc.subr
│   ├── rc.volume
│   ├── rc.wifi
│   ├── resolv.conf
│   ├── securetty
│   ├── services
│   ├── shadow
│   ├── shells
│   ├── ssl
│   ├── synogrinst.sh
│   ├── synoinfo.conf
│   ├── synouser.conf
│   ├── sysconfig
│   ├── sysctl.conf
│   └── termcap
├── etc.defaults -> etc
├── init -> bin/busybox
├── lib -> usr/lib
├── lib32 -> usr/lib32
├── lib64 -> usr/lib
├── linuxrc -> bin/busybox
├── linuxrc.syno
├── mnt
├── proc
├── root
├── run
│   └── lock
├── sbin -> usr/sbin
├── sys
├── tmp
├── usr
│   ├── bin
│   ├── lib
│   ├── lib32
│   ├── lib64 -> lib
│   ├── local
│   ├── sbin
│   ├── share
│   └── syno
├── var
│   ├── cache
│   ├── crash
│   ├── lib
│   ├── lock -> ../run/lock
│   ├── log
│   ├── packages
│   ├── run -> ../run
│   ├── services
│   ├── spool
│   └── tmp
└── volume1

extra.lzma 是對 initrd 中內核模塊的補充,支持了更多類型的設備:

$ tree extra -L 4
extra
├── etc
│   ├── jun.patch
│   └── rc.modules
├── extra.lzma
├── init
└── usr
├── bin
│   └── patch
├── lib
│   ├── firmware
│   │   ├── bnx2
│   │   └── tigon
│   └── modules
│   ├── BusLogic.ko
│   ├── alx.ko
│   ├── ata_piix.ko
│   ├── atl1.ko
│   ├── atl1c.ko
│   ├── atl1e.ko
│   ├── ax88179_178a.ko
│   ├── bnx2.ko
│   ├── bnx2x.ko
│   ├── button.ko
│   ├── cnic.ko
│   ├── e1000.ko
│   ├── ehci-hcd.ko
│   ├── ehci-pci.ko
│   ├── ipg.ko
│   ├── jme.ko
│   ├── libcrc32c.ko
│   ├── libphy.ko
│   ├── mdio.ko
│   ├── megaraid.ko
│   ├── megaraid_mbox.ko
│   ├── megaraid_mm.ko
│   ├── megaraid_sas.ko
│   ├── mii.ko
│   ├── mptbase.ko
│   ├── mptctl.ko
│   ├── mptsas.ko
│   ├── mptscsih.ko
│   ├── mptspi.ko
│   ├── netxen_nic.ko
│   ├── ohci-hcd.ko
│   ├── pch_gbe.ko
│   ├── pcnet32.ko
│   ├── ptp_pch.ko
│   ├── qla3xxx.ko
│   ├── qlcnic.ko
│   ├── qlge.ko
│   ├── r8168.ko
│   ├── r8169.ko
│   ├── scsi_transport_spi.ko
│   ├── sfc.ko
│   ├── skge.ko
│   ├── sky2.ko
│   ├── tg3.ko
│   ├── uio.ko
│   ├── usbnet.ko
│   ├── vmw_pvscsi.ko
│   └── vmxnet3.ko
└── sbin
└── modprobe

這其中我只認識 e1000,它是虛擬化中最常見的網卡。

至此我們完成了老驥伏櫪版群暉引導的分析。

總結

老驥伏櫪的硬盤引導法,本質上為三級加載:MBR => VBR => 群暉的 Linux kernel 。在這次分析過程中,我被 MBR 中的奇怪 bootloader 所惑,百思不得其解為什么能夠引導活動分區(qū),最后還是網上找了個反匯編工具才明白其原理。當然,這樣做的目的老驥伏櫪也說了:

我們做黑群暉硬盤自啟動時,最不希望影響硬盤主引導分區(qū),而希望所有的改裝都放在硬盤子分區(qū)中。

有點道理,但這樣做容易有坑:如果用戶一開始沒有使用 gparted 來重建分區(qū)表,那么 MBR 中 bootloader 的邏輯可能就不是這樣的,甚至可能由于該盤之前裝了 Linux 導致 bootloader 被寫入為 GRUB 的 boot.img 。但如果將 VBR 中的 boot.img 寫入到 MBR 中,那么根據(jù) boot.img 的實現(xiàn),其會加載位于后面的 core.img,因此前 63 個扇區(qū)我們都要改,理論上可以實現(xiàn) MBR => 群暉的 Linux kernel 的加載。如果之后有時間,會嘗試這樣折騰下。

無論如何,非常感謝老驥伏櫪提供的引導,不僅讓我成功實現(xiàn)硬盤引導群暉,更重要的是讓我把引導相關的知識復習了一遍,非常有意思。

后記

自從 18 年 12 月裝機完成后,至今已經平穩(wěn)運行了兩個多月。在我將其搬回家后,更是作為了家中的存儲中樞。家中電視能夠方便地通過 dlna 訪問其中照片和視頻,用過的都說好。

唯一的缺點就是機械硬盤太吵了,放房間里夜深人靜的時候嘎嘎嘎響,于是把它搬到客廳了。

參考

http://www.nasyun.com/thread-28601-1-2.html

https://thestarman.pcministry.com/asm/mbr/GRUB.htm

https://en.wikipedia.org/wiki/GNU_GRUB

https://wiki.osdev.org/MBR_(x86)

https://en.wikipedia.org/wiki/INT_13H#INT_13h_AH=02h:_Read_Sectors_From_Drive

本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
【新提醒】本論壇首發(fā)【老驥伏櫪
Grub4DOS引導img文件打造啟動U盤
在windows多系統(tǒng)中安裝grub2
用CloneZilla制作緊急恢復分區(qū)
有什么簡單的辦法可以制作一個多重引導的啟動盤?
[轉]硬盤的那些事(主分區(qū)、擴展分區(qū)、邏輯分區(qū)、活動分區(qū)、系統(tǒng)分區(qū)、啟動分區(qū)、引導扇區(qū)、MBR等)
更多類似文章 >>
生活服務
熱點新聞
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服