手动构建适用于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

  1. 安装nfs-utils
  2. 修改/etc/exports文件,添加以下内容:
<your share dir> 192.168.2.2(rw,no_root_squash,no_subtree_check)

<your share dir>要替换成实际共享的路径,192.168.2.2是客户端的IP地址。

  1. 启动nfs-server.service;
  2. 让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项目路径下生成的MLOu-boot.img两个 文件即为待烧写到SD卡的映像文件。

准备SD卡

将SD通过读卡器连接到主机,并执行以下操作:

  1. 清空SD卡

  2. 新建分区表(MBR类型)

  3. 新建分区,规格如下:

    • 大小:64MB
    • 类型:W95 FAT32 (LBA)
    • 使能bootable标志

    示例如下:

Device     Boot  Start      End  Sectors  Size Id Type
/dev/sdd1  *      2048   133119   131072   64M  c W95 FAT32 (LBA)
  1. 格式化新建的分区(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配置
  1. 执行make help,选择一个适用于开发板搭载的TI AM3358 SOC 的配置作为起始配置:
make omap2plus_defconfig
  1. 执行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
  1. 在U-Boot中设置bootargs环境变量:
setenv bootargs console=ttyS0,115200n8
  1. 把构建Kernel后得到的zImage和设备树文件拷贝到 主机TFTP服务共享路径下;
  2. 在U-Boot中加载TFTP服务端的内核映像和设备树文件:
tftp 0x81000000 zImage
tftp 0x82000000 am335x-boneblack.dtb
  1. 启动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. 根文件系统配置
  1. 在BusyBox生成的根文件系统路径下,新建路径 devprocsystmp作虚拟文件系统 的挂载点;
  2. 新建etc/inittab文件,内容如下:
::sysinit:/etc/init.d/rcS
ttyS0::askfirst:/bin/sh
::shutdown:/bin/umount -a -r
  1. 新建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文件系统部署根文件系统:

  1. 主机安装squashfs-tools
  2. 制作SquashFS文件系统映像:
mksquashfs <your rootfs dir> rootfs.sqfs
  1. SD卡新建分区,大小8MB,用于存放根文件系统;
  2. 使用dd,将SquashFS文件系统映像写入新建的分区(sdx2要替换 成该分区在主机中实际对应的设备):
dd if=rootfs.sqfs of=/dev/sdx2 bs=1M status=progress conv=fsync

在U-Boot中,修改环境变量bootargsbootcmd

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卡启动运行。

参考