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”
      • 参考:https://archlinuxarm.org/platforms/armv7/allwinner/cubieboard-2
  • 错误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
    
    • 参考:https://blog.csdn.net/p1279030826/article/details/113931568

2.2 编译 sunxi-tools

  • sunxi-tools 提供了 fexc、nand-part 等工具,在系统安装、定制的过程中可能会用到,所以可以先编译它们。

  • 因为这些工具常常在宿主系统上(x86-64 Ubuntu Linux)来针对目标设备、目标系统运行,所以可以把它们编译为x86-64的可执行文件。

  • 编译:

cd $WORK_DIR/sunxi-tools
make

2.3 配置、编译内核

  • 其它参考:https://blog.csdn.net/CNflysky/article/details/125417838
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 supportWirelessGeneric IEEE 802.11 Networking Stack (mac80211)
SATADevice DriversSerial ATA and Parallel ATA driversSoftWinner Platform AHCI SATA support
Tun/TapDevice DriversNetwork device supportUniversal TUN/TAP device driver support
USB 网卡Device DriversNetwork device supportWireless LAN (NEW)Ralink driver support
红外线Device DriversInput device supportKeyboards (NEW)sunxi IR support (NEW)
GPIODevice DriversGPIO SupportGPIO Support for sunxi platform
错误Device DriversHardware Monitoring support
摄像头Device DriversMultimedia supportVideo capture adapters (NEW)V4L USB devices (NEW)USB Video Class (UVC)
HDMIDevice DriversGraphics supportSupport for frame buffer devicesHDMI Driver Support(sunxi)
USB串口Device DriversUSB support(NEW)USB Serial Converter supportUSB 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

  • 参考:https://blog.csdn.net/CNflysky/article/details/125467518

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/<font color=red>u-boot-sunxi-with-spl.bin</font>

- (2)kernel
$WORK_DIR/linux-sunxi/arch/arm/boot/<font color=red>uImage</font>

- (3)boot.scr
$WORK_DIR/<font color=red>boot.scr</font>

- (4)script.bin
$WORK_DIR/sunxi-boards/sys_config/a20/<font color=red>script.bin</font>

- (5)rootfs
$WORK_DIR/<font color=red>chroot-armhf.tar.gz</font>

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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值