本文發(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ū)表
mount ds3617xs_v612b.img /mnt
,執(zhí)行安裝腳本 cd /mnt
后 ./usb_inst.sh /dev/sdd2
,將數(shù)據(jù)寫到 sdd2 分區(qū)/dev/sdd2
:mount /dev/sdd2 /boot
cat /sys/kernel/debug/usb/devices
,得到 U 盤的 vid 和 pid/boot/boot/grub/grub.cfg
中的 vid 和 pid 為 U 盤的 vid 和 pid/boot/boot/grub/DS3617xs/
中相應的文件umount /boot
,拔出 U 盤,啟動 U 盤制作完成由于安裝方式的原因,安裝群暉的系統(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
的問題。
sudo -i
切換到 rootcd 到剛剛創(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 |
找到系統(tǒng)盤設備路徑(如 /dev/sdd
),執(zhí)行 ./disk_setboot.sh /dev/sdd ./ds3617xs_v612b.img
parted --script /dev/sdd p free
檢查系統(tǒng)盤是否新增了一個 flags 為 boot + lba 的分區(qū),假設為 /dev/sdd4
mount /dev/sdd4 /mnt
/mnt/boot/grub/DS3617xs
,用剛上傳的 checksum.syno / grub_cksum.syno / zImage / rd.gz 替換掉該目錄下的相應文件看著黑群暉歡快地跑著,我卻高興不起來。為何老驥伏櫪的方法可以引導呢?他是如何實現(xiàn)的?
雖然老驥伏櫪在帖子里給出了一些解釋,但我卻看的一頭霧水。根據(jù)老驥伏櫪帖子中的說法,其實現(xiàn)的引導流程主要是這樣的:硬盤引導 - 硬盤分區(qū)引導 - 群暉系統(tǒng),其中硬盤分區(qū)引導使用 GRUB 。因此,在對 GRUB 引導流程進行復習,總結出 Linux啟動流程:從啟動到 GRUB 后,我開始了對群暉引導流程的分析。
我目前的硬盤已經按照上述流程安裝了群暉的系統(tǒng)并做了硬盤引導。先來研究第一步:硬盤引導。
在 Legacy mode 中,存儲在硬盤第一個扇區(qū)中的 MBR 用于決定在啟動時磁盤中那部分的代碼會被加載運行。其構成如下:
我們把黑群暉硬盤的 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ū)表項定義如下:
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 。
硬盤第一個扇區(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ū)的代碼。
我們把 /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
聯(lián)系客服