芯片启动的全过程大概是:Bootloader-Kernel-RootFS
对于我们这次实验来说,就是:uboot-linux kernel6.1.19-Buildroot
环境准备
本次实验宿主机使用全新的Ubuntu20.04环境,并在完成实验后用户目录下有以下结构的文件夹。
首先需要创建架构。
workspace
- linux
- partitions
-- boot
--- boot.scr
--- sun8i-v3s-licheepi-zero.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_Zero_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 0x43000000 sun8i-v3s-licheepi-zero.dtb
load mmc 0:1 0x42000000 zImage
bootz 0x42000000 - 0x43000000
接着编译配置文件。
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
我们需要修改arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts以启用以太网和USB支持。
/*
* Copyright (C) 2016 Icenowy Zheng <icenowy@aosc.xyz>
*
* This file is dual-licensed: you can use it either under the terms
* of the GPL or the X11 license, at your option. Note that this dual
* licensing only applies to this file, and not this project as a
* whole.
*
* a) This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Or, alternatively,
*
* b) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/dts-v1/;
#include "sun8i-v3s.dtsi"
#include "sunxi-common-regulators.dtsi"
/ {
model = "Lichee Pi Zero";
compatible = "licheepi,licheepi-zero", "allwinner,sun8i-v3s";
aliases {
serial0 = &uart0;
ethernet0 = &emac;
};
chosen {
stdout-path = "serial0:115200n8";
};
leds {
compatible = "gpio-leds";
blue_led {
label = "licheepi:blue:usr";
gpios = <&pio 6 1 GPIO_ACTIVE_LOW>; /* PG1 */
};
green_led {
label = "licheepi:green:usr";
gpios = <&pio 6 0 GPIO_ACTIVE_LOW>; /* PG0 */
default-state = "on";
};
red_led {
label = "licheepi:red:usr";
gpios = <&pio 6 2 GPIO_ACTIVE_LOW>; /* PG2 */
};
};
soc {
ehci0: usb@01c1a000 {
compatible = "allwinner,sun8i-v3s-ehci", "generic-ehci";
reg = <0x01c1a000 0x100>;
interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_EHCI0>, <&ccu CLK_BUS_OHCI0>;
resets = <&ccu RST_BUS_EHCI0>, <&ccu RST_BUS_OHCI0>;
status = "okay";
};
ohci0: usb@01c1a400 {
compatible = "allwinner,sun8i-v3s-ohci", "generic-ohci";
reg = <0x01c1a400 0x100>;
interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_EHCI0>, <&ccu CLK_BUS_OHCI0>,
<&ccu CLK_USB_OHCI0>;
resets = <&ccu RST_BUS_EHCI0>, <&ccu RST_BUS_OHCI0>;
status = "okay";
};
};
};
&mmc0 {
broken-cd;
bus-width = <4>;
vmmc-supply = <®_vcc3v3>;
status = "okay";
};
&uart0 {
pinctrl-0 = <&uart0_pb_pins>;
pinctrl-names = "default";
status = "okay";
};
&usb_otg {
dr_mode = "host";
status = "okay";
};
&usbphy {
usb0_id_det-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
status = "okay";
};
&emac {
allwinner,leds-active-low;
status = "okay";
};
接着执行以下指令。
# 编译内核,-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设置为cortex-a7 | 设置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://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
文章评论
你好,我按你的步骤编译uboot,发现uboot中以太网识别不了???
U-Boot SPL 2023.04-01131-gcaf0a88d9f-dirty (Apr 27 2023 - 08:05:04 -0700)
DRAM: 64 MiB
Trying to boot from FEL
U-Boot 2023.04-01131-gcaf0a88d9f-dirty (Apr 27 2023 - 08:05:04 -0700) Allwinner Technology
CPU: Allwinner V3s (SUN8I 1681)
Model: Lichee Pi Zero
DRAM: 64 MiB
Core: 32 devices, 14 uclasses, devicetree: separate
WDT: Not starting watchdog@1c20ca0
MMC: mmc@1c0f000: 0
Loading Environment from FAT... Card did not respond to voltage select! : -110
** Bad device specification mmc 0 **
In: serial@1c28000
Out: serial@1c28000
Err: serial@1c28000
Net: No ethernet found.
Hit any key to stop autoboot: 0
Card did not respond to voltage select! : -110
No ethernet found.
missing environment variable: pxeuuid
Retrieving file: pxelinux.cfg/00000000
No ethernet found.
Retrieving file: pxelinux.cfg/0000000
No ethernet found.
Retrieving file: pxelinux.cfg/000000
No ethernet found.
Retrieving file: pxelinux.cfg/00000
No ethernet found.
Retrieving file: pxelinux.cfg/0000
No ethernet found.
Retrieving file: pxelinux.cfg/000
No ethernet found.
Retrieving file: pxelinux.cfg/00
No ethernet found.
Retrieving file: pxelinux.cfg/0
No ethernet found.
Retrieving file: pxelinux.cfg/default-arm-sunxi-sunxi
No ethernet found.
Retrieving file: pxelinux.cfg/default-arm-sunxi
No ethernet found.
Retrieving file: pxelinux.cfg/default-arm
No ethernet found.
Retrieving file: pxelinux.cfg/default
No ethernet found.
Config file not found
No ethernet found.
No ethernet found.
xqeNB