复刻Planck_Pi笔记

介绍

全志F1C200s是全志的一款高度集成、低功耗的移动应用处理器,可用于多种多媒体音视频设备中

F1C200s基于ARM 9架构,芯片集成了SiP的DDR,外围电路可以极其简单;它支持高清视频解码,包括H.264、H.263、MPEG 1/2/4等,还集成了音频编解码器和I2S/PCM接口,是一款开发简单、性价比较高的产品,也适合用来做入门级的Linux开发板。

  1. F1Cxxxs芯片的上电启动顺序

芯片可以从SPI Flash或者SD-Card中启动,因为Flash容量较小可玩性不高,后文都是以SD卡启动为主的

参考:F1C100s启动时搜索SPI Flash的顺序?

  1. 上电后, f1c100s内部 BROM (芯片内置,无法擦除) 启动;

  2. 首先检查 SD0 有没有插卡, 如果有插卡就读卡 8k偏移数据,是否是合法的启动数据, 如果是BROM 引导结束, 否则进入下一步;

  3. 检测SPI0 NOR FLASH(W25QXXX, MX25LXXX) 是否存在, 是否有合法的启动数据, 如果是BROM 引导结束, 否则进入下一步;

  4. 检测SPI0 NAND FLASH 是否存在, 是否有合法的启动数据, 如果是BROM 引导结束, 否则进入下一步;

  5. 因为找不到任何可以引导的介质, 系统进入usb fel 模式, 可以用USB烧录了。

推荐直接使用我配置好的完整镜像,用Etcher等工具直接烧写到SD卡里即可以使用,方便又好用~

镜像的账户:

pi 密码:planck root 密码:planck 下面的教程是给需要自己配置uboot、内核、文件系统的人看的。

1. 配置编译环境

准备Docker开发环境 为了最小化编译环境,这里采用Docker构建ubuntu20.04镜像的方式来搭建环境。Docker 比虚拟机运行效率高的多

首先需要自己安装一下Docker,然后pull一下Ubuntu官方的Docker镜像到本地,选择版本为ubuntu:20.04:

docker pull ubuntu:20.04

实际操作中使用了我自己预先配置好的本地镜像(安装了nano、ssh等软件,更新了国内的apt源等)

然后启动容器:

docker run -it --name planck-pi-env --network host \
-p 8022:22 \
-v /home/pengzhihui/WorkSpace:/workspace \
--privileged \
ubuntu:20.04

编译过程中需要的依赖

进入容器之后执行apt update核apt upgrade更新软件,接下来安装依赖的软件包:

sudo apt update

apt-get install xz-utils nano wget unzip build-essential git bc swig libncurses5-dev libpython3-dev libssl-dev pkg-config zlib1g-dev libusb-dev libusb-1.0-0-dev python3-pip gawk bison flex

交叉编译工具链

编译工具链官网:https://www.linaro.org/

或Arm GNU Toolchain,以linaro为例:进入support->downloads可以看到下载页面,点击GNU cross-toolchain binary archives,可以进入对应下载列表,可以看到各个版本的toolchain,这里我使用的latest-7/arm-linux-gnueabi/即gcc-linaro-7.5.0-2019.12-x8664arm-linux-gnueabi即可。

下载

wget http://releases.linaro.org/components/toolchain/binaries/7.2-2017.11/arm-linux-gnueabi/gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabi.tar.xz

解压

mkdir /usr/local/arm 
tar -vxf gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabi.tar.xz -C /usr/local/arm

配置环境变量:

nano  ~/.bashrc

添加下面的变量:

PATH=$PATH:/usr/local/arm/gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabi/bin

使环境变量立即生效 :

source ~/.bashrc

查询版本,确认安装成功

arm-linux-gnueabi-gcc -v

注意:GCC版本要大于 6;此处为获取交叉编译链为7.2.1版本,也可以自行下载其他版本。

配置完成后可以commit容器到镜像方便未来部署:

sudo docker commit planck-pi-env planck-pi-env.image
sudo docker save -o planck-pi-env.image.tar planck-pi-env.image

tf卡分区

在TF卡上构建系统之前,需要将TF卡进行分区与格式化。

首先查看电脑上已插入的TF卡的设备号

fdisk -l 

若自动挂载了TF设备,先卸载(有多个分区则全部卸载):

sudo umount /dev/sdb1...

进行分区操作:

sudo fdisk /dev/sdb

操作步骤如下:

若已存分区即按 d 删除各个分区

分两个分区

boot    32M     FAT16
rootfs  --      EXT4

boot 分区存 u-boot linux 内核 和 文件树 rootfs 分区 存文件系统

通过 n 新建分区,第一分区暂且申请为32M用于储存uboot,和Linux内核,剩下的空间都给root-fs

第一分区操作:p 主分区、默认 1 分区、默认2048、+32M

n p [Enter] [Enter] [Enter] +32M

第二分区操作:p 主分区、3 分区、默认2048,剩下的全部分配

n p [Enter] [Enter] [Enter] [Enter]

w 保存写入并退出

分区格式化:

sudo mkfs.vfat /dev/sdb1 # 将第1分区格式化成FAT
sudo mkfs.ext4 /dev/sdb2 # 将第2分区格式化成EXT4

格式说明:

EXT4:只用于Linux系统的内部磁盘 NTFS:与Windows共用的磁盘 FAT:所有系统和设备共用的磁盘

也可以使用GParted等软件做图形化的操作

sudo apt-get install gparted -y

2. uboot

下载u-boot源码

这里使用荔枝派的 u-boot

git clone https://github.com/Lichee-Pi/u-boot.git -b nano-v2018.01
cd u-boot
//git branch -a
//git checkout nano-v2018.01

修改编译器工具

在uboot顶层Makefile的248行左右,添加默认编译器,就可以直接用make编译省去后面的参数了:

vim Makefile

ifeq ($(HOSTARCH),$(ARCH))
CROSS_COMPILE ?= 
endif

ARCH ?= arm
CROSS_COMPILE ?= arm-linux-gnueabi-

vim 显示行号命令 :set number

在uboot根目录进行编译配置为不带spi,来在根目录生成.config

make licheepi_nano_defconfig

图形化配置

make menuconfig
#Enable boot arguments
console=ttyS0,115200 panic=5 rootwait root=/dev/mmcblk0p2 earlyprintk rw
#bootcmd value
load mmc 0:1 0x80008000 zImage;load mmc 0:1 0x80c08000 suniv-f1c100s-licheepi-nano.dtb;bootz 0x80008000 - 0x80c08000;

回到uboot根目录进行编译

make -j4

确定已经生成了u-boot-sunxi-with-spl.bin文件

使用dd将u-boot-sunxi-with-spl.bin烧写进第一分区:

sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/sdb bs=1024 seek=8

注意:这里的bs=1024 seek=8是添加了8192字节的偏移,之所以要加8K偏移是因为FSBL也就是bootROM里面硬写死了会从设备的8K地址处加载SPL,然后进入uboot。因此上面烧写的时候,指定的偏移地址一定是相对于储存设备硬件的偏移,而不是相对于分区的偏移!

8K的来源是参考buildroot-mangopi-r/board/allwinner/generic/genimage-sdcard.cfg文件的描述offset = 0x2000。

是否单独划分一个uboot分区其实不重要,因为烧写的时候直接覆盖了

关于genimage的使用,可以参考billdroot官方的文档描述:The Buildroot user manual 。

对于boot分区完挂载之后直接把zImage和dtb文件放进去就行了,至于如何指定内核镜像和设备树所在分区,可以参考configs/uboot.env里面的配置,启动的时候相关参数是在这里被传递给内核的。

3. linux kernel

将下载的linux.tar.gz上传到虚拟机中。下载链接

提取码:f1g3

# 解压

tar -zxvf linux.tar.gz

进入源码文件夹

cd linux-nano-5.2-tf

编译

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j4

将zImage和suniv-f1c100s-licheepi-nano.dts复制到boot分区

对于内核的FAT分区,分区完挂载之后直接把zImage和dtb文件放进去就行了,至于如何指定内核镜像和设备树所在分区,可以参考configs/uboot.env里面的配置,启动的时候相关参数是在这里被传递给内核的

4 rootfs

由于F1C200s的RAM只有64M,无法支持像是Ubuntu-Core这样的文件系统(最低RAM需求512M),所以一般只能用buildroot来生成简单的文件系统,或者裸机开发。

但是为了方便地使用Debian系的丰富软件,我们可以自己构建Debian最小系统,最小rootfs在180MB左右。

安装构建文件系统的工具主要有两个:

  • 一个是qemu用来模拟ARM9的芯片架构,基于qemu模拟器可以在x86的宿主机上通过chroot切换到ARM环境然后完成root-fs的各种配置。

  • 一个是debootstrap ,用来构建Debian文件系统。

配置构建环境

运行下面的命令安装软件:

apt install qemu-user-static  
apt install debootstrap  

注意:上述软件都是需要在安装了交叉编译环境的Docker容器下运行的或者你的linux虚拟机,否则编译出来的文件系统上版运行的时候会报格式错误

构建Debian文件系统

构建文件系统之前,需要知道我们想要构建哪个版本的文件系统,这里从Debian 全球镜像站选择访问速度快的源,这里使用华为源:mirrors.huaweicloud.com。

注意:选择的源需要支持硬件架构armel,因为F1Cxxxs是armel架构的芯片。

关于不同架构的区别:

armel:arm eabi little endian的缩写,针对旧的 32 位 ARM 处理器,而不支持硬件浮点单元(FPU)

armhf:arm hard float的缩写,仅适用于较新的 32 位 ARM 处理器,其至少实现了 ARMv7 架构,且支持 ARM 矢量浮点规范(VFPv3)第 3 版

arm64:适用于 64 位 ARM 处理器,64位的arm默认就是hf的,其至少实现了 ARMv8 架构

然后就是debian的版本,使用最新的buster:

debootstrap是debian/ubuntu下的一个工具,用来构建一套基本的系统(根文件系统)。生成的目录符合Linux文件系统标准(FHS)

mkdir rootfs
cd rootfs
# 构建文件系统 从华为源下载
sudo debootstrap --foreign --verbose --arch=armel  buster rootfs-debian http://mirrors.huaweicloud.com/debian/

cd rootfs-debian
# 挂载
mount --bind /dev dev/
mount --bind /sys sys/
mount --bind /proc proc/
mount --bind /dev/pts dev/pts/

cd ..

cp /usr/bin/qemu-arm-static rootfs-debian/usr/bin/
chmod +x rootfs-debian/usr/bin/qemu-arm-static
LC_ALL=C LANGUAGE=C LANG=C chroot rootfs-debian /debootstrap/debootstrap --second-stage --verbose
LC_ALL=C LANGUAGE=C LANG=C chroot rootfs-debian

注意:前文启动Docker容器的时候,一定要加--privileged参数,否则上面mount指令会报权限错误。

配置文件系统

通过下面的命令进入chroot环境:

LC_ALL=C LANGUAGE=C LANG=C chroot rootfs-debian

上面最后一条命令chroot完成,此时可以用apt-get等命令给文件系统安装需要的软件包,修改root登录密码等操作

apt install net-tools usbutils ssh

passwd root
# 修改密码

nano /etc/ssh/sshd_config
# 添加SSH权限,修改为PermitRootLogin yes

可能会出现无法使用方向键的问题,输入bash命令进入bash窗口即可。

打包文件。

当所有的内容制作完成,就可以清理缓存,打包之后就可以替换你的文件系统了

apt clean
exit  #退出chroot
sudo rm rootfs-debian/usr/bin/qemu-arm-static

卸载刚在挂载的文件夹。

cd rootfs-debian
//sudo umount   dev/pts/
sudo umount   dev/
//sudo umount   sys/
//sudo umount   proc/
//sudo umount   dev/pts/

把文件系统并复制到 SD 卡的 rootfs 分区

sudo tar -cvf ../rootfs.tar .    #要注意那个.  代表当前目录rootfs-debian
cd ..
sudo cp rootfs.tar /media/ly/rootfs     #拷贝到 rootfs 分区 ly换成你的用户名 
cd /media/ly/rootfs 
sudo tar -xvf rootfs.tar
sudo rm rootfs.tar

planckpi操作

通过串口连接pc进行操作,使用串口工具可以看到 pi 的启动信息

通过串口完成以下操作

修改主机名

HOSTNAME=lycraftpi          #lycraftpi可以换成别的名字
echo $HOSTNAME > /etc/hostname
echo $HOSTNAME > /proc/sys/kernel/hostname
sed -i '/localhost/s/$/\t'"$HOSTNAME"'/g' /etc/hosts
# 查看Debian版本号
cat /etc/os-release

启用swap

芯片的SiP内存只有64MB,大部分情况下都不够用,所以需要开启swap使用内存卡的一部分空间来作为交换内存。

通过free -m来查看下内存使用状况:

# free -m
              total        used        free      shared  buff/cache   available
Mem:             54          15           6           0          31          34
Swap:             0           0           0

创建一个自定义的目录 /opt/images/:

mkdir /opt/images/
rm -rf /opt/images/swap

创建一个需要内存大小的文件,如512M:

dd if=/dev/zero of=/opt/images/swap bs=1M count=512

把创建的文件变成SWAP分区并启用:

mkswap /opt/images/swap #mkswap可将磁盘分区或文件设为Linux的交换区
swapon /opt/images/swap #swapon命令用于激活Linux系统中交换空间

Linux系统的内存管理必须使用交换区来建立虚拟内存

free -m看看SWAP是否生效,ok的话设置开机自动挂载swap:

nano /etc/fstab

添加一行:
/opt/images/swap swap swap defaults 0 0

配置USB虚拟网卡永久静态ip

vim /etc/network/interfaces

# 添加以下内容  
allow-hotplug usb0
auto usb0
iface usb0 inet static
address 192.168.2.100
netmask 255.255.255.0
gateway 192.168.2.1

# 这里网段是可以修改的,但是要和虚拟机一个网段

# 启用网卡
ifup usb0

# 开机自启
vim /etc/init.d/rcS

# 添加以下内容
ifup lo
ifup usb0

配置DNS

vim /etc/resolv.conf
# 在nameserver下添加
nameserver 223.5.5.5        #阿里的DNS

增加开机自启脚本

文件系统中的/etc/init.d负责linux的服务的开启和关闭等,为了能使系统开机自动运行一些脚本和命令,这里介绍如何新添加一个自启动项。

首先我们创建一个文件/etc/init.d/runOnBoot,内容如下:

#!/bin/sh /etc/init.d/runOnBoot
### BEGIN INIT INFO
# Provides: runOnBoot Required-Start: $local_fs $syslog $network
# Required-Stop: $local_fs $syslog $network Default-Start: 2 3 4 5
# Default-Stop: 0 1 6 Short-Description: runOnBoot startup Description:
# runOnBoot auto startup 1.0
### END INIT INFO

#------------------------------------------------------------------------------
swapon /opt/images/swap

mkdir /sys/kernel/config/usb_gadget/gg
cd /sys/kernel/config/usb_gadget/gg
echo "0x0502" > idVendor
echo "0x3235" > idProduct
mkdir functions/rndis.rn0
mkdir configs/c1.1
ln -s functions/rndis.rn0 configs/c1.1/
echo "musb-hdrc.1.auto" > UDC
ifconfig usb0 192.168.137.2
ifconfig usb0 up
route add default gw 192.168.137.1


# Demo to run a script ↓
# script_path=/home/start.sh
# if [ ! -r ${script_path} ]; then
#     echo ${script_path} not existing;
# fi
# . ${myStart_spaddr}

#------------------------------------------------------------------------------

给文件添加可执行权限:

chmod +x /etc/init.d/runOnBoot

最后要添加软链接:

ln -s /etc/init.d/runOnBoot /etc/rc2.d/S99runOnBoot

/etc/rc.d/rc0.d/~/etc/rc.d/rc6.d/文件夹的含义不同,S开头代表是开启时处理的脚本,按照后面紧跟的数字进行按顺序启动,S99则是最后进行启动。

linux虚拟机ssh连接pi

通过虚拟机设置 pi 的IP 地址

sudo vim /etc/network/interfaces

#添加以下内容
allow-hotplug ens35u1
auto ens35u1
iface ens35u1 inet static
address 192.168.2.1
netmask 255.255.255.0

#重启下

#输入以下指令后planckpi就可以上网了
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward > /dev/null
sudo iptables -P FORWARD ACCEPT
sudo iptables -A POSTROUTING -t nat -j MASQUERADE -s 192.168.2.0/24

接下来通过ssh连接到planckpi玩耍吧

ssh root@192.168.2.100

ping www.baidu.com

文档信息

版权声明:可自由转载(请注明转载出处)-非商用-非衍生

发表时间:2025年8月12日 11:29