免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

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

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

折騰硬件

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

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

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

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

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

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

折騰軟件

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

黑群暉,顧名思義的就是安裝群暉的系統(tǒng)。群暉的系統(tǒng)鏡像在其官網(wǎng)能夠下載到,雖然它是基于 debian 的 Linux ,然而安裝方式卻不同于常規(guī)。這個(gè)系統(tǒng)鏡像是沒有引導(dǎo)的,而是需要在群暉通電后,按照流程通過瀏覽器上傳安裝。而群暉的引導(dǎo)是燒在主板的 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 小巧得多。顯然這里面存放的就是群暉的引導(dǎo)了。那么對(duì)于黑群暉來說,沒有這個(gè) ROM 來引導(dǎo)怎么辦呢?沒關(guān)系,我們可以 U 盤引導(dǎo)。這個(gè)網(wǎng)上有很多教程,我采用的是 nasyun 論壇上老驥伏櫪的教程。前后折騰了兩天,在此分享整個(gè)折騰過程的筆記。

制作啟動(dòng)盤

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

  1. 通過 rescuecd 盤啟動(dòng),運(yùn)行 startx 啟動(dòng)圖形界面
  2. 運(yùn)行 gparted,重建分區(qū)表為 msdos,會(huì)強(qiáng)制格盤
  3. 創(chuàng)建兩個(gè)分區(qū),第一個(gè)占大空間,格式為 fat32。第二個(gè)大于 32M,格式為 fat16
  4. 上傳 ds3617xs_v612b.img ,可通過新 U 盤傳入也可以將其拷貝到第一個(gè)分區(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/ 中相應(yīng)的文件
  10. umount /boot,拔出 U 盤,啟動(dòng) U 盤制作完成

安裝系統(tǒng)

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

硬盤自引導(dǎo)

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

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

  1. 創(chuàng)建 RAID Group,用系統(tǒng)盤創(chuàng)建一個(gè)類型為 BASIC 的 Group,然后在其之上創(chuàng)建一個(gè) Volume,文件系統(tǒng)隨便。Volume 初始化完成后,創(chuàng)建一個(gè) Shared Folder,比如 boot,給予當(dāng)前用戶讀寫權(quán)限。
  2. 在 File Station 中打開該文件夾,上傳 ds3617xs_v612b.img (剛剛做引導(dǎo)盤的那個(gè)鏡像)和 disk_setboot.sh 。如果安裝的系統(tǒng)鏡像版本新于引導(dǎo)鏡像,則將最新版引導(dǎo)鏡像中的 checksum.syno / grub_cksum.syno / zImage / rd.gz 也上傳到該目錄
  3. Control Panel - Terminal & SNMP 中開啟 ssh
  4. 使用群暉賬號(hào)密碼 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)盤設(shè)備路徑(如 /dev/sdd),執(zhí)行 ./disk_setboot.sh /dev/sdd ./ds3617xs_v612b.img

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

思考

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

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

硬盤引導(dǎo)流程

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

在 Legacy mode 中,存儲(chǔ)在硬盤第一個(gè)扇區(qū)中的 MBR 用于決定在啟動(dòng)時(shí)磁盤中那部分的代碼會(huì)被加載運(yùn)行。其構(gòu)成如下:

  • 0-445(0x1bd) :Bootstrap Code,又稱 bootloader
  • 446(0x1be)-509(0x1fd) :磁盤分區(qū)表(Disk Partition table),共四項(xiàng),每個(gè)項(xiàng) 16 byte
  • 510(0x1fe)-511(0x1ff) :MBR 結(jié)束標(biāo)志。如果值為 0x55 0xaa,表明該設(shè)備可以用于啟動(dòng),否則 BIOS 會(huì)將控制權(quán)轉(zhuǎn)交給啟動(dòng)順序中的下一個(gè)設(shè)備

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

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

dump 出來內(nèi)容如下:

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ū)表內(nèi)容為:

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ū)表項(xiàng)定義如下:

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

CHS(Cylinder-Head-Sector) 和 LBA(Logical Block Addressing) 是扇區(qū)的編址方式。前者直接使用 (c,h,s) 來表示一個(gè)扇區(qū)的位置。扇區(qū)號(hào)(s)從1開始,柱面號(hào)(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ū)號(hào)從 0 開始。

因此對(duì)于上述分區(qū)表,最后一項(xiàng)說明了它是活動(dòng)分區(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

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

bootloader

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

把它們粘到 ODA 中,架構(gòu)選 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

這里在關(guān)中斷環(huán)境下設(shè)置 ss = 0x1000,sp = 0xb000,ax = ds = es = 0x0。隨后通過循環(huán)將位于 0x0:0x7c00 的 512 byte 代碼(也就是當(dāng)前正在執(zhí)行的 MBR 區(qū)域代碼)拷貝到 0x0:0x600,然后跳轉(zhuǎn)過去執(zhí)行后續(xù)代碼。檢查 0x7be (MBR 的 1be,位于 MBR 分區(qū)表的第一項(xiàng))地址是否為 0,如果不為 0,表示第一分區(qū)是活動(dòng)分區(qū),跳轉(zhuǎn)到后續(xù)代碼執(zhí)行。否則將地址加 16 后比較下一個(gè)表項(xiàng)。如果比較完 4 個(gè)表象都沒找到目標(biāo),則執(zhí)行 jmp 0x00000049 自己跳轉(zhuǎn)自己無限 busy loop。假設(shè)找到了活動(dòng)分區(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 號(hào)中斷,ah = 2 為 Read Sectors From Drive,al = 1 指定要讀的扇區(qū)數(shù)為 1,Drive 為 0x80,讀取位置 (c,h,s) 為活動(dòng)分區(qū)表項(xiàng)中指定的那些,將其讀取到 0x0:0x7c00。隨后跳轉(zhuǎn)過去執(zhí)行代碼。

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

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

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

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

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

我們把 /dev/sdd4 的第一個(gè)扇區(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 下來,對(duì)應(yīng)代碼位于 grub-core/boot/i386/pc/boot.S

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

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

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

其主要調(diào)用的幾個(gè)函數(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 引導(dǎo)項(xiàng)的 linux command,多了 sn=A8ODN01234 mac1=0011322CA785 netif_num=1 vid=1234 pid=1234 這一串參數(shù),估計(jì)是群暉的 kernel 在啟動(dòng)時(shí)需要對(duì)這些參數(shù)進(jìn)行校驗(yàn),猜測(cè)如果校驗(yàn)失敗,那么就無法啟動(dòng)。

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

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 是對(duì) initrd 中內(nèi)核模塊的補(bǔ)充,支持了更多類型的設(shè)備:

$ 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

這其中我只認(rèn)識(shí) e1000,它是虛擬化中最常見的網(wǎng)卡。

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

總結(jié)

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

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

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

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

后記

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

唯一的缺點(diǎn)就是機(jī)械硬盤太吵了,放房間里夜深人靜的時(shí)候嘎嘎嘎響,于是把它搬到客廳了。

參考

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

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

聯(lián)系客服