--- title: RYO - eaglebone Black tags: [RYO, BeagleBone Black, Embedded Linux, U-Boot, Toolchain, rootfs] --- # RYO-Beaglebone Black > 作者:Gordon Lu > 更新日期:20250619 --- ## 1 工具鏈建置 (Toolchain) ### 1-1 安裝 crosstool-NG ```bash git clone https://github.com/crosstool-ng/crosstool-ng.git cd crosstool-ng #install necessary tools sudo apt-get install gperf bison flex texinfo unzip help2man libtool-bin sudo apt-get install autoconf ./bootstrap #install current folder $PWD, do not install in /usr/local/share ./configure --prefix=${PWD} make make install ``` ### 1-2 建立工具鏈 ```bash= bin/ct-ng show-arm-cortex_a8-linux-gnueabi bin/ct-ng arm-cortex_a8-linux-gnueabi bin/ct-ng menuconfig ``` - 取消選取:Path and misc options → Render the toolchain read-only ![image](https://hackmd.io/_uploads/Hk_h5MNZll.png) - 選取:Target options → Floating point → hardware(FPU) ![image](https://hackmd.io/_uploads/Hykcof4Zgg.png) - 選取:Target options → Use specific FPU → "neon" ![image](https://hackmd.io/_uploads/Hy4Qf41Zee.png) ![image](https://hackmd.io/_uploads/ryaoizE-ee.png) 儲存 `.config` 後,執行: ```bash bin/ct-ng build ``` (約需 30 分鐘) ### 1-3 設定環境變數 ```bash echo 'export PATH=~/x-tools/arm-cortex_a8-linux-gnueabihf/bin:$PATH' >> ~/.bashrc source ~/.bashrc ``` ### 1-4 測試工具鏈 ```bash= #show version arm-cortex_a8-linux-gnueabihf-gcc -v #comiple hello.c arm-cortex_a8-linux-gnueabihf-gcc hello.c -o hello #check file fromate file hello ``` ![image](https://hackmd.io/_uploads/BkQZ2zN-ge.png) ![image](https://hackmd.io/_uploads/ryBgnzV-gg.png) --- ## 2 建置 U-Boot ### 2-1 取得原始碼 ```bash git clone https://github.com/u-boot/u-boot.git cd u-boot #目前用個版本測試ok git checkout v2023.04 ``` ![image](https://hackmd.io/_uploads/SkUf9TKZgx.png) ### 2-2 設定交叉編譯器 某些重要的套件可以輕易地以跨平台方式編譯,包括Linux 的內核、U-Boot 啟動載入器、BusyBox。以上這些情況,只要把工具鏈的前綴字樣餵給 make 指令的變數CROSS_COMPILE 就好,如在第一步驟用corsstool-NG 做出的compile arm-cortex a8-1inux-gnueabihf-。記得最末尾的那個破折號。 ```bash PATH=${HOME}/x-tools/arm-cortex_a8-linux-gnueabihf/bin/:$PATH export CROSS_COMPILE=arm-cortex_a8-linux-gnueabihf- export ARCH=arm ``` ### 2-3 設定配置檔 BeagleBone Black 使用 ARM 架構,並且有特定的 U-Boot 配置。選擇適合 BeagleBone Black 的配置 ```bash #第一次換cofig前下make distclean,會清清除所有編譯狀態, make distclean包括了make clean的清理範圍 make distclean #make clean只會清object與binary想快速重新編譯時使用 #make clean make am335x_evm_defconfig ``` ### 2-4 編譯 ```bash make #check output file ls -l MLO u-boot* ``` 產出檔案: - `u-boot` 這是以ELF 目標檔格式(ELF object format)存在的U-Boot,可與除錯器搭配使用。 - `u-boot.map` 符號表(symbol table) - `u-boot.bin` 以二進位格式存在的U-Boot,可在目標環境上運行。 - `u-boot.img` 這是加上了U-Boot 標頭檔的u-boot.bin,可作為 U-Boot 的運行複本上傳使用。 - `u-boot.srec` 這是以 Motorola S-Record 格式(又被稱為 SRECORD 或SRE)存在的U-Boot,可透過序列連接(serial connection)進行傳輸。 - `MLO`(第二階段 bootloader) BeagleBone Black 還需要一個第二階段程式載入器(SPL)。這部分也一起組建出來了,並被命名為 MLO。 --- ## 3 在WSL2建立 SD 卡映像檔 (MLO and U-boot) (MLO and U-boot) ### 3-1 WSL2下將sd掛載 1、安裝usbipd - 比較簡單就請自行安裝 2、重新build wsl2 kernel (因為目前的kernel不支援usb mass storage driver) 參考:https://blog.csdn.net/weixin_43638991/article/details/139891334 ![image](https://hackmd.io/_uploads/rkwjsFczxx.png) ``` #clone wsl2 git git clone https://github.com/microsoft/WSL2-Linux-Kernel.git #checkout current kernenl version (my kernel is 5.15.167.4) cd WSL2-Linux-Kernel git checkout linux-msft-wsl-$(uname -r | cut -d- -f1) #install necessary tools sudo apt update sudo apt install libncurses-dev build-essential flex bison libssl-dev libelf-dev dwarves #clean all make distclean #config kernel make menuconfig KCONFIG_CONFIG=Microsoft/config-wsl ``` check and save Device Drivers-> USB support ![image](https://hackmd.io/_uploads/rkQ7H46fee.png) 如果要在wsl2 中用ftdi232收bbb的uart,記得要把 USB Serial Converter Support -> USB FTDI Single Port Serial Driver 也選起來。 ![image](https://hackmd.io/_uploads/rknLpTCzle.png) ``` #make kenrel , 使用上面建立的config-wsl 來make make -j$(nproc) bzImage KCONFIG_CONFIG=Microsoft/config-wsl ``` 將build好的image複制到c: `cp ./arch/x86/boot/bzImage /mnt/c/Users/User/custom-wsl2-kernel/` 在 C:\Users\User\下新增或修改.wslconfig檔,主要是增加kernel=C:\\Users\\user\\custom-wsl2-kernel\\bzImage,這個設定,其他的可以視電腦的規格而定 ``` [wsl2] memory=8GB # 分配給 WSL2 的最大記憶體(可視情況調整 6~10GB) processors=6 # 分配 CPU 核心數(i7-1360P 有 12 線程,分一半給 WSL) swap=4GB # swap 空間(RAM 不夠時使用) localhostForwarding=true # 讓 WSL2 與 Windows 之間可互通網路 kernel=C:\\Users\\user\\custom-wsl2-kernel\\bzImage ``` 重啟wsl2,再看一下kernel是否已改變。 ``` wsl --shutdown wsl ``` ![image](https://hackmd.io/_uploads/B1nLiq5zel.png) 以管理員開啟powershell `usbipd list` ![image](https://hackmd.io/_uploads/ByGB3q5Gxg.png) bind SD card reader and attach it to wsl2 ``` usbipd bind -b 2-14 usbipd attach --wsl -b 2-14 usbipd list ``` ![image](https://hackmd.io/_uploads/r1PC3c9zlx.png) 在wsl2中看是有 SD card, `lsblk` ![image](https://hackmd.io/_uploads/SyUgC9cfxg.png) 其中sdf就是我的sd card ### 3-2 分割和格式化SD card ```bash sudo fdisk /dev/sdf o # 清除舊分割表,create a new empty DOS partition table n # 建立新分區 p # 主分區 1 # 分區號 1 # (Enter)起始位置預設 +64M # 給 boot 區 64MB n # 建立第 2 分區 p # 主分區 2 # (Enter)起始位置預設 # (Enter)結束預設為最大 t # 改變分區類型 1 # 改第 1 分區 c # W95 FAT32 (LBA) #將partation 1 i設為boot a 1 #檢查設定 p w # 寫入並離開 # 建立兩個分區:FAT32 + ext4 ``` 格式化分區 ```bash sudo mkfs.vfat /dev/sdf1 -n BOOT sudo mkfs.ext4 /dev/sdf2 -L rootfs ``` check SD card `sudo fdisk -l /dev/sdf` ![image](https://hackmd.io/_uploads/H1ZKbj9Gle.png) ### 3-3 掛載分區並寫入檔案 ```bash sudo mkdir -p /mnt/boot /mnt/rootfs sudo mount /dev/sdf1 /mnt/boot sudo mount /dev/sdf2 /mnt/rootfs (⚠️ MLO 一定要是 FAT32 分區中第一個寫入的檔案,不要先複製其他檔) sudo cp MLO /mnt/boot/ sudo cp u-boot.img /mnt/boot/ #ls -lt --full-time /mnt/boot #確保 MLO 是最早複製的(timestamp 最早) #如果有根檔系統,解壓 rootfs 至 /mnt/rootf,或是從 debootstrap 建立基本系統再複製(可延伸)。 sudo tar -xpf rootfs.tar.gz -C /mnt/rootfs ``` ### 3-4 卸載 sudo umount /mnt/boot sudo umount /mnt/rootfs --- ## 4 在BBB建立 SD 卡映像檔 (MLO and U-boot) ### 4-1 copy MLO and u-boot.img to BBB 將2-4得到的MLO and u-boot.img 傳到bbb ``` ls -l MLO u-boot* scp MLO gordon@192.168.7.2:/home/gordon scp u-boot.img gordon@192.168.7.2:/home/gordon ``` ### 4-2 切換到 BBB做SD card ``` ssh gordon@192.168.7.2 #bbb lsblk #確認sd卡的位置,這裏是/dev/mmcblk0 ``` ![image](https://hackmd.io/_uploads/rJriNTF-ex.png) ### 4-3 fdisk sd card ``` sudo fdisk /dev/mmcblk0 o ← 清除舊分割表 n ← 新增boot分割區 p ← 主分割區 1 ← 分割區 1 2048 ← 起始位址(預設即可) +64M ← 大小為 64MB t ← 改變分割區格式 c ← 設為 W95 FAT32 (LBA) a ← 設為 bootable n ← 新增rootfs分割區 p ← 主分割區 2 ← 分割區2 ← 起始位址(預設即可) ← 大小為 (預設即可) w ← 儲存並退出 ``` ### 4-3 格式化分割區 ``` #boot sudo mkfs.vfat -F 32 -n BOOT /dev/mmcblk0p1 #rootfs sudo mkfs.ext4 /dev/mmcblk0p2 ``` ### 4-4 掛載 FAT 分割區 ``` sudo mkdir -p /mnt/sd sudo mount /dev/mmcblk0p1 /mnt/sd ``` ### 4-5 複製 MLO 和 u-boot.img ``` sudo cp MLO /mnt/sd/ sudo cp u-boot.img /mnt/sd/ sync #確保 MLO 是最早複製的(timestamp 最早) ls -lt --full-time /mnt/sd ``` ![image](https://hackmd.io/_uploads/HJQ4OTFZlx.png) ### 4-6 卸載 `sudo umount /mnt/sd` --- ## 5 使用SD卡和U-Boot啟動BBB - 一定要使用 5V/2A DC 電源(內徑 2.1mm / 外徑 5.5mm,中心正極) - 插入 SD 卡 - 按住 S2 Boot 鍵 → 接電源 → 按任意一鍵中斷原本自動開機流程(透過uart0 console)->約 2~3 秒後放開Boot鍵 ![image](https://hackmd.io/_uploads/Hksp_LVWex.png) 在host consle看到下面的文字,進到u-boot SPL 2-23.04,也就是在前面2-1 checkout的版本。 並且進到U-Boot 的符號: => 輸入nand測試 ![image](https://hackmd.io/_uploads/H1rJYTFWxl.png) !!!上面的console是要直接把TXD/RXD/GND利用usb to uart的硬體從BBB接上host。請注意:不是透過ssh登入,因為這時只有uboot,沒有其他的功能。!!! ![image](https://hackmd.io/_uploads/rJ5OKN6Mee.png) --- ## 6編譯內核 ### 6-1 取得原始碼 ```bash #方法一下載穩定版工作樹 (這裏是用v5.4.290) git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git cd linux-stable git checkout v5.4.290 #方法二,直接下載source code wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.4.50.tar.xz tar -xf linux-5.4.290.tar.xz mv linux-5.4.290 linux-stable ``` ### 6-2 下載必要工具 `sudo apt install libncurses-dev flex bison` ### 6-3 設定和編譯內核 ``` PATH=${HOME}/x-tools/arm-cortex_a8-linux-gnueabihf/bin/:$PATH #把內核原始碼清乾淨, 清除編譯產物與 .config(保留源碼) make ARCH=arm CROSS_COMPILE=arm-cortex_a8-linux-gnueabihf- mrproper or #移除所有編譯產物與設定檔,讓專案回到初始未設定的乾淨狀態 make ARCH=arm CROSS_COMPILE=arm-cortex_a8-linux-gnueabihf- distclean #ARMv7-A的通用設定, bbb-TI AM3358實體處理器核心是ARM Cortex-A8,而ARM Cortex-A8是由ARM依據 ARMv7-A 架構打造出來的具體產品 make ARCH=arm multi_v7_defconfig #menu config 必要選項 make ARCH=arm menuconfig #編譯內核, -j$(nproc):用所有可用的CPU平行處理,指的是CPU核 #成功之後 zImage 會在 ./arch/arm/boot time make -j$(nproc) ARCH=arm CROSS_COMPILE=arm-cortex_a8-linux-gnueabihf- zImage #編譯內核模組 time make -j$(nproc) ARCH=arm CROSS_COMPILE=arm-cortex_a8-linux-gnueabihf- modules #編譯硬體結構樹 #成功之後結構樹會在 ./arch/arm/boot/dts/am335x-boneblack.dtb time make -j$(nproc) ARCH=arm CROSS_COMPILE=arm-cortex_a8-linux-gnueabihf- dtbs ``` --- ## 7 利用uboot啟動內核 copy zImage and dtb to bbb ``` gordon@pc:~/kernel/linux-stable/arch/arm/boot/dts$ scp am335x-boneblack.dtb gordon@192.168.7.2:~/ gordon@pc:~/kernel/linux-stable/arch/arm/boot$ scp zImage gordon@192.168.7.2:~/ ``` 開啟bbb,檢查sd card分區,將資料copy到boot 分區 `sudo fdisk -l` #在bbb中 ![image](https://hackmd.io/_uploads/H1o8sWXfle.png) ``` sudo mount /dev/mmcblk0p1 /mnt/boot #在bbb gordon@bbb:~$ sudo cp zImage /mnt/boot/ gordon@bbb:~$ sudo /mnt/boot/ gordon@bbb:ls /mnt/boot ``` bbb利用sd card開機------執行(5 使用SD卡和U-Boot啟動BBB) ``` => fatload mmc 0:1 0x80200000 zImage 9331200 bytes read in 612 ms (14.5 MiB/s) => fatload mmc 0:1 0x80f00000 am335x-boneblack.dtb 58495 bytes read in 7 ms (8 MiB/s) =>setenv bootargs console=ttyO0,115200 => bootz 0x80200000 - 0x80f00000 Kernel image @ 0x80200000 [ 0x000000 - 0x8e6200 ] ## Flattened Device Tree blob at 80f00000 Booting using the fdt blob at 0x80f00000 Working FDT set to 80f00000 Loading Device Tree to 8ffee000, end 8ffff47e ... OK Working FDT set to 8ffee000 Starting kernel ... [ 0.000000] Booting Linux on physical CPU 0x0 [ 0.000000] Linux version 5.4.290 (gordon@pc) (gcc version 15.1.0 (crosstool-NG 1.27.0.42_35c1e72)) #1 SMP Tue May 27 17:13:52 CST 2025 [ 0.000000] CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c5387d [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache [ 0.000000] OF: fdt: Machine model: TI AM335x BeagleBone Black [ 0.000000] Memory policy: Data cache writeback [ 0.000000] efi: Getting EFI parameters from FDT: [ 0.000000] efi: UEFI not found. [ 0.000000] cma: Reserved 64 MiB at 0x9b800000 [ 0.000000] CPU: All CPU(s) started in SVC mode. [ 0.000000] AM335X ES2.1 (sgx neon) ..................................... ..................................... [ 2.577953] [<c0f54648>] (kernel_init) from [<c03010e8>] (ret_from_fork+0x14/ 0x2c) [ 2.585552] Exception stack(0xdb0a7fb0 to 0xdb0a7ff8) [ 2.590625] 7fa0: 00000000 00000000 00000 000 00000000 [ 2.598839] 7fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000 000 00000000 [ 2.607052] 7fe0: 00000000 00000000 00000000 00000000 00000013 00000000 [ 2.613710] ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) ]--- #內核崩壞!!!!!!!!!!!! #因為沒有root file system ``` --- ## 8 建立根檔案系統 ### 8-1建立暫存目錄 ``` mkdir rootfs cd rootfs mkdir bin dev etc home lib proc sbin sys tmp usr var mkdir usr/bin usr/lib usr/sbin mkdir -p var/log sudo chown -R root:root * tree -d ``` ![image](https://hackmd.io/_uploads/ry3CRJnfeg.png) ### 8-2 下載和編譯busybox ``` git clone git://busybox.net/busybox.git or git clone https://github.com/mirror/busybox.git git checkout 1_36_1 make distclean make ARCH=arm CROSS_COMPILE=arm-cortex_a8-linux-gnueabihf- defconfig make ARCH=arm CROSS_COMPILE=arm-cortex_a8-linux-gnueabihf- menuconfig ------------------------------------------------------------ Busybox Settings ---> Build Options ---> [*] Build BusyBox as a static binary (no shared libs) Coreutils ---> [ * ] ls [ * ] cp [ * ] rm [ * ] mv [ * ] mkdir Shells ---> [ * ] lash 或 [ * ] ash(建議用 ash) Init Utilities ---> [ * ] init [ * ] reboot [ * ] halt #disable tc due to compile error Networking Utilities ---> [ ] tc ------------------------------------------------------------------------- #make busybox make ARCH=arm CROSS_COMPILE=arm-cortex_a8-linux-gnueabihf- #install busybox to rootfs,因為前面已經把rootfs 的owner改為root, 所以要用sudo。而在使用 sudo 時,環境變數 $PATH 被清空或不同於一般使用者,所以這裏要把path 代入,這樣會把目前 shell 的 $PATH 傳遞給 sudo 內部的環境,讓它找得到交叉編譯器。 sudo env "PATH=$PATH" make ARCH=arm CROSS_COMPILE=arm-cortex_a8-linux-gnueabihf- CONFIG_PREFIX=../rootfs install #check busybox file format : shoud be "statically linked" file ../rootfs/bin/busybox ``` ![image](https://hackmd.io/_uploads/S1XjHXx7eg.png) ``` #check rootfs cd rootfs tree ``` ![image](https://hackmd.io/_uploads/S1CV8QlXee.png) ### 8-3 建立裝置節點 busybox在啟動過程中至少要兩個裝置節點:consol and null ``` cd rootfs sudo mknod -m 600 dev/console c 5 1 sudo mknod -m 666 dev/null c 1 3 ``` ### 8-4 建立boot initramfs ``` cd rootfs #建立 initramfs 的 cpio 封裝 find . | cpio -H newc -ov --owner root:root > ../initramfs.cpio cd .. gzip initramfs.cpio mkimage -A arm -O linux -T ramdisk -d initramfs.cpio.gz uRamdisk #如何驗証是否包好的檔案為root所有,同時檢查其中的內容 #zcat initramfs.cpio.gz | cpio -tv #copy uRamdisk to sd card boot partition lsblk sudo mount /dev/sdd1 /mnt/boot sudo cp uRamdisk /mnt/boot sudo umount /mnt/boot ``` ### 8-5 boot with initramfs 先參考 5-使用SD卡和U-Boot啟動BBB,開機到uboot 下。 ``` => fatload mmc 0:1 0x80200000 zImage 9331200 bytes read in 612 ms (14.5 MiB/s) => fatload mmc 0:1 0x80f00000 am335x-boneblack.dtb 58495 bytes read in 7 ms (8 MiB/s) => fatload mmc 0:1 0x81000000 uRamdisk 1301805 bytes read in 86 ms (14.4 MiB/s) => setenv bootargs console=ttyO0,115200 rdinit=/bin/sh #bootz zImage initramfs=psuRamdisk DTB => bootz 0x80200000 0x81000000 0x80f00000 ``` ### 8-6 uboot自動化載入 8-5的步驟可以完全自動化 先編一個boot.cmd文字檔 ``` #boot.cmd setenv bootargs console=ttyS0,115200 rdinit=/bin/sh fatload mmc 0:1 0x82000000 zImage fatload mmc 0:1 0x80F00000 am335x-boneblack.dtb fatload mmc 0:1 0x81000000 uRamdisk bootz 0x82000000 0x81000000 0x80F00000 #在舊版 kernel(例如 3.x)中,TI 的 UART 是 ttyO0(O = OMAP) 但在新版 kernel(如你用的 5.4),統一改用 ttyS0 表示 serial 裝置 ``` 然後編譯成uboot可以執行的binary ``` #會產出boot.scr mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n "BBB autoboot" -d boot.cmd boot.scr ``` 將boot.src copy to boot partition 在uboot 開機時輸入下面二行指令,然後重新啟動即可。 ``` setenv bootcmd 'load mmc 0:1 ${loadaddr} boot.scr; source ${loadaddr}' saveenv ``` saveeenv 會把剛剛設定的變數(如 bootcmd)永久寫入到 U-Boot 的環境儲存區(通常是 NAND、eMMC 或 SPI Flash)。 回復手動開機的話,可以用這清除 bootcmd: ``` setenv bootcmd saveenv ``` ### 8-7 掛載proc 現在應該可以開到~#下面,但ps沒有作用,所以要掛載proc -t proc :指定要掛載的檔案系統類型是 proc(虛擬檔案系統) proc :資源名稱,這裡是 proc(對於虛擬 FS 是慣用名稱) /proc :掛載點,也就是你要把 procfs 掛在哪個目錄下 `mount -t proc proc /proc` ![image](https://hackmd.io/_uploads/S11wFQeQxx.png) --- ## 9 root file system 直接加入核心映像檔中 除了上面initramfs 可以由uboot 載入啟動外,除了上面initramfs 也可以直接加入核心映像檔中 ``` cd linux-stable/ make ARCH=arm CROSS_COMPILE=arm-cortex_a8-linux-gnueabihf- distclean make ARCH=arm multi_v7_defconfig make ARCH=arm multi_v7_defconfig menuconfig ``` 把root file system path放入設定 ![image](https://hackmd.io/_uploads/HJnXfElXll.png) ![image](https://hackmd.io/_uploads/ryaJMVeXlg.png) ``` #編譯內核 make -j$(nproc) ARCH=arm CROSS_COMPILE=arm-cortex_a8-linux-gnueabihf- zImage #copy zImage to sd boot partition ``` 再用uboot啟動 ``` => fatload mmc 0:1 0x80200000 zImage 9331200 bytes read in 612 ms (14.5 MiB/s) => fatload mmc 0:1 0x80f00000 am335x-boneblack.dtb 58495 bytes read in 7 ms (8 MiB/s) => setenv bootargs console=ttyO0,115200 rdinit=/bin/sh #這次不用指定initramfs 即可開機。 => bootz 0x80200000 - 0x80f00000 ``` ![image](https://hackmd.io/_uploads/r1dWDEgQxe.png) --- ## 10 完整的root filesystem 設定,可以透過root登入 上面的步驟已經可以開到shll,但非一般透過init的做法,下面是比較完整的做法。 有幾個步驟要做: 修改boot.cmd,並且在rootfs下面增加: etc/inittab, etc/init.d/rcS, etc/passwd, etc/shadow 四個檔案 ``` #boot.cmd setenv bootargs console=ttyS0,115200 rdinit=/sbin/init fatload mmc 0:1 0x82000000 zImage fatload mmc 0:1 0x80F00000 am335x-boneblack.dtb fatload mmc 0:1 0x81000000 uRamdisk bootz 0x82000000 0x81000000 0x80F00000 #注意:console=ttyS0,115200 rdinit=/sbin/init 這裏和前面不同。 ``` ``` #etc/inittab ::once:/bin/sh -c 'echo "inittab test OK" > /tmp/inittab_test' ::sysinit:/etc/init.d/rcS ttyS0::respawn:/sbin/getty -L ttyS0 115200 vt100 ::ctrlaltdel:/sbin/reboot ::shutdown:/sbin/swapoff -a ::shutdown:/bin/umount -a -r ::restart:/sbin/init ``` ``` #etc/init.d/rcS echo "Init: mounting filesystems..." mount -t proc proc /proc mount -t sysfs sysfs /sys mount -t tmpfs tmpfs /tmp mount -t devtmpfs devtmpfs /dev echo "Init: setting up mdev..." if [ -e /proc/sys/kernel/hotplug ]; then echo /sbin/mdev > /proc/sys/kernel/hotplug fi mdev -s echo "Init: system ready." ``` ``` #etc/passwd, root 用空白密碼登入 root:x:0:0:root:/root:/bin/sh ``` ``` #etc/shadow , root 用空白密碼登入 root::10933:0:99999:7::: ``` 注意要各檔案的權限,一定要和下圖一樣。可以用chmod來做,如: sudo chmod +x etc/init.d/rcS sudo chmod 600 shadow ![image](https://hackmd.io/_uploads/r1SyA8F7ll.png) ![image](https://hackmd.io/_uploads/Hkk-CUKXxx.png) 然後重新打包rootfs、編譯boot.scr、copy ``` mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n "BBB autoboot" -d boot.cmd boot.scr ``` 如果要重新build root filesystem 並且檔查設定和複製檔案,可以用下面的自動化script ``` #buildfs.sh #!/bin/bash sudo -v ROOTFS_DIR=${1:-rootfs} INITRAMFS=initramfs.cpio URAMDISK=uRamdisk MNT=/mnt/sdcard echo "[*] 使用 rootfs 目錄: $ROOTFS_DIR" [ ! -d "$ROOTFS_DIR" ] && echo "❌ 沒有 rootfs 目錄" && exit 1 # 補上換行符 for file in "$ROOTFS_DIR/etc/passwd" "$ROOTFS_DIR/etc/shadow"; do [ -f "$file" ] || continue sudo tail -c1 "$file" | grep -qv $'\n' && echo >> "$file" done [ ! -f "$ROOTFS_DIR/init" ] && [ ! -f "$ROOTFS_DIR/sbin/init" ] && echo "⚠️ 無 init 或 sbin/init" cd "$ROOTFS_DIR" sudo bash -c "find . | cpio -H newc -ov --owner root:root > ../$INITRAMFS" cd .. sudo gzip -f $INITRAMFS sudo mkimage -A arm -O linux -T ramdisk -d ${INITRAMFS}.gz $URAMDISK echo "[✓] uRamdisk 建立完成:$(pwd)/$URAMDISK" echo "[*] 偵測 FAT32 SD 分割區..." FAT_DEV=$(lsblk -o NAME,FSTYPE -nr | grep -i 'vfat' | awk '{print "/dev/"$1}' | head -n1) if [ -z "$FAT_DEV" ]; then echo "❌ 沒有找到 FAT32 分割區,請確認 SD 卡有正確格式" exit 1 fi echo "[✓] 偵測到 FAT32 分割區:$FAT_DEV" sudo mkdir -p $MNT sudo mount $FAT_DEV $MNT && echo "[✓] 已掛載 $FAT_DEV 到 $MNT" read -p "❓ 是否將 $URAMDISK 複製到 FAT32 分割區?[y/N] " yn if [[ "$yn" =~ ^[yY]$ ]]; then sudo cp $URAMDISK $MNT/ echo "[✓] 已複製到 $MNT" echo "[*] FAT32 分割區內容:" ls -lh $MNT/ sudo umount $MNT && echo "[✓] 已卸載 $MNT" else echo "[ℹ️] 已略過複製" fi ``` ``` chmod +x buildfs.sh ./buildfs.sh ``` 以root 空白密碼登入後,top, Ctrl-C 等都可以正常使用。 ![image](https://hackmd.io/_uploads/Sy0NGwYmge.png) --- ## 11.用tftp載入kernel Image and dtb 安裝TFTP server https://pjo2.github.io/tftpd64/ 設定目錄,並將zImage和am335x-boneblack.dtb放在目錄之下: ![image](https://hackmd.io/_uploads/BkhkFgW4le.png) ![image](https://hackmd.io/_uploads/rkDHKlZNgg.png) ``` #啟動uboot, 輸入下面資訊 setenv ethact eth2 setenv ipaddr 10.0.3.99 setenv serverip 10.0.3.142 setenv netmask 255.255.255.0 setenv gatewayip 10.0.3.1 setenv bootfile zImage setenv fdtfile am335x-boneblack.dtb setenv nfsroot /nfs_rootfs setenv rootpath ${serverip}:${nfsroot} setenv bootargs "console=ttyO0,115200n8 root=/dev/nfs rw nfsroot=${rootpath},tcp ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:bbb:eth0:off" tftpboot 0x82000000 ${bootfile} tftpboot 0x88000000 ${fdtfile} bootz 0x82000000 - 0x88000000 ``` 到這裏應可以開到kernel, 但root filesystem應該沒有掛上,因為還要架一個NFS server要讓root filesystem掛上, 不過目前nfs的實驗沒有成功,所以就先到這裏。,現在在wsl2中架nfs可以在本機掛上根檔案系統,但是無法在bbb上掛上,可能是網路的關係,等以後有合適網路環境再來試試。 要先備註在這的是用nfs 掛上root filesystem的方法,kernel build 的時候要取消之前用initramfs的選項才可以(前面第九章是做成支持initramfs的kernel) --- ## 參考: [Mastering Embedded Linux Programming](https://www.amazon.com/Mastering-Embedded-Linux-Programming-potential/dp/1789530385) https://hackmd.io/@sss22213/SyHM2lfIO