关于荔枝派(LiChee Pi)Nano初体验中的114514个坑

  1. 1. 下载交叉编译工具
  2. 2. 编译U-Boot
  3. 3. 烧录U-Boot
  4. 4. 修改TF卡分区
  5. 5. 建立U-Boot启动文件
  6. 6. 编译Linux内核及设备树
  7. 7. 编译根文件系统
  8. 8. 就这?

上周入手了一块荔枝派 Nano,本想这以为这块板子比较简单,适合学习嵌入式Linux,结果没想到刚开始上手就踩到了一堆的坑,下面来总结一下………

此处使用的操作系统为Ubuntu 20.04,之前在Manjaro下试了半天,就是编译错误,也不知道为什么,换到Ubuntu下就好了。

下载交叉编译工具

下载地址:http://releases.linaro.org/components/toolchain/binaries/7.5-2019.12/arm-linux-gnueabi/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabi.tar.xz

下载完成后解压至/opt目录下,将/opt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabi/bin添加至环境变量PATH

测试是否安装成功:

1
2
3
4
5
6
7
8
$ arm-linux-gnueabi-gcc -v
Using built-in specs.
COLLECT_GCC=arm-linux-gnueabi-gcc
COLLECT_LTO_WRAPPER=/opt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabi/bin/../libexec/gcc/arm-linux-gnueabi/7.5.0/lto-wrapper
Target: arm-linux-gnueabi
(中间省略)
Thread model: posix
gcc version 7.5.0 (Linaro GCC 7.5-2019.12)

编译U-Boot

下载地址:https://github.com/Lichee-Pi/u-boot/archive/nano-v2018.01.zip

1
2
3
4
5
6
# 这里安装一些后面会用到的包
sudo apt install libncurses5-dev make patch swig python python-dev libssl-dev libusb-1.0-0-dev gcc g++ u-boot-tools python3 python3-dev python3-distutils

# 开始编译U-Boot
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- licheepi_nano_spiflash_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j8

不一会,编译应该就完成了,如果最后的时候提示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  (上面省略)
COPY u-boot.bin
MKIMAGE u-boot.img
MKIMAGE u-boot-dtb.img
CC spl/common/spl/spl.o
CC spl/lib/display_options.o
LD spl/common/spl/built-in.o
LD spl/lib/built-in.o
LD spl/u-boot-spl
OBJCOPY spl/u-boot-spl-nodtb.bin
COPY spl/u-boot-spl.bin
MKSUNXI spl/sunxi-spl.bin
BINMAN u-boot-sunxi-with-spl.bin
./tools/binman/binman: 1: ./binman.py: not found
make: *** [Makefile:1148: u-boot-sunxi-with-spl.bin] Error 127

可以执行如下命令:

1
mv tools/binman/binman.py tools/binman/binman

之后重新make就可以了。

烧录U-Boot

下载烧录工具sunxi-toolshttps://github.com/Icenowy/sunxi-tools/archive/f1c100s-spiflash.zip

解压,打开文件夹,编译并安装:

1
make && sudo make install

将荔枝派用USB线连接至电脑,可通过命令sudo sunxi-fel ver来确认是否成功进入FEL Mode,当Flash中没有程序时,会自动进入FEL Mode,如有程序,可短接Flash的1、4脚以进入FEL Mode。

进入U-Boot的根目录:

1
2
3
4
5
# 1.以 uboot file-with-spl形式进行(单次运行,测试时推荐)
sudo sunxi-fel uboot ./u-boot-sunxi-with-spl.bin # 请自行修改到本机地址

# 2.烧进 spi-flash (开机自启)
sudo sunxi-fel -p spiflash-write 0 ./u-boot-sunxi-with-spl.bin

等待烧录完成,打开串口调试工具,如minicom,即可看到如下输出,说明U-Boot已经烧录成功了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
U-Boot SPL 2018.01 (Jun 25 2020 - 17:30:44)
DRAM: 32 MiB
Trying to boot from FEL

U-Boot 2018.01 (Jun 25 2020 - 17:30:44 +0800) Allwinner Technology
CPU: Allwinner F Series (SUNIV)
Model: Lichee Pi Nano
DRAM: 32 MiB
MMC: SUNXI SD/MMC: 0
SF: unrecognized JEDEC id bytes: 0b, 40, 18
*** Warning - spi_flash_probe_bus_cs() failed, using default environment

In: serial@1c25000
Out: serial@1c25000
Err: serial@1c25000
Net: No ethernet found.
starting USB...
No controllers found
Hit any key to stop autoboot: 0

修改TF卡分区

这里可以使用fdisk来分区,或者使用GUI的分区工具如GParted、KDE PartitionManager,下面给出fdisk的命令:

1
2
3
4
5
6
7
8
sudo fdisk -l				# 查看TF卡的设备文件
sudo umount /dev/sdXx # 如果挂载了TF设备,需先卸载
sudo fdisk /dev/sdX # 进行分区操作
# d 删除指定分区
# n 新建分区,第一分区大小设置为32M,剩下的分给第二分区
# w 保存更改并退出
sudo mkfs.vfat /dev/sdX1 # 将第一分区格式化为FAT
sudo mkfs.ext4 /dev/sdX2 # 将第二分区格式化为EXT4

建立U-Boot启动文件

首先,新建一个boot.cmd文件,输入如下内容:

1
2
3
4
setenv bootargs console=tty0 console=ttyS0,115200 panic=5 rootwait root=/dev/mmcblk0p2 rw
load mmc 0:1 0x80C00000 suniv-f1c100s-licheepi-nano.dtb
load mmc 0:1 0x80008000 zImage
bootz 0x80008000 - 0x80C00000

其中,第一行为设置启动参数环境变量,第二行为从TF卡的第一分区读取设备树文件到内存地址0x80C00000,第三行为从第一分区读取zImage到内存地址0x80008000,最后一行为从指定内存地址启动内核。

保存后执行:

1
mkimage -C none -A arm -T script -d boot.cmd boot.scr

将生成的boot.scr放入TF卡的第一分区。

编译Linux内核及设备树

内核源代码下载地址:https://github.com/Icenowy/linux/archive/f1c100s-480272lcd-test.zip

下载.config文件,放入源代码根目录下,确保文件名为.config。然后开始编译:

1
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j8    #请自行修改编译线程数

在编译生成设备树的过程中,会出现如下错误:

1
2
3
4
5
6
  DTC     arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dtb
In file included from arch/arm/boot/dts/suniv-f1c100s.dtsi:6:0,
from arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dts:7:
arch/arm/boot/dts/suniv.dtsi:6:10: fatal error: dt-bindings/clock/suniv-ccu.h: No such file or directory
#include <dt-bindings/clock/suniv-ccu.h>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

具体原因我也不是很清楚,解决的办法是:仿照编译器include的办法,将无法include的头文件的内容直接粘贴进arch/arm/boot/dts/suniv.dtsi文件即可,并注释掉原include语句。然后重新编译即可。

编译完成后,将

  • arch/arm/boot/zImage
  • arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dtb

两个文件放入TF卡的第一分区。在U-Boot从SPL启动后,插入TF卡,等待自动启动,如没有自动启动,可输入命令boot启动。在内核启动的过程中,会提示Kernel Panic(内核恐慌内核错误)

1
Kernel panic - not syncing: No working init found.  Try passing init= option to kernel. See Linux Documentation/admin-guide/init.rst for guidance.

这是由于我们还没有构建根文件系统造成的(找不到init程序),所以接下来我们将进行最后一步,也是耗时最久的一步:编译根文件系统

编译根文件系统

首先在Buildroot下载页面下载构建工具,然后解压,进入目录。

1
make menuconfig

这里的设置很重要,关系到Linux能否正常运行。需修改的设置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Target options  --->
Target Architecture (ARM (little endian)) --->
Target Architecture Variant (arm926t) --->
[ ] Enable VFP extension support (NEW) # 注意:由于F1C100S中没有浮点单元,所以不能勾选
Build options --->
Mirrors and Download locations --->
(https://mirrors.tuna.tsinghua.edu.cn/gnu) GNU Software mirror # 使用镜像站加速下载
Toolchain --->
Toolchain type (Buildroot toolchain) ---> # 最好用Buildroot自动构建的工具链
C library (glibc) ---> # 想兼容性好的选这个,想节省空间的选musl
Kernel Headers (Manually specified Linux version) --->
(4.15) linux version
Custom kernel headers series (4.15.x) --->
System configuration --->
(LicheePi-Nano) System hostname
(Welcome to LicheePi Nano) System banner
(licheepi) Root password
[*] remount root filesystem read-write during boot
Target packages --->
# 关于预装软件包的选择,根据需要自行选择

接着就是漫长的编译:

1
make

在编译过程中,Buildroot会根据选择软件包的不同,下载对应的源代码进行编译,其中主要是GNU的软件,如从其他镜像站下载速度过慢,可考虑HTTP_PROXY(懂的都懂),如果从kernel.org下载速度过慢,可考虑从清华大学镜像站手动下载对应的压缩包(因为起始目录不同的原因,不能直接设置镜像站),手动下载的压缩包需放入.../buildroot-20xx.xx.x/dl目录下的对应文件夹中。

构建完成后,可以在../buildroot-20xx.xx.x/output/images/下找到生成的压缩包。

最后,就是将生成的跟文件系统复制到TF卡中并解压:

1
2
3
4
sudo cp rootfs.tar /path/to/tf/card
cd /path/to/tf/card
sudo tar -xf ./rootfs.tar
sudo rm ./rootfs.tar

终于,我们的Linux可以正常启动了!!!附上完整启动日志:

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
Starting kernel ...

[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 4.15.0-rc8-licheepi-nano (××××××××) (gcc version 7.5.0 (Linaro GCC 7.5-2019.12)) #1 Thu Jun 25 20:46:42 CST 2020
[ 0.000000] CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=0005317f
[ 0.000000] CPU: VIVT data cache, VIVT instruction cache
[ 0.000000] OF: fdt: Machine model: Lichee Pi Nano
[ 0.000000] Memory policy: Data cache writeback
[ 0.000000] random: fast init done
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 8128
[ 0.000000] Kernel command line: console=tty0 console=ttyS0,115200 panic=5 rootwait root=/dev/mmcblk0p2 rw
[ 0.000000] Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
[ 0.000000] Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
[ 0.000000] Memory: 22684K/32768K available (6144K kernel code, 236K rwdata, 1388K rodata, 1024K init, 244K bss, 10084K reserved, 0K cma-reserved, 0K highmem)
[ 0.000000] Virtual kernel memory layout:
[ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB)
[ 0.000000] fixmap : 0xffc00000 - 0xfff00000 (3072 kB)
[ 0.000000] vmalloc : 0xc2800000 - 0xff800000 ( 976 MB)
[ 0.000000] lowmem : 0xc0000000 - 0xc2000000 ( 32 MB)
[ 0.000000] pkmap : 0xbfe00000 - 0xc0000000 ( 2 MB)
[ 0.000000] modules : 0xbf000000 - 0xbfe00000 ( 14 MB)
[ 0.000000] .text : 0x(ptrval) - 0x(ptrval) (7136 kB)
[ 0.000000] .init : 0x(ptrval) - 0x(ptrval) (1024 kB)
[ 0.000000] .data : 0x(ptrval) - 0x(ptrval) ( 237 kB)
[ 0.000000] .bss : 0x(ptrval) - 0x(ptrval) ( 245 kB)
[ 0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[ 0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
[ 0.000044] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 89478484971ns
[ 0.000109] clocksource: timer: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 79635851949 ns
[ 0.000634] Console: colour dummy device 80x30
[ 0.001539] console [tty0] enabled
[ 0.001643] Calibrating delay loop... 203.16 BogoMIPS (lpj=1015808)
[ 0.070275] pid_max: default: 32768 minimum: 301
[ 0.070612] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.070700] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.072159] CPU: Testing write buffer coherency: ok
[ 0.073851] Setting up static identity map for 0x80100000 - 0x80100058
[ 0.076417] devtmpfs: initialized
[ 0.082719] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[ 0.082881] futex hash table entries: 256 (order: -1, 3072 bytes)
[ 0.083185] pinctrl core: initialized pinctrl subsystem
[ 0.085180] NET: Registered protocol family 16
[ 0.086606] DMA: preallocated 256 KiB pool for atomic coherent allocations
[ 0.088429] cpuidle: using governor menu
[ 0.112992] SCSI subsystem initialized
[ 0.113394] usbcore: registered new interface driver usbfs
[ 0.113598] usbcore: registered new interface driver hub
[ 0.113850] usbcore: registered new device driver usb
[ 0.114338] pps_core: LinuxPPS API ver. 1 registered
[ 0.114418] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 0.114543] PTP clock support registered
[ 0.115027] Advanced Linux Sound Architecture Driver Initialized.
[ 0.116565] clocksource: Switched to clocksource timer
[ 0.141992] NET: Registered protocol family 2
[ 0.143454] TCP established hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.143600] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.143685] TCP: Hash tables configured (established 1024 bind 1024)
[ 0.143991] UDP hash table entries: 256 (order: 0, 4096 bytes)
[ 0.144098] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[ 0.144611] NET: Registered protocol family 1
[ 0.145851] RPC: Registered named UNIX socket transport module.
[ 0.145959] RPC: Registered udp transport module.
[ 0.146008] RPC: Registered tcp transport module.
[ 0.146051] RPC: Registered tcp NFSv4.1 backchannel transport module.
[ 0.148362] NetWinder Floating Point Emulator V0.97 (double precision)
[ 0.150198] Initialise system trusted keyrings
[ 0.150793] workingset: timestamp_bits=30 max_order=13 bucket_order=0
[ 0.167974] NFS: Registering the id_resolver key type
[ 0.168122] Key type id_resolver registered
[ 0.168181] Key type id_legacy registered
[ 0.181191] Key type asymmetric registered
[ 0.181297] Asymmetric key parser 'x509' registered
[ 0.181535] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 251)
[ 0.181627] io scheduler noop registered
[ 0.181672] io scheduler deadline registered
[ 0.182443] io scheduler cfq registered (default)
[ 0.182539] io scheduler mq-deadline registered
[ 0.182597] io scheduler kyber registered
[ 0.183706] sun4i-usb-phy 1c13400.phy: Couldn't request ID GPIO
[ 0.193385] suniv-pinctrl 1c20800.pinctrl: initialized sunXi PIO driver
[ 0.357599] Serial: 8250/16550 driver, 8 ports, IRQ sharing disabled
[ 0.364131] console [ttyS0] disabled
[ 0.384445] 1c25000.serial: ttyS0 at MMIO 0x1c25000 (irq = 23, base_baud = 6250000) is a 16550A
[ 0.854300] console [ttyS0] enabled
[ 0.864668] panel-simple panel: panel supply power not found, using dummy regulator
[ 0.874133] SCSI Media Changer driver v0.25
[ 0.881914] m25p80 spi0.0: unrecognized JEDEC id bytes: 0b, 40, 18
[ 0.888843] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[ 0.895438] ehci-platform: EHCI generic platform driver
[ 0.901089] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[ 0.907459] ohci-platform: OHCI generic platform driver
[ 0.913128] usbcore: registered new interface driver usb-storage
[ 0.920219] udc-core: couldn't find an available UDC - added [g_cdc] to list of pending drivers
[ 0.929389] i2c /dev entries driver
[ 0.986703] sunxi-mmc 1c0f000.mmc: base:0xdf78b1b5 irq:19
[ 0.994177] usbcore: registered new interface driver usbhid
[ 0.999937] usbhid: USB HID core driver
[ 1.021682] NET: Registered protocol family 17
[ 1.026446] Key type dns_resolver registered
[ 1.033117] Loading compiled-in X.509 certificates
[ 1.049500] sun4i-drm display-engine: bound 1e60000.display-backend (ops 0xc0739478)
[ 1.058465] sun4i-drm display-engine: bound 1c0c000.lcd-controller (ops 0xc073875c)
[ 1.066217] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
[ 1.072980] [drm] No driver support for vblank timestamp query.
[ 1.129457] Console: switching to colour frame buffer device 60x34
[ 1.132337] mmc0: host does not support reading read-only switch, assuming write-enable
[ 1.135145] mmc0: new high speed SD card at address 0007
[ 1.136261] mmcblk0: mmc0:0007 SD01G 951 MiB
[ 1.153264] mmcblk0: p1 p2 p3
[ 1.196058] sun4i-drm display-engine: fb0: frame buffer device
[ 1.215463] [drm] Initialized sun4i-drm 1.0.0 20150629 for display-engine on minor 0
[ 1.237237] usb_phy_generic usb_phy_generic.0.auto: usb_phy_generic.0.auto supply vcc not found, using dummy regulator
[ 1.267992] musb-hdrc musb-hdrc.1.auto: MUSB HDRC host driver
[ 1.286715] musb-hdrc musb-hdrc.1.auto: new USB bus registered, assigned bus number 1
[ 1.309838] hub 1-0:1.0: USB hub found
[ 1.320422] hub 1-0:1.0: 1 port detected
[ 1.332504] using random self ethernet address
[ 1.343534] using random host ethernet address
[ 1.356114] usb0: HOST MAC 16:9a:54:72:59:0b
[ 1.366949] usb0: MAC ea:c8:2a:0c:1f:48
[ 1.377149] g_cdc gadget: CDC Composite Gadget, version: King Kamehameha Day 2008
[ 1.397002] g_cdc gadget: g_cdc ready
[ 1.407816] cfg80211: Loading compiled-in X.509 certificates for regulatory database
[ 1.438151] cfg80211: Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'
[ 1.457349] ALSA device list:
[ 1.466463] #0: Loopback 1
[ 1.476283] platform regulatory.0: Direct firmware load for regulatory.db failed with error -2
[ 1.497060] cfg80211: failed to load regulatory.db
[ 1.511503] EXT4-fs (mmcblk0p2): couldn't mount as ext3 due to feature incompatibilities
[ 1.568949] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
[ 1.589476] VFS: Mounted root (ext4 filesystem) on device 179:2.
[ 1.615570] devtmpfs: mounted
[ 1.629468] Freeing unused kernel memory: 1024K
[ 1.829528] EXT4-fs (mmcblk0p2): re-mounted. Opts: data=ordered
Starting logging: OK
Initializing random number generator... done.
Starting network: OK

Welcome to LicheePi Nano Linux
LicheePi-Nano login:

就这?

关于SPI Flash的适配得另外写一篇文章了,因为又是一堆的坑……

对于荔枝派 Nano,首先性价比肯定是高,35元就可以买到一块Linux板子,但由于的全志商业模式,相比其其他的SoC,网上关于F1C100S SoC的资料少得多,目前关于裸机开发,比较好的参考资料就是XBOOT的源代码,它已经实现了F1C100S的很多驱动,而且其代码可读性很不错。

如果真的想学习嵌入式Linux的话,个人感觉选择资料比较多的NXP i.MX 6系列SoC会好的多。

本网站所有文章除特别声明外,均采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。