Licheepi Nano 02 编译linux

发布于 2022-07-21  351 次阅读


  对于一个完整的linux系统,其由三部分组成:

  1. bootloader
  2. kernel
  3. rootfile system

bootloader相当于pc机上的bios,负责引导进入kernel,而rootfile system负责文件的存放与用户的交互。对于bootloader,这里使用uboot;对于rootfs,使用buildroot。

一、编译工具的准备

  这里需要使用的交叉编译工具链为:arm-linux-gnueabi-。我们使用它来编译u-boot和kernel。而rootfs则使用musl完成。

二、u-boot

  这里根据自己的需求下拉u-boot,这里使用licheepi nano的800*480分支。

git clone -b nano-lcd800480 https://github.com/LicheePiNano/u-boot.git

  因为本次系统存放在SD卡上,所以使用licheepi_nano_defconfig,然后在menuconfig里面修改一些启动参数。如果使用spi flash,则使用licheepi_nano_spiflash_defconfig。配置文件保存在/u-boot/configs/下。

make ARCH=arm licheepi_nano_defconfig

make menuconfig

2.1 u-boot参数配置

2.1.1 bootcmd

这里主要添加bootargs和bootcmd。bootcmd主要执行三条命令

  1. load mmc 0:1 0x80008000 zImage;
  2. load mmc 0:1 0x80c08000 suniv-f1c100s-licheepi-nano.dtb;
  3. bootz 0x80008000 - 0x80c08000;

load mmc负责将kernel编译出来的zImg、dtb加载到内存;bootz负责启动linux zImg。

  因此,bootcmd中添加如下内容:

load mmc 0:1 0x80008000 zImage;load mmc 0:1 0x80c08000 suniv-f1c100s-licheepi-nano.dtb;bootz 0x80008000 - 0x80c08000;

2.1.1 bootargs

console=ttyS0,115200 panic=5 rootwait root=/dev/mmcblk0p2 earlyprintk rw
  1. console=ttyS0,115200,表示终端为ttyS0即串口0,波特率为115200;
  2. panic=5,设置kernel恐慌时间;
  3. rootwait, 该参数是告诉内核挂在文件系统之前需要先加载相关驱动,这样做的目的是防止因mmc驱动还未加载就开始挂载驱动而导致文件系统挂载失败;
  4. root=/dev/mmcblk0p2,表示根文件系统的位置在mmc的0:2分区处,/dev是设备文件夹,内核在加载mmc中的时候就会在根文件系统中生成mmcblk0p2设备文件,这个设备文件其实就是mmc的0:2分区(这里对应TF卡的第二个分区:rootfs),这样内核对文件系统的读写操作方式本质上就是读写/dev/mmcblk0p2该设备文件;
  5. earlyprintk,参数是指在内核加载的过程中打印输出信息,这样内核在加载的时候终端就会输出相应的启动信息。rw表示文件系统的操作属性,此处rw表示可读可写。

2.2 编译u-boot

  在配置完成bootargs和bootcmd之后,开始编译:

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

在编译完成之后,/u-boot/下生成了输出文件——u-boot-sunxi-with-spl.bin。在使用dd创建启动盘之前,先对SD卡进行初始化。

三、SD卡分区设置

  我们在ubuntu下使用GParted来实现SD卡分区设置,如果没有安装,则可以直接使用apt来安装,sudo apt-get install gprated。SD卡分区设置如下:

图1
图1:SD卡分区设置

第一个分区为fat16,用来存放kernel内容;第二分区为ext4,用来存放rootfs内容。

四、kernel

  我们在kernel.org下载内核,同时将linux-licheepi_nano_defconfig放入/arch/arm/configs/中。

make ARCH=arm linux-licheepi_nano_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j8
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j8 INSTALL_MOD_PATH=out modules
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j8 INSTALL_MOD_PATH=out modules_install

  之后输出的zImg文件在/arch/arm/boot/下;设备树dtb文件在/arch/arm/boot/dts/下。

五、buildroot

  在buildroot.org下载源码,解压后准备配置:

make clean
make menuconfig

5.1 Target options

  这里需要注意的配置有:目标架构为arm小端,即ARM (little endian);同时架构变体为arm926t;浮点运算选择soft float软浮点。详细的配置如下图2所示。

图2
图2:Target options

5.2 Build options

  这里将库设置为动态化静态库,如下图3所示。

图3
图3:Build options

5.3 Toolchain

  这里编译工具选择musl以减少体积,同时选择Thread library debuggingEnable xxxx一堆选项。

图4
图4:Toolchain

5.4 System configuration

  这里主要配置root登录的密码:

图5
图5:System configuration

  之后直接使用make开始编译,第一次编译需要下载一些组件,所以时间比较长。编译完成后,在/output/images/下有输出文件,rootfs.tar

六、移植

  在第三节中,我们对SD卡进行了分区,之后将开始移植。首先使用dd将u-boot文件拷贝到SD卡作为启动项,以图1中的设备为例,此处为/dev/sdb,即:

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

  之后将zImg和dtb文件拷贝到SD卡的boot分区;将rootfs.tar解压到SD卡的rootfs分区:

sudo tar -xvf rootfs.tar -C /media/<你的用户名>/rootfs/