目录
- 0.前言
- 1.下载所需的资源
- 1.1 交叉编译工具链
- 1.2 U-Boot
- 1.3 Linux Kernel
- 1.4 Buildroot
- 2.镜像的修改和编译
- 2.1 U-Boot源码的修改和编译
- 2.2 Kernel源码的修改
- 2.3 Buildroot编译
- 3.镜像的烧录和后续设置
- 3.1 烧录
- 3.2 bootcmd和bootargs设置
- 4.运行示例
- 本文资源共享
- 参考
0.前言
本文的构建过程多次参考了Whycan等网站上的帖子,文末的参考列表将列出本文编写时的引用。
如果你不想花费时间进行源码的下载和编译,可以从文末共享资源中获取到已经编译好的U-Boot、Kernel、rootfs镜像,而后从本文第三部分看起,直接烧录它们到开发板。这种方式也是最快的方式。
1.下载所需的资源
首先给出需要的工具和源码的GitHub链接,文末的百度网盘共享链接中存放了下载好的源码所以你大可不必翻墙或者花费数以小时计的时间去下载它们。所以在阅读了下面几项的必要性和说明之后,你可以跳过这部分直接从文末获取资源,再转到第二章进行编译。
1.1 交叉编译工具链
交叉编译工具链用于编译U-Boot和内核,文件系统的编译并不一定依赖外部工具链,文末共享资源中分别提供了使用内部和外部工具链编译出的rootfs镜像。
交叉编译工具链地址: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
交叉编译工具链的安装不再赘述,和其它工具链相同,需更新到系统环境目录。Terminal中输入arm-linux-gnueabi-并按TAB两次可见提示则说明安装成功。后文内容默认已经安装好该交叉编译工具链。
1.2 U-Boot
U-Boot源码地址:https://github.com/Lichee-Pi/u-boot/tree/nano-v2018.01
U-Boot的代码要下载 nano-v2018.01 分支。如果分支选择错误,则配置目录下没有适配开发板的deconfig文件。如前文所说,你可以在文末网盘资源中得到这些镜像。
1.3 Linux Kernel
内核源码地址:https://github.com/Icenowy/linux/tree/f1c100s-480272lcd-test
内核的代码要下载 f1c100s 或者 f1c100s-480272lcd-test 分支上的代码,前者不包括LCD驱动,后者包括。如果分支选择错误,则设备树目录下没有适配开发板的dts文件。如前文所说,你可以在文末网盘资源中得到这些镜像。
1.4 Buildroot
Buildroot源码地址:https://buildroot.org/downloads/buildroot-2017.08.tar.gz
使用Buildroot并不会使初次构建根文件系统快多少,事实上,在虚拟机中使用文末提供的config首次配置编译的时长很可能达到半个下午(取决于具体配置)。但是却免去了手动编译busybox和复制运行库文件的麻烦。
2.镜像的修改和编译
本部分将整合已有的经验贴进行总述,这里的修改将创建支持LCD输出的U-Boot和Kernel镜像。当你不需要LCD屏幕时,可以忽略本部分中有关LCD的修改。
【注意】有关各部分 make menuconfig 的方法网上已经有很多了,为了达到快速上手的目的,本文将忽略这些配置,本部分的源码修改可以配合文末提供的各部分config文件直接编译。
2.1 U-Boot源码的修改和编译
这部分可能需要修改的内容主要是:增加对 xt25f128b 的支持。首先你需要看一下买到的LicheePi的板子上的Flash型号是什么,如果是诸如 w25q128bv 这样在 /LicheePi_Nano_u-boot/drivers/mtd/spi/spi_flash_ids.c 中已经列出的型号,那么本步骤可以略去,否则需要增加对所使用型号的Flash的支持。
在如下图所示的位置增加对 xt25f128b 的配置项,0x0b4018是该型号的标识。这里的修改可能并不严谨,但是不影响使用,怎么快怎么来。
另外,在参考中你可能看到需要修改 ./include/configs/suniv.h 文件,添加启动命令到宏定义中,但是这里我们不使用这种办法。
将文末提供的U-Boot配置文件 uboot.config 复制到U-Boot根目录下并重命名为 .config ,从命令行进入该文件夹输入以下命令编译:
1 | make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j4 |
-j的指令是进行编译加速用的(如果make认为可行),不加这个也可以编译。
这样编译完成之后可以在U-Boot根目录下得到 u-boot-sunxi-with-spl.bin 文件。
此时你需要知道,这时的U-Boot仅仅是完成了设备的启动,因为没有启动命令也没有传递参数,所以还不能引导内核,下一部分我们将在烧录后增加这两个命令。
2.2 Kernel源码的修改
首先修改设备树,添加对屏幕的支持。
在 /linux-f1c100s-480272lcd-test/arch/arm/boot/dts/ 下的 suniv.dtsi 文件中增加一个i2c节点:
1 2 3 4 | i2c0_pins: i2c0 { pins = "PE11", "PE12"; function = "i2c0"; }; |
在 suniv-f1c100s-licheepi-nano.dts 文件中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.h> panel: panel { compatible = "lg,lb070wv8", "simple-panel"; #address-cells = <1>; #size-cells = <0>; enable-gpios = <&pio 4 6 GPIO_ACTIVE_HIGH>; port@0 { reg = <0>; #address-cells = <1>; #size-cells = <0>; panel_input: endpoint@0 { reg = <0>; remote-endpoint = <&tcon0_out_lcd>; }; }; }; //touchscreen support &i2c0 { pinctrl-0 = <&i2c0_pins>; pinctrl-names = "default"; status = "okay"; gt911: touchscreen@14 { compatible = "goodix,gt911"; reg = <0x14>; interrupt-parent = <&pio>; interrupts = <4 10 IRQ_TYPE_EDGE_FALLING>; /* (PE10) */ pinctrl-names = "default"; pinctrl-0 = <&ts_reset_pin>; irq-gpios = <&pio 4 10 GPIO_ACTIVE_HIGH>; /* (PE10) */ reset-gpios = <&pio 4 9 GPIO_ACTIVE_HIGH>; /* RST (PE9) */ /* touchscreen-swapped-x-y */ }; }; &pio { ts_reset_pin: ts_reset_pin@0 { pins = "PE9"; function = "gpio_out"; }; }; |
当然,修改后的设备树文件我也放在了共享中,你也可以直接替换。文末提供的配置文件中已经开启了对内核启动信息输出到屏幕的支持。
另外,关于MTD分区,在参考中你可能看到需要修改设备树,增加分区信息,但是本文不使用这种方法,后续启动时我们使用传递bootargs的方式告诉内核分区信息。
在 /linux-f1c100s-480272lcd-test/drivers/mtd/spi-nor/spi-nor.c 文件中,增加对flash的支持:
将文末提供的Kernel配置文件 kernel.config 复制到linux根目录下并重命名为 .config ,从命令行进入该文件夹输入以下命令编译:
1 | make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j8 |
-j的指令是进行编译加速用的(如果make认为可行),不加这个也可以编译。
这样编译完成之后可以在 /linux-f1c100s-480272lcd-test/arch/arm/boot/ 文件夹下得到 zImage 文件。
2.3 Buildroot编译
将文末提供的 buildroot.config 文件复制到buildroot根目录下并重命名为 .config ,从命令行进入该文件夹下输入make即可编译。
编译过程中会出错中断,则从命令行进入到 buildroot-2017.08/output/build/host-m4-1.4.18/ 文件夹下依次执行以下两个命令:
1 2 | sed -i 's/IO_ftrylockfile/IO_EOF_SEEN/' lib/*.c echo "#define _IO_IN_BACKUP 0x100" >> lib/stdio-impl.h |
而后继续make即可。
使用文末共享资源中提供的buildroot配置文件进行编译将会在 /buildroot-2017.08/output/images/ 文件夹下生成 rootfs.jffs2 和 rootfs.tar 两个文件,后续烧录时我们只使用前者。直接生成JFFS2格式的镜像可以省去使用mkfs.jffs2进行打包所耗费的精力,而且放心,它可以正常使用。
3.镜像的烧录和后续设置
3.1 烧录
镜像的烧录工具使用的是windows下 Whycan论坛@晕哥 提供的f1c100s版本,同样放在共享资源中了。原链接帖子在参考列表中。
短接开发板flash1、4引脚后通过usb连接开发板到电脑将使芯片进入FEL模式,并在电脑上识别为一个设备,此时引脚1、4可不再保持短接。使用 zadig-2.3 工具安装驱动,设备选择开发板对应的设备,驱动库选择 libusb-win32 (v1.2.6.0) 项,但设备名称无所谓。
安装完成后使用cmd进入到sunxi-fel工具目录下依次输入以下命令进行烧录:
1 2 3 4 | sunxi-fel.exe -p spiflash-write 0 u-boot-sunxi-with-spl.bin sunxi-fel.exe -p spiflash-write 0x100000 suniv-f1c100s-licheepi-nano.dtb sunxi-fel.exe -p spiflash-write 0x110000 zImage sunxi-fel.exe -p spiflash-write 0x510000 rootfs.jffs2 |
由于本篇文章不是教学文章,只是用于快速上手并做个人笔记,所以对指令的讲解略去。
3.2 bootcmd和bootargs设置
烧录完成后,将开发板上电,在串口打印到U-Boot启动延时时按回车进入到uboot环境下,依次输入如下命令:
1 2 3 4 5 6 7 8 9 | setenv bootcmd 'sf probe 0 50000000;sf read 0x80C00000 0x100000 0x4000;sf read 0x80008000 0x110000 0x400000;bootz 0x80008000 - 0x80C00000' 【仅使用串口输出内核启动打印信息的bootargs】 setenv bootargs 'console=ttyS0,115200 root=/dev/mtdblock3 rootfstype=jffs2 mtdparts=spi0.0:1M(uboot),64K(dtb),4M(kernel),-(rootfs)' 【内核和屏幕均输出内核启动打印信息的bootargs】 setenv bootargs 'console=tty0 console=ttyS0,115200 root=/dev/mtdblock3 rootfstype=jffs2 mtdparts=spi0.0:1M(uboot),64K(dtb),4M(kernel),-(rootfs)' saveenv |
其中,bootargs的命令二选一。
本文提供的Buildroot制作的rootfs登录名为root,密码为空。
4.运行示例
U-Boot环境下屏幕输出:
内核启动信息打印:
本文资源共享
百度网盘链接:https://pan.baidu.com/s/1MUGxrJTNSwuHUxh6PLWPAg
提取码:oyuc
参考
1.荔枝派Nano全流程指南
2.尝试从零开始构建F1C100s开发环境
3.https://whycan.cn/t_493.html#p1304
4.荔枝派nano内核没有正常启动,spiflash用的xt25f128b,16M,跪求大神帮帮忙啦
5.LicheePi Nano linux启动失败,jffs2 Magic bitmask 错误
6.licheepi nano 内核启动 无法识别spiflash
————2020-6-19 @燕卫博————