f1c100s编译启动所需的uboot,kernel,rootfs
https://github.com/Icenowy/linux.git 有f1c100s-480272lcd-test和f1c100s分支, 然后自己手动修复一个 USB 问题,驱动就比较全了
https://github.com/Lichee-Pi/linux.git 有nano-4.14-exp和nano-5.2-flash分支,用哪个合适
个人画了块没有连接任何其他模块的F1C100S开发板,没有链接任何外设,本文是编译所有启动所需的三大件。(只要编译出三个东西复制到sd卡就可启动,不需要制作成镜像img文件)
环境:使用安装了ubuntu18的电脑进行编译。以及准备了一张128M的内存卡,提前分好两个区,分区1大小20M,为fat32格式,分区2为剩余的所有空间,是ext4格式。
镜像三大件
一个可供启动运行使用的linux镜像,包含3大部分,bootloader,linux kernel,root file system。需要使用3个开源项目进行编译,uboot(bootloader),最伟大的linux,buildroot(root file system)。
bootlader是上电后第一个被调出来运行的程序,他负责初始化芯片的各种外设并引导linux内核运行,还能实现一些如联网下载linux内核更新等骚操作。
kernel,linux内核,由那个史上最伟大的开源项目编译而成,linux操作系统的本体。
root file system简称rootfs,虽然名字叫文件系统,但跟NTFS FAT32那种文件系统不是一个东西。在linux中的作用相当于windows下的c盘。是一堆文件夹与文件的集合体,xxx路径下存放着可供执行的指令,xx路径是用于存放linux运行时产生的数据等,这一坨文件夹以及内部的各种文件统称为rootfs,如果要在板子上使用python vim git等软件,都是要将那些软件编译后存放到rootfs里。
下载所需工具/项目
1.安装后续会使用到的软件
如果编译时遇到报错xxx命令not found,那就是对应的程序没安装,用apt指令安装即可。
sudo apt-get install gcc g++ make python-dev python3-dev git swig net-tools ssh sed binutils build-essential apt-utils ncurses-base bison flex nfs-kernel-server chrpath gawk texinfo cvs file cpio w3m asciidoc dblatex asciidoc-dblatex graphviz -y
2.安装易缺少的库。
如果编译时遇到报错xxx.h文件不能打开,那就是缺少lib库文件,用apt指令安装即可。
sudo apt-get install diffstat libsdl1.2-dev libc6-i386 lib32stdc++6 lib32z1 libssl-dev libncurses5-dev -y
3.安装交叉编译器
在x86架构的电脑上,编译要在arm架构中运行的程序,需要使用交叉编译器编译
sudo apt-get install gcc-arm-linux-gnueabi gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf -y
4.uboot项目(官方)
git clone https://github.com/u-boot/u-boot.git
5.linux项目(官方)
那个史上最伟大的开源项目linux(这链接是国内的镜像下载站)
wget http://ftp.sjtu.edu.cn/sites/ftp.kernel.org/pub/linux/kernel/v5.x/linux-5.2.tar.gz
解压刚刚下载的linux项目
tar -zxvf linux-5.2.tar.gz
6.buildroot项目(官方)
用于编译rootfs的
git clone https://github.com/buildroot/buildroot.git
编译uboot
首先进入uboot项目的文件夹。
1.声明交叉编译器
export CROSS_COMPILE=arm-linux-gnueabi-
2.载入配置
所有配置文件都存储于configs文件夹下,大部分芯片厂商都会把自己芯片的配置文件贡献进来,但全志没有。我们使用其中名为licheepi_nano_defconfig的,由荔枝派贡献的配置文件。
make ARCH=arm licheepi_nano_defconfig
-前几步的操作如下图-
3.进menuconfig改点配置
按照荔枝派设计的流程,接下来需要创建一个文件,填入一些参数,调用脚本单独编译那个文件。太麻烦,这里我选择直接将那些参数通过menuconfig写入编译配置。
用命令进入menuconfig
make ARCH=arm menuconfig
menuconfig的操作方法:上下键在竖向选项间移动,左右键控制下面横向选项移动,回车执行横向的选项,按两下esc键返回,按空格选择启用选项。
1)启用boot arguments
将光标移动到Enable boot arguments,按空格启用(左边[]变成[*]就是启用)。下面就会冒出个Boot arguments的选项
-操作如下图-
2)修改Boot arguments
光标移动到Boot arguments,按回车进入修改。 将下面这一串复制进去,然后按回车ok。
console=ttyS0,115200 panic=5 rootwait root=/dev/mmcblk0p2 earlyprintk rw
console:指定控制台为串口0,波特率115200
root:指定rootfs位置
rw:设置rootfs可读写
-操作如下图-
3)修改bootcmd value
光标移动到bootcmd value,按回车进入修改
-位置如下图-
将其内容修改为下面这一串
load mmc 0:1 0x80008000 zImage; load mmc 0:1 0x80c08000 suniv-f1c100s-licheepi-nano.dtb; bootz 0x80008000 - 0x80c08000;
这段东西的含义是:
load mmc 0:1 0x80008000 zImage; 将mmc0的分区1中名为“zImage”的文件加载到内存的0x80008000位置
load mmc 0:1 0x80c08000 suniv-f1c100s-licheepi-nano.dtb; 将mmc0的分区1中名为“xxx.dtb”的文件加载到内存的0x80c08000位置
bootz 0x80008000 - 0x80c08000; 从内存的这个区域启动linux
-操作如下图-
4)修改完成,退出
修改完成后,按两下esc键,会弹出是否保存的询问,选择yes按回车。
-完成修改后如下图-
4.编译
使用make编译。uboot是三大件里编译最快的(
make ARCH=arm
make默认使用单线程,如果想用多线程加快速度,如8线程编译,可以在后面加上-j8,如
make ARCH=arm -j8
5.目标文件烧录
编译完成后,会在当前目录下生成一个u-boot-sunxi-with-spl.bin文件。我们需要将此文件烧录进sd卡的8k偏移处,这个位置写死在芯片内部,上电时会从这个位置调出uboot来运行。
使用dd指令来烧录,示例如下:
sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/sdb bs=1k seek=8
编译linux kernel
首先进入刚刚下载的linux5.2项目的文件夹。
我们需要编译出一个内核zImage文件,与一个设备树文件(驱动会根据设备树的内容去配置芯片外设,如设置mmc,串口初始化等)。
正常情况下应该由厂商提供一个配置文件,但全志没有。这里我们调用荔枝派大佬所编写的配置文件。
1.下载文件
为了方便本文读者,我去荔枝派的开源资料里把那几个所需文件找了出来,并放在我自己的github里,用下面的链接就可以下载(linux主线里有荔枝派贡献的设备树,但版本太老,一些东西没开启)
下载荔枝派的配置文件.config及两个设备树文件
wget https://raw.githubusercontent.com/orange2c/public/main/f1c100s/licheepi-kernel/.config wget https://raw.githubusercontent.com/orange2c/public/main/f1c100s/licheepi-kernel/suniv-f1c100s.dtsi wget https://raw.githubusercontent.com/orange2c/public/main/f1c100s/licheepi-kernel/suniv-f1c100s-licheepi-nano.dts
2.处置下载的文件
.config文件存放到linux5.2项目的文件夹下,两个设备树文件就移动到arch/arm/boot/dts路径
mv suniv-f1c100s.dtsi arch/arm/boot/dts/ mv suniv-f1c100s-licheepi-nano.dts arch/arm/boot/dts/
3.进一次menuconfig
我们需要先进一次menuconfig,不需要修改东西,只是要触发一下设置流程,让他将我们刚刚下载进来的.config文件更新一下。
make ARCH=arm menuconfig
这个menuconfig界面可以用来启用或关闭一些内核功能。但我们现在不做任何操作。按两次esc键退出menuconfig,记得在弹出询问是否保存的界面时选择yes后按回车
4.声明交叉编译器
makefile脚本通过环境变量CROSS_COMPILE来控制要使用的交叉编译器,这个变量不填就是用gcc编译。我们要使用arm-linux-gnueabi-gcc来编译,只要把除了gcc三个字母的那部分前缀赋给这个变量就行。
export CROSS_COMPILE=arm-linux-gnueabi-
5.开始编译
我使用4线程来编译内核镜像,耗时约几分钟
make ARCH=arm -j4
还有设备树需要编译,这个的编译就比较快了。不需要多线程,才几个文件
make ARCH=arm dtbs
6.处置编译出的目标文件
我们需要的是arch/arm/boot路径下的zImage,和arch/arm/boot/dts路径下的suniv-f1c100s-licheepi-nano.dtb。
我们刚刚在uboot内已经指定了文件名和存储位置,这两个文件只要复制到sd卡的分区1内即可。例如我的操作是:
sudo mount /dev/sdb1 /mnt/ #挂载sd卡分区1到电脑/mnt路径 sudo cp arch/arm/boot/zImage /mnt/ sudo cp arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dtb /mnt/ sudo umount /mnt/
编译rootfs
我们使用buildroot来编译rootfs。你想在开发板使用的所有软件如vim gcc python等,都是在这个项目的配置菜单里启用,并编译进去。
rootfs只要芯片架构的设置一样就可使用,所以这里我们使用默认配置,然后手动修改涉及芯片架构的部分。不添加任何软件,不新增对xx功能的支持。
1进入menuconfig
make menuconfig
menuconfig的操作方法:上下键在竖向选项间移动,左右键控制下面横向选项移动,回车执行横向的选项,按两下esc键返回,按空格选择启用选项。
2.修改选项
首先按回车进入第一个Target options的选项,这里是设置编译的目标芯片架构的。我们只需要修改三项。
Target Architecture 目标架构,选择ARM (little endian)
Target Architecture Variant ,选择arm926t,即F1c100的内核。
确保Enable VFP extension support项不被勾选。VFP是指硬件浮点计算单元,F1C100并没有。
-完成修改后如下图-
3.退出menuconfig
按两次esc键退出menuconfig,记得它询问是否保存时要选yes,然后按回车
4.编译
开始编译,这个耗时较长,中途还会自己下载所需软件,网速更拖长了时间。我电脑第一次编译花了一小时。
make
5.目标文件
编译结果,是位于output/images/下的rootfs.tar。我们只要将这个压缩包内的东西解压到sd卡的分区2即可。例如我的操作是:
sudo mount /dev/sdb2 /mnt/ #挂载sd卡分区2到电脑/mnt路径 sudo tar -xvf rootfs.tar -C /mnt/ sudo umount /mnt
sd卡内容总结
在sd卡8k偏移的地方存放着uboot
分区1里存放的是.dtb后缀的设备树文件与zImage。
分区2内存放着rootfs.tar解压后的内容
只要全部编译正确,即可启动。