Cubieboard2(二) 系统构建 —— 基于 linux-sunxi
前言
参考文章
- (一)工具安装:https://blog.csdn.net/wb4916/article/details/72898266
- (二)代码下载:https://blog.csdn.net/wb4916/article/details/72898747
- (三)Debian 基础系统配置:https://blog.csdn.net/wb4916/article/details/72899191
- (四)编译组件:https://blog.csdn.net/wb4916/article/details/72900725
- (五)建立 ROOTFS:https://blog.csdn.net/wb4916/article/details/72916692
其它参考
- ubuntu:https://old-releases.ubuntu.com/releases/
- http://releases.linaro.org/components/toolchain/binaries/
- https://github.com/peng-zhihui/Planck-Pi
摘要
整体来说,大致的过程为,嵌入式设备上电后将执行 bootloader,对硬件进行硬件和堆栈初始化,然后搬运内核到 RAM 中并启动内核,紧接着挂载根文件系统。
- 本文在 Ubuntu22.04 的 Linux 上为 Cubieboard2 构建一个基于 armhf 的 Debian Linux,包括 SPL、U-BOOT、内核(Kernel)、根系统(ROOTFS)。
1 环境准备
mkdir -p ~/cubieboard2/chroot-armhf # 创建目录
WORK_DIR=~/cubieboard2 # 工作目录
ROOTFS_DIR=${WORK_DIR}/chroot-armhf # 目标系统 rootfs 目录
1.1 下载必须的工具软件
sudo apt-get install build-essential libncurses5-dev u-boot-tools \
qemu-user-static debootstrap git binfmt-support \
libusb-1.0-0-dev pkg-config gcc-arm-linux-gnueabihf
1.2 下载源码
# 由于 github 仓库的网速过慢,这里使用 gitee 的同步仓库
cd $WORK_DIR
# 下载 lichee/内核
git clone https://gitee.com/luyaocf/linux-sunxi.git -b cubie/sunxi-3.4
tar -czvf linux-sunxi_cb2_`date +%Y%m%d_%H%M%S`.tar.gz linux-sunxi/
# 下载 uboot
git clone https://gitee.com/luyaocf/u-boot-sunxi.git -b cubie/sunxi
tar -czvf u-boot-sunxi_cb2_`date +%Y%m%d_%H%M%S`.tar.gz u-boot-sunxi/
# sunxi-tools master 分支
git clone https://gitee.com/luyaocf/sunxi-tools.git
tar -czvf sunxi-tools_cb2_`date +%Y%m%d_%H%M%S`.tar.gz sunxi-tools/
# sunxi-boards master 分支
git clone https://gitee.com/luyaocf/sunxi-boards.git
tar -czvf sunxi-boards_cb2_`date +%Y%m%d_%H%M%S`.tar.gz sunxi-boards/
建议这里给虚拟机拍摄一个快照,因为接下来配置源需要多次尝试
1.3 下载并配置 Debian 基础系统
cd $ROOTFS_DIR
##/ man debootstrap :
# --no-check-gpg :Disables checking gpg signatures of retrieved Release files.
# 从 man 的示例 “debootstrap stretch ./stretch-chroot http://deb.debian.org/debian” 可知:
# 这里允许自定义下载源,官方的地址已经不支持 wheezy 版本,这里通过指定阿里源来指定 debian 版本为最新的 fullseye
#/
debootstrap --foreign --no-check-gpg --arch armhf bullseye . http://mirrors.aliyun.com/debian/
cd $ROOTFS_DIR && sudo cp /usr/bin/qemu-arm-static usr/bin/
LC_ALL=C LANGUAGE=C LANG=C chroot . /debootstrap/debootstrap --second-stage
2 编译组件
2.1 编译 u-boot
这里使用 ubuntu 22.04 版本,其默认的 gcc-arm-linux-gnueabihf 版本为 11.2.0
# 卸载原来的工具链
apt-get remove gcc-arm-linux-gnueabi*
# 下载工具链
wget https://releases.linaro.org/components/toolchain/binaries/4.9-2016.02/arm-linux-gnueabihf/gcc-linaro-4.9-2016.02-x86_64_arm-linux-gnueabihf.tar.xz
# 解压
mkdir /usr/local/arm
tar -vxf gcc-linaro-4.9-2016.02-x86_64_arm-linux-gnueabihf.tar.xz -C /usr/local/arm
# 配置环境变量,在 /root/.bashrc 文件中添加:
export PATH=$PATH:/usr/local/arm/gcc-linaro-4.9-2016.02-x86_64_arm-linux-gnueabihf/bin
# 使生效
. ~/.bashrc
# 测试
-> arm-linux-gnueabihf-gcc -v
Using built-in specs.
COLLECT_GCC=arm-linux-gnueabihf-gcc
......
gcc version 4.9.4 20151028 (prerelease) (Linaro GCC 4.9-2016.02)
2.1.1 u-boot-sunxi 分支
# git branch -a
cubie/sunxi # make 过程报错
lichee-dev # 无 cubieboard2
lichee-dev-a20 # 无 cubieboard2
lichee/lichee-dev # 无 cubieboard2
lichee/lichee-dev-ICS # 无 cubieboard2
lichee/lichee-dev-mmc # 无 cubieboard2
old/sunxi-current # make 过程报错
sunxi # make 过程报错
wip/a20 # make 过程报错
# git checkout cubie/sunxi
# 这里选择 cubie/sunxi 分支
2.1.2 编译 U-boot
cd $WORK_DIR/u-boot-sunxi
# 清空
sudo make distclean CROSS_COMPILE=arm-linux-gnueabihf-
# 编译
sudo make cubieboard2 CROSS_COMPILE=arm-linux-gnueabihf-
-
错误 1:arm-linux-gnueabihf-gcc: error: unrecognized -march target: armv5
- 通过 grep -rn "armv5" 找到所有包含 “armv5” 的地方,其中 arch/arm/cpu/armv7/config.mk:11 处有如下内容,说明这里可以把 armv5 修改为 armv7-a
# If armv7-a is not supported by GCC fall-back to armv5, which is # supported by more tool-chains PF_CPPFLAGS_ARMV7 := $(call cc-option, -march=armv7-a, -march=armv5)
- 通过查找,cubieboard2 的 CPU 架构确实是 “ARMv7 Cortex-A7”
-
错误2:compiler-gcc.h:93:1: fatal error: linux/compiler-gcc11.h: 没有那个文件或目录
# 这里将内核文件夹 include/linux 下的 compiler-gcc3.h 或 compiler-gcc4.h 拷贝为 compiler-gcc11.h cp include/linux/compiler-gcc3.h include/linux/compiler-gcc11.h
2.2 编译 sunxi-tools
-
sunxi-tools 提供了 fexc、nand-part 等工具,在系统安装、定制的过程中可能会用到,所以可以先编译它们。
-
因为这些工具常常在宿主系统上(x86-64 Ubuntu Linux)来针对目标设备、目标系统运行,所以可以把它们编译为x86-64的可执行文件。
-
编译:
cd $WORK_DIR/sunxi-tools
make
2.3 配置、编译内核
2.3.1 拷贝预设内核配置文件
# 切换到内核代码目录
cd $WORK_DIR/linux-sunxi/
# 复制配置文件
cp arch/arm/configs/sun7i_defconfig .config
2.3.2 配置内核
- 打开配置图形化界面:
cp .config bak1_orig.config
make ARCH=arm menuconfig
cp .config bak2_soloforce.config
- 具体配置项:
- *,表示该驱动将作为内核的一部分被编译进内核映像中。
- M,则表示该驱动将作为一个独立的模块编译,并且可以在需要时通过 insmod 或 modprobe 加载。
- 推荐除自定义模块外,所有项前面需要修改为选中 <*>
说明 |
第一级 |
第二级 | 第三级 | 第四级 | 第五级 |
---|---|---|---|---|---|
无线网络 | Networking support | Wireless | Generic IEEE 802.11 Networking Stack (mac80211) | ||
SATA | Device Drivers | Serial ATA and Parallel ATA drivers | SoftWinner Platform AHCI SATA support | ||
Tun/Tap | Device Drivers | Network device support | Universal TUN/TAP device driver support | ||
USB 网卡 | Device Drivers | Network device support | Wireless LAN (NEW) | Ralink driver support | |
红外线 | Device Drivers | Input device support | Keyboards (NEW) | sunxi IR support (NEW) | |
GPIO | Device Drivers | GPIO Support | GPIO Support for sunxi platform | ||
错误 | Device Drivers | Hardware Monitoring support | |||
摄像头 | Device Drivers | Multimedia support | Video capture adapters (NEW) | V4L USB devices (NEW) | USB Video Class (UVC) |
HDMI | Device Drivers | Graphics support | Support for frame buffer devices | HDMI Driver Support(sunxi) | |
USB串口 | Device Drivers | USB support(NEW) | USB Serial Converter support | USB Prolific 2303 Single Port Serial Driver |
2.3.3 编译内核
# 备份
cp .config bak_`date +%Y%m%d_%H%M%S`.config
# 编译
make -j12 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- uImage modules
- 编译完成后,得到内核文件:
ll arch/arm/boot/uImage
2.3.4 发掘更多的可用内存
3 建立 ROOTFS
3.1 ROOTFS 配置
cd $WORK_DIR/chroot-armhf
chroot . passwd
echo "Cubieboard2" > etc/hostname && cat etc/hostname
echo "127.0.0.1 Cubieboard2" >> etc/hosts && cat etc/hosts
# 安装内核镜像
cp ../linux-sunxi/arch/arm/boot/uImage boot/
make -C ../linux-sunxi INSTALL_MOD_PATH=. ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules_install
# 初始化 inittab 文件
echo T0:2345:respawn:/sbin/getty -L ttyS0 115200 vt100 >> etc/inittab && cat etc/inittab
# 初始化 sources.list 文件
vi etc/apt/sources.list
cat etc/apt/sources.list
chroot . apt-get update
chroot . apt-get upgrade
chroot . apt-get install openssh-server locales wireless-tools wpasupplicant vim lrzsz net-tools firmware-ralink
echo "en_US.UTF-8 UTF-8" > etc/locale.gen
echo "zh_CN.UTF-8 UTF-8" >> etc/locale.gen
chroot . locale-gen
# 到此为止,Debian 基础系统已经配置好了;现在可以把 $ROOTFS_DIR 保存为一个压缩包,以备日后之用。
cd ../ && sudo tar -czvf chroot-armhf_cb2_`date +%Y%m%d_%H%M%S`.tar.gz chroot-armhf/
3.2 更新为阿里源
deb http://mirrors.aliyun.com/debian/ bullseye main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ bullseye main non-free contrib
deb http://mirrors.aliyun.com/debian-security/ bullseye-security main
deb-src http://mirrors.aliyun.com/debian-security/ bullseye-security main
deb http://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib
deb http://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib
3.3 etc/inittab 文件内容
# /etc/inittab: init(8) configuration.
# $Id: inittab,v 1.91 2002/01/25 13:35:21 miquels Exp $
# The default runlevel.
id:2:initdefault:
# Boot-time system configuration/initialization script.
# This is run first except when booting in emergency (-b) mode.
si::sysinit:/etc/init.d/rcS
# What to do in single-user mode.
~~:S:wait:/sbin/sulogin
# /etc/init.d executes the S and K scripts upon change
# of runlevel.
#
# Runlevel 0 is halt.
# Runlevel 1 is single-user.
# Runlevels 2-5 are multi-user.
# Runlevel 6 is reboot.
l0:0:wait:/etc/init.d/rc 0
l1:1:wait:/etc/init.d/rc 1
l2:2:wait:/etc/init.d/rc 2
l3:3:wait:/etc/init.d/rc 3
l4:4:wait:/etc/init.d/rc 4
l5:5:wait:/etc/init.d/rc 5
l6:6:wait:/etc/init.d/rc 6
# Normally not reached, but fallthrough in case of emergency.
z6:6:respawn:/sbin/sulogin
# What to do when CTRL-ALT-DEL is pressed.
ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
# Action on special keypress (ALT-UpArrow).
#kb::kbrequest:/bin/echo "Keyboard Request--edit /etc/inittab to let this work."
# What to do when the power fails/returns.
pf::powerwait:/etc/init.d/powerfail start
pn::powerfailnow:/etc/init.d/powerfail now
po::powerokwait:/etc/init.d/powerfail stop
# /sbin/getty invocations for the runlevels.
#
# The "id" field MUST be the same as the last
# characters of the device (after "tty").
#
# Format:
# <id>:<runlevels>:<action>:<process>
#
# Note that on most Debian systems tty7 is used by the X Window System,
# so if you want to add more getty's go ahead but skip tty7 if you run X.
#
1:2345:respawn:/sbin/getty 38400 tty1
2:23:respawn:/sbin/getty 38400 tty2
3:23:respawn:/sbin/getty 38400 tty3
4:23:respawn:/sbin/getty 38400 tty4
5:23:respawn:/sbin/getty 38400 tty5
6:23:respawn:/sbin/getty 38400 tty6
# Example how to put a getty on a serial line (for a terminal)
#
#T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100
#T1:23:respawn:/sbin/getty -L ttyS1 9600 vt100
# Example how to put a getty on a modem line.
#
#T3:23:respawn:/sbin/mgetty -x0 -s 57600 ttyS3
4 烧录
4.1 准备工作
- 1)工作目录
WORK_DIR=~/cubieboard2
ROOTFS_DIR=${WORK_DIR}/chroot-armhf
- 2)准备工具
- (1)uboot
$WORK_DIR/u-boot-sunxi/u-boot-sunxi-with-spl.bin
- (2)kernel
$WORK_DIR/linux-sunxi/arch/arm/boot/uImage
- (3)boot.scr
$WORK_DIR/boot.scr
- (4)script.bin
$WORK_DIR/sunxi-boards/sys_config/a20/script.bin
- (5)rootfs
$WORK_DIR/chroot-armhf.tar.gz
4.2 烧写
4.2.1 分区
ll /dev/sd* # 查看分区名称,一般为 sdb
card=/dev/sdb
dd if=/dev/zero of=${card} bs=1M count=1 # dd if=<输入文件> of=<输出文件> bs=<块大小> count=<块数>
sfdisk -r ${card} # 分区排序
fdisk ${card} # 操作分区
d # 删除旧分区
n [Enter] [Enter] [Enter] +64M # 创建分区 1
n [Enter] [Enter] [Enter] [Enter] # 创建分区 2
t 1 c w # 指定分区类型
# 格式化分区 1、2
mkfs.vfat ${card}1
mkfs.ext4 ${card}2
4.2.2 写入 bootloader
cd $WORK_DIR/u-boot-sunxi
dd if=u-boot-sunxi-with-spl.bin of=$card bs=1024 seek=8
4.2.3 烧写其它内容
- 1)分区 1 中写入内核 uImage、script.bin、boot.scr:
mount ${card}1 /mnt
mkdir /mnt/boot
# 安装内核 uImage
cp $WORK_DIR/linux-sunxi/arch/arm/boot/uImage /mnt/boot
# 安装 script.bin
cp $WORK_DIR/sunxi-boards/sys_config/a20/script.bin /mnt/boot
# 安装 boot.scr
cp $WORK_DIR/boot.scr /mnt/
sync && umount /mnt
- 2)分区 2 中写入文件系统:
# 安装 rootfs
mount ${card}2 /mnt
cp $WORK_DIR/chroot-armhf.tar.gz /mnt/
tar -zxvf chroot-armhf.tar.gz
sync && umount /mnt
4.2.4 烧写结果
lsb_release -a # 查看 ubuntu 版本
cat /etc/issue # 查看 ubuntu 版本
cat /etc/debian_version # ubuntu 下查看 debian 版本
cat /etc/os-release # 查看系统详情
后记
于 2022-08-07:
重试了多次,上述过程无法正常启动系统。
最终,使用官方的 uboot 与 内核,只将根文件系统 chroot-armhf.tar.gz 解压到 /dev/sdb2 下后成功,且系统为 debian 11。