Cubieboard2(二) 系统构建 —— 基于 linux-sunxi

前言

参考文章

其它参考

摘要

整体来说,大致的过程为,嵌入式设备上电后将执行 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)
    
  • 错误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。

posted @ 2024-09-16 00:51  送南阳马生序  阅读(9)  评论(0编辑  收藏  举报