芯片启动的全过程大概是:Bootloader-Kernel-RootFS
对于我们这次实验来说,就是:uboot-linux kernel6.1.19-Buildroot
环境准备
本次实验宿主机使用全新的Ubuntu20.04环境,并在完成实验后用户目录下有以下结构的文件夹。
首先需要创建架构。
workspace
- linux
- partitions
-- boot
--- boot.scr
--- suniv-f1c100s-licheepi-nano.dtb
--- zImage
-- root
- u-boot
- modules
- buildroot
- boot.cmd
然后下载所有本次实验会使用到的代码和依赖。
# 安装依赖
sudo apt-get install flex bison gcc make gcc-arm-linux-gnueabihf libncurses-dev swig python-dev device-tree-compiler python3-setuptools python3-dev libssl-dev u-boot-tools g++ patch
# 下载Mainline Linux,你可以在https://www.kernel.org寻找最新的LTS版本
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.1.19.tar.xz
# extract是zsh提供的自动解压指令,可以替换成tar的对应格式解压指令
extract linux-6.1.19.tar.xz
mv linux-6.1.19 linux
# 下载U-Boot,我们这里没有使用LTS版本,你可以进入cd进去后切换到LTS分支
git clone git://git.denx.de/u-boot.git
# 下载Buildroot,你可以在https://buildroot.org/downloads寻找最新的版本
wget https://buildroot.org/downloads/buildroot-2023.02.tar.xz
extract buildroot-2023.02.tar.xz
mv buildroot-2023.02 buildroot
每一章节结束后请返回workspace目录。
编译U-Boot
cd u-boot
# 使用荔枝派Nano的默认配置
make CROSS_COMPILE=arm-linux-gnueabihf- licheepi_nano_defconfig
# 编译
make CROSS_COMPILE=arm-linux-gnueabihf-
# 拷贝U-Boot镜像
cp u-boot-sunxi-with-spl.bin ../partitions
接下来我们需要准备U-Boot启动所需的配置文件,将以下内容写入boot.cmd。
setenv bootargs console=tty0 console=ttyS0,115200 panic=5 rootwait root=/dev/mmcblk0p2 rw
load mmc 0:1 0x80C00000 suniv-f1c100s-licheepi-nano.dtb
load mmc 0:1 0x80008000 zImage
bootz 0x80008000 - 0x80C00000
接着编译配置文件。
mkimage -C none -A arm -T script -d boot.cmd ./partitions/boot/boot.scr
编译Kernel
cd linux
# 使用linux-sunxi项目的默认配置,该项目主要包含全志各芯片的硬件支持文档和手册
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- sunxi_defconfig
# 进入内核配置菜单
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
我们需要修改内核配置菜单中的部分项目,否则在之后会遇到很多问题。
配置位置 | 操作 | 用途 |
System Type -> Platform selection | 取消所有勾,勾选ARMv5支持 | CPU架构支持 |
System Type -> Allwinner SoCs | 勾选Armv5支持 | CPU架构支持,本选项不勾选会影响DTB文件生成 |
Kernel Features | 勾选ARM EABI | 不勾选会导致Kernel可以运行,但是无法加载RootFS的Init |
# 编译内核,-j4的4可以修改为你的CPU核心数
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make -j4 zImage
# 编译DTB文件,本文件用于Kernel识别外设,是 Mainline Kernel不可缺少的部分,-j4的4可以修改为你的CPU核心数
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make -j4 dtbs
# 编译Modules,-j4的4可以修改为你的CPU核心数
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make -j4 modules
# 安装模块
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=../modules make modules modules_install
# 拷贝生成的zImage内核镜像和DTB文件
cp arch/arm/boot/zImage ../partitions/boot
cp arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dtb ../partitions/boot
编译Buildroot
我们使用Buildroot默认的BusyBox程序和GLIBC,如果需要剪裁大小,可以选择其他的C支持库。
cd buildroot
# 进入配置菜单
make menuconfig
配置位置 | 操作 | 用途 |
Target options | Target Arch设置为ARM (little endian) | 设置大小端 |
Target options | Target Arch Variant设置为arm926t | 设置CPU架构 |
Toolchain | Kernel Headers设置为你下载的LTS版本内核对应的版本号 | 匹配内核版本 |
# 编译,Buildroot不支持多线程编译,所以不携带-j
make
# 拷贝解压文件系统和内核模块
cp output/images/rootfs.tar ../partitions/root
cd ../partitions/root
extract rootfs.tar
mv rootfs/* ./
rm -rf rootfs
rm rootfs.tar
cp -R ../../modules/* ./
同时修改partitions/root/etc/fstab文件中的ext2为ext4
写入SD卡
请替换CARD_PATH为你的SD卡设备路径,如/dev/sdb
cd partitions
# 清空分区表
dd if=/dev/zero of=CARD_PATH bs=1M count=1
# 写入U-Boot
dd if=u-boot-sunxi-with-spl.bin of=CARD_PATH bs=1024 seek=8
# 写入分区表,请复制除了本行内的内容并执行
blockdev --rereadpt CARD_PATH
cat <<EOT | sfdisk CARD_PATH
1M,16M,c
,,L
EOT
# 格式化
mkfs.vfat 第一个分区路径
mkfs.ext4 第二个分区路径
# 拷贝boot进入第一个分区
mount 第一个分区路径 /mnt
cp -R boot/* /mnt
sync
umount /mnt
# 拷贝rootfs进入第二个分区
mount 第二个分区路径 /mnt
cp -R root/* /mnt
sync
umount /mnt
开机测试
将SD卡安全拔出后插入设备,接入uart0后开机,可以看到U-Boot和Kernel的启动过程并顺利看到sh。
参考文档
https://blog.csdn.net/kencaber/article/details/107575210
https://linux-sunxi.org/Manual_build_howto
https://linux-sunxi.org/Mainline_Kernel_Howto
https://linux-sunxi.org/Manual_build_howto
https://linux-sunxi.org/U-Boot
文章评论