手动构建适用于Beaglebone Black的Linux系统
本文记录手动构建适用于Beaglebone Black开发板的Linux 系统的过程,包括U-Boot构建、Kernel构建和使用BusyBox构建 根文件系统,以及相关的配置和部署,最终在开发板上运行一个 小型的Linux系统。
准备工作
1. 实验环境
- 主机OS: Arch Linux
- 开发板: BeagleBone Black
- 其他设备: SD卡,SD读卡器,USB转串口工具
2. 配置交叉编译工具链
构建交叉编译工具链的方法可参考本站文章:在Docker中使用crosstool-ng构建交叉编译工具链
以下是几个构建Linux系统相关组件时经常设置的环境变量,
PATH中的<...>要替换成实际安装工具链的路径。
export ARCH=arm
export CROSS_COMPILE=arm-unknown-linux-gnueabihf-
export PATH=<...>/arm-unknown-linux-gnueabihf/bin:$PATH
可以把以上内容保存到一个"setup"文件,需要时执行
source setup操作。
3. 主机配置TFTP和NFS服务
TFTP服务用于U-Boot加载内核和设备树,NFS服务用于 挂载根文件系统。
TFTP
安装tftp-hpa然后启动tftpd.service,默认配置下,
/src/tftp路径下的内容可以被TFTP客户端访问。
NFS
- 安装
nfs-utils; - 修改
/etc/exports文件,添加以下内容:
<your share dir> 192.168.2.2(rw,no_root_squash,no_subtree_check)
<your share dir>要替换成实际共享的路径,192.168.2.2是客户端的IP地址。
- 启动
nfs-server.service; - 让NFS服务使用新配置:
exportfs -arv
U-Boot
U-Boot获取
这里使用beagleboard维护的U-Boot:
git clone https://github.com/beagleboard/u-boot.git
cd u-boot
U-Boot配置
make am335x_evm_defconfig
可以使用make menuconfig进一步自定义配置,此处保留默认配置。
执行构建
make DEVICE_TREE=am335x-boneblack
构建完成后,u-boot项目路径下生成的MLO和u-boot.img两个
文件即为待烧写到SD卡的映像文件。
准备SD卡
将SD通过读卡器连接到主机,并执行以下操作:
-
清空SD卡
-
新建分区表(MBR类型)
-
新建分区,规格如下:
- 大小:64MB
- 类型:W95 FAT32 (LBA)
- 使能bootable标志
示例如下:
Device Boot Start End Sectors Size Id Type
/dev/sdd1 * 2048 133119 131072 64M c W95 FAT32 (LBA)
- 格式化新建的分区(
sdx1要替换成该分区在主机中实际对应的设备):
mkfs.vfat -a -F 32 -n boot /dev/sdx1
拷贝映像文件到SD卡
cp MLO u-boot.img <your new partion mount point>
测试U-Boot
将SD卡插入开发板,在按住S2按键不放的情况下上电,在
串口调试工具可以看到U-Boot成功启动。
U-Boot网络相关配置
开发板U-Boot中执行的配置:
setenv ipaddr 192.168.2.2
setenv serverip 192.168.2.1
setenv ethprime usb_ether
setenv usbnet_devaddr f8:dc:7a:00:00:02
setenv usbnet_hostaddr f8:dc:7a:00:00:01
saveenv
在开发板上执行ping 192.168.2.1,可以看到主机出现一个
新的网络接口设备,可以通过nmcli con show查看,
记住该设备名,在主机执行以下操作(把<device>替换成
实际的设备名),配置IP:
nmcli connection add type ethernet ifname <device> ip4 192.168.2.1/24
Kernel
1. Kernel获取
使用稳定版Kernel:
git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
cd linux
git checkout linux-6.12.y
2. Kernel配置
- 执行
make help,选择一个适用于开发板搭载的TI AM3358 SOC 的配置作为起始配置:
make omap2plus_defconfig
- 执行
make menuconfig进行一些自定义配置:
CONFIG_USB=y
CONFIG_USB_GADGET=y
CONFIG_USB_MUSB_HDRC=y
CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_MUSB_DUAL_ROLE=y
CONFIG_AM335X_PHY_USB=y
CONFIG_USB_ETH=y
CONFIG_INPUT_EVDEV=y
CONFIG_DEVTMPFS_MOUNT=y
3. Kernel构建
执行make构建Kernel,构建结束后,以下两个文件即
启动内核需要的内核映像和设备树文件:
./arch/arm/boot/zImage
./arch/arm/boot/dts/ti/omap/am335x-boneblack.dtb
4. 测试加载和启动Kernel
- 在U-Boot中设置
bootargs环境变量:
setenv bootargs console=ttyS0,115200n8
- 把构建Kernel后得到的
zImage和设备树文件拷贝到 主机TFTP服务共享路径下; - 在U-Boot中加载TFTP服务端的内核映像和设备树文件:
tftp 0x81000000 zImage
tftp 0x82000000 am335x-boneblack.dtb
- 启动Kernel
bootz 0x81000000 - 0x82000000
可以看到Kernel开始启动,最后发生panic,因为这里还没有根 文件系统。
可以在U-Boot中添加环境变量bootcmd,在板reset后自动加载
和启动Kernel:
setenv bootcmd 'tftp 0x81000000 zImage; tftp 0x82000000 am335x-boneblack.dtb;
bootz 0x81000000 - 0x82000000'
saveenv
根文件系统
使用BusyBox构建根文件系统。
1. BusyBox获取
git clone https://git.busybox.net/busybox
cd busybox
2. BusyBox配置
使用make defconfig生成构建的起始配置,使用
make menuconfig进行自定义配置,选择静态构建
并设置执行make install时目标输出路径(实际的
NFS服务共享路径):
CONFIG_STATIC=y
CONFIG_PREFIX="<your nfs share dir>"
3. BusyBox构建
make
make install
以上步骤完成后,在NFS服务共享路径下可见BusyBox生成 根文件系统相关的文件。
4. 根文件系统配置
- 在BusyBox生成的根文件系统路径下,新建路径
dev,proc,sys和tmp作虚拟文件系统 的挂载点; - 新建
etc/inittab文件,内容如下:
::sysinit:/etc/init.d/rcS
ttyS0::askfirst:/bin/sh
::shutdown:/bin/umount -a -r
- 新建
etc/init.d/rcS文件,内容如下:
mount -t proc proc /proc
mount -t sysfs sys /sys
mount -t tmpfs tmp /tmp
5. 测试启动系统
在U-Boot中,设置bootargs环境变量,从NFS加载根
文件系统(注意NFS共享路径参数):
setenv bootargs console=ttyS0,115200n8 root=/dev/nfs ip=192.168.2.2:::::usb0
g_ether.dev_addr=f8:dc:7a:00:00:02 g_ether.host_addr=f8:dc:7a:00:00:01
nfsroot=192.168.2.1:<your nfs share dir>,nfsvers=3,tcp rw
然后,执行run bootcmd,可以看到成功挂载根文件系统并
最终显示命令提示符。
最终部署
经过以上的步骤,成功构建了一个小型的Linux系统,内核映像和 设备树文件是存放在主机TFTP共享路径上的,根文件系统位于主机 主机NFS共享路径上,BusyBox是静态链接的。
1. 使用共享库
重新构建BusyBox,在make menuconfig自定义配置选项
时,取消勾选Build static binary (no shared libs)。
在根文件系统路径下新建lib路径,将交叉编译工具链
中的共享库:
- ld-linux-armhf.so.3
- libc.so.6
- libm.so.6
- libresolv.so.2
拷贝到新建的lib路径下。
reset开发板,确认重新构建的根文件系统能被正常挂载和使用。
2. 将内核映像、设备树文件和根文件系统部署到SD卡
将内核映像、设备树文件拷贝到SD卡第一个分区;
以下步骤使用SquashFS文件系统部署根文件系统:
- 主机安装
squashfs-tools; - 制作SquashFS文件系统映像:
mksquashfs <your rootfs dir> rootfs.sqfs
- SD卡新建分区,大小8MB,用于存放根文件系统;
- 使用
dd,将SquashFS文件系统映像写入新建的分区(sdx2要替换 成该分区在主机中实际对应的设备):
dd if=rootfs.sqfs of=/dev/sdx2 bs=1M status=progress conv=fsync
在U-Boot中,修改环境变量bootargs和bootcmd:
setenv bootargs console=ttyS0,115200n8 root=/dev/mmcblk0p2 rootwait
setenv bootcmd 'load mmc 0:1 0x81000000 zImage;
load mmc 0:1 0x82000000 am335x-boneblack.dtb;
bootz 0x81000000 - 0x82000000'
saveenv
reset开发板,确认重新部署的Linux能够从SD卡启动运行。