背景:本人从淘宝上买了一块荔枝派nano,意欲构建一个需要用到网络的服务。购买回来后,虽然提供了wifi模块,但是接进去后发现并不能连上网络。预装系统启动时也报了网络启动失败的错误,所以只好去官方尝试找支持wifi的firmware镜像,网上也有人说用官方firmware烧录时能正常连上wifi。结果是自己烧录后发现连系统都启动不了,最终一查发现我的flash用的是”xt25f128b”芯片,而官方的镜像默认是没有支持上的。最终只好自己去编译,过程中碰到不少问题,这里记录下来,以供后来者有个参考。
同时这里请注意本人主开发环境是mac,有些个别地方mac上需要特别处理,但大部分情况下你在ubuntu上操作是一样的,甚至更简单。对于有区别的地方,我会进行相应提示。
第一章 Docker容器编译环境搭建
Docker 镜像下载
不要用官网提供的 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
直接去官方提供的网盘上去下载:
[docker镜像](https://pan.baidu.com/s/1aYcGfzyz-g4CbxGSsVREGQ)
下载后解压
>gunzip nano.tar.gz
将获得
>nano.tar
下面将会用到
#### 创见大小写敏感分区(只需要在Mac环境下做)
这个我是听官方群的人说的,真实情况是否如此以及我是否有理解正确,我其实比较怀疑,不过我没有花时间去对比,所以直接就这样开干了。
> 在mac上使用docker编译时,会出现mac和linux文件系统不兼容的问题。所以需要创建独立大小写敏感分区作为共享文件夹来进行编译。
我们将会在启动docker容器时通过-v host路径:容器路径 来让容器和系统共享文件夹,这样在容器内编译好的东西,我们在mac上就能直接烧录
**创建5g磁盘名为DockerShare的分区**
>hdiutil create -size 5g -type SPARSE -fs "Case-sensitive HFS+" -volume DockerShare DockerShare.sparseimage
**挂载分区**
>hdiutil attach DockerShare.sparseimage
**检查分区**
>df -lh
/dev/disk2s2 4.7Gi 2.8Gi 1.8Gi 61% 171722 4294795557 0% /Volumes/DockerShare1
2
3
4
5
6
7#### 加载docker镜像
加载刚才解压的docker镜像
>sudo docker import nano.tar
查看docker image id
>sudo docker images
Kevins-MacBook-Pro:build kzhu$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
1
2
3
4
5
6
7
8
#### 运行容器
通过指定刚才获得的image id和本地的共享文件夹运行容器,同时默认打开sshd,好让我们可以通过ssh进去容器进行操作
>sudo docker run -d -v /Volumen/DockerShare:/data -p 6666:22 808dbfca6929 /usr/sbin/sshd -D
检查容器是否正确运行
>sudo docker ps
Kevins-MacBook-Pro:build kzhu$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
489c34f2215e 808dbfca6929 “/usr/sbin/sshd -D” 23 hours ago Up 23 hours 0.0.0.0:6666->22/tcp licheepai1
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
检查ssh是否正常工作
>ssh -p 6666 root@127.0.0.1
输入密码,默认licheepi。注意buildroot时如果改了则用相应密码
#### 移动源码到共享目录
ssh进去通过root账号登录后,我们会发现里面已经准备好了以下源码
- linux
- u-boot
- buildroot-2017.08
如上面说的,我们会在共享文件夹中进行编译,所以需要将这些文件夹拷贝到上面挂载的/data/目录下。
#### 安装缺少的依赖包
ssh到容器后,我们会发现里面已经为我们准备好了linux,u-boot等的源码,在编译之前,我们需要安装缺少的几个包,我自己跑的时候缺的是以下一些,按照命令安装就好了。
>sudo apt install libusb-1.0-0-dev
>sudo apt install swig
>sudo apt install python-dev
### 第二章 编译uboot
#### 编译选项配置
首先进入u-boot源码目录,然后如官网上一样执行以下命令
此处告知make采用arm-linux-gnueabi下的所有交叉编译工具,目标架构为Arm,设定各项默认配置为 nano 的spiflash支持版
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- licheepi_nano_spiflash_defconfig
若不带spi-flash的板子,请换成 licheepi_nano_defconfig
进行可视化配置
make ARCH=arm menuconfig1
2
然后开始进行编译配置,首先我用的是一块800x480的LCD屏,所以我需要勾选上:ARM architecture ‣ Enable graphical uboot console on HDMI, LCD or VGA, 然后统计的LCD panel timing details设置成:
x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:40,up:31,lo:13,hs:1,vs:1,sync:3,vmode:01
2
3
4
5
6
7然后将LCD panel backlight pwm pin设置成PE6
修改完LCD支持后,跟着配置启动参数, 勾选Enable boot arguments
console=ttyS0,115200 panic=5 rootwait root=/dev/mtdblock3 rw rootfstype=jffs2
然后是配置bootcmd,这里是可选的,你可以在这里配置,也可以通过修改源码进行配置。我选择在这里配。
首先勾选上Enable a default value for bootcmd,然后填上:
sf probe 0 50000000;sf read 0x80C00000 0x100000 0x4000;sf read 0x80008000 0x110000 0x400000;bootz 0x80008000 - 0x80C00000”1
2
3
4
5
6
7
8
9
10
然后保存配置并退出
#### 源码修改以适配flash芯片
下一步我需要做的是让uboot支持上我的"xt25f128b"flash,这里特别要注意的是,如果你是在淘宝上买的荔枝派nano,那么很大可能你的flash芯片是“xt25f128b”, 因为据说原来不是这个芯片,后来芯片价格贵了,就找了这个芯片来替代。 如果我们不改的话,烧录新固件到flash后就会启动不了并报以下错误:
>SF: unrecognized JEDEC id bytes: 0b, 40, 18
首先我们进入u-boot源码下的drivers/mtd/spi/spi_flash_ids.c。
找到对应数据结构增加"xt25f128b"的信息定义,具体含义我也不知道,反正就照做
const struct spi_flash_info spi_flash_ids[] = {
…
{“w25q128fw”, INFO(0xef6018, 0x0, 64 1024, 256, RD_FULL | WR_QPP | SECT_4K) },
{“xt25f128b”, INFO(0x0b4018, 0x0, 64 1024, 256, RD_FULL | WR_QPP | SECT_4K) },
…
};
1 |
|
&spi0 {
pinctrl-names = “default”;
pinctrl-0 = <&spi0_pins_a>;
status = “okay”;
flash@0 {
#address-cells = <1>;
#size-cells = <1>;
#compatible = "winbond,w25q128", "jedec,spi-nor";
compatible = "winbond,xt25f128b", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <40000000>;
};
};1
2
#### 开始编译
开始编译
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j81
2
3
4
5
6
7
8
9
10
编译完成后,可一看到目录下多了一堆以u-boot带头的文件,我们只需取 u-boot-sunxi-with-spl.bin 即可;
### 第三章 编译linux
#### dts修改
因为我们上面是通过uboot的bootargs传递给内核进行解析分区信息,所以这里我觉得应该不改写可以。但我是改了的,然后最终起来也没有报错,所以我就懒得去掉它重新测试了。
在linux源码目录下打开arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dts,并进行以下修改,注意我这里将芯片型号改成了我的”xt25f128b"
&spi0 {
pinctrl-names = “default”;
pinctrl-0 = <&spi0_pins_a>;
status = “okay”;
spi-max-frequency = <50000000>;
flash: xt25f128b@0 {50000000>
#address-cells = <1>;
#size-cells = <1>;
compatible = "winbond,xt25f128b", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <50000000>;
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "u-boot";
reg = <0x000000 0x100000>;
read-only;
};
partition@100000 {
label = "dtb";
reg = <0x100000 0x10000>;
read-only;
};
partition@110000 {
label = "kernel";
reg = <0x110000 0x400000>;
read-only;
};
partition@510000 {
label = "rootfs";
reg = <0x510000 0xAF0000>;
};
};
};
};1
2
3
4
5
根据官方说的下载[.config](http://dl.sipeed.com/LICHEE/Nano/SDK/config)文件,然后替换掉linux目录下的.config
然后在linux目录下执行以下命令进行配置
make ARCH=arm menuconfig
1 |
|
{ “xt25f128b”, INFO(0x0b4018, 0, 64 1024, 256, 0) },
{ “w25q80”, INFO(0xef5014, 0, 64 1024, 16, SECT_4K) },1
2
为了加快编译速度,请自行更改线程数
编译内核,生成zImage
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j4
编译dts,生成dtb文件
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- dtbs -j4
编译内核模块,并输出到out目录
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- INSTALL_MOD_PATH=out modules
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- INSTALL_MOD_PATH=out modules_install1
2
3
4
5
6
7
8
9
10编译完成后会生成如下两个文件:
- ./arch/arm/boot/zImage
- ./arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dtb
和如下目录:
- ./out/lib/modules
### 第四章 编译esp8089 wifi驱动模块
如果你要连接网络,并且用的是相应的模块,则需要对esp8089驱动进行编译。
首先进入到我们的/data目录,执行以下命令拉取esp8089驱动源码
git clone https://github.com/Icenowy/esp8089.git1
2
然后再次进入到linux目录下执行以下命令进行编译即可
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j4
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j4 INSTALL_MOD_PATH=out modules
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j4 INSTALL_MOD_PATH=out modules_install
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j4 M=../esp8089 CONFIG_ESP8089=m INSTALL_MOD_PATH=out modules
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j4 M=../esp8089 CONFIG_ESP8089=m INSTALL_MOD_PATH=out modules_install1
2
3
4
5
6
7
8
9
10
11
最终将生成:
- esp8089/esp8089.ko。 生成的模块将会和linux自身模块一起打包到镜像中
- esp8089/firmware。这里的内容也必须打包,没有的话到时insmode esp8089模块时会失败
生成的模块将会和linux自身模块一起打包到镜像中
### 第五章 buildroot构建根文件系统
这里我通过官网提供的[.config](https://fdvad021asfd8q.oss-cn-hangzhou.aliyuncs.com/migrate/buildroot.config)构建出来的文件系统打包后rootfs.tar达到95兆之大,所以只能删掉该配置文件,只选取基本的包来进行编译。
首先,进入到buildroot-2017.08源代码,删除.config文件,然后执行
make menuconfig1
2
然后对编译选项做相应配置。首先根据官网做最简单的配置
Target options —>
Target Architecture Variant (arm926t) ---> // arm926ejs架构
[ ] Enable VFP extension support // Nano 没有 VFP单元,勾选会导致某些应用无法运行
Target ABI (EABI) —>
Floating point strategy (Soft float) —> // 软浮点
System configuration —>
(Lichee Pi) System hostname // hostname
(licheepi) Root password // 默认账户为root 密码为licheepi
[*] remount root filesystem read-write during boot // 启动时重新挂在文件系统使其可读写
1 |
|
#!/bin/bash
curPath=$(readlink -f “$(dirname “$0”)”)
_IMG_FILE=firmware.bin
_UBOOT_FILE=$curPath/u-boot/u-boot-sunxi-with-spl.bin
_DTB_FILE=$curPath/linux/arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dtb
_KERNEL_FILE=$curPath/linux/arch/arm/boot/zImage
_ROOTFS_FILE=$curPath/buildroot-2017.08/output/images/rootfs.tar
_MOD_FILE=$curPath/linux/out/lib/modules
_ESP8089_FIRMWARE=$curPath/esp8089/firmware
_TEMP_FOLDER=~/_temp
if [ -f $_IMG_FILE ] ; then
echo “Image exist,rename it to .old”
mv $_IMG_FILE $_IMG_FILE.old -f
echo “Creating new an Image”
fi
rm -rf $_TEMP_FOLDER
mkdir $_TEMP_FOLDER &&\
cd $_TEMP_FOLDER &&\
echo “Generate bin…”
dd if=/dev/zero of=flashimg.bin bs=1M count=16 &&\
echo “Packing Uboot…”
dd if=$_UBOOT_FILE of=flashimg.bin bs=1K conv=notrunc &&\
echo “Packing dtb…”
dd if=$_DTB_FILE of=flashimg.bin bs=1K seek=1024 conv=notrunc &&\
echo “Packing zImage…”
cp $_KERNEL_FILE ./zImage &&\
dd if=./zImage of=flashimg.bin bs=1K seek=1088 conv=notrunc &&\
mkdir rootfs
echo “Packing rootfs…”
tar -xvf $_ROOTFS_FILE -C ./rootfs >/dev/null &&\
cp -r $_MOD_FILE rootfs/lib/modules/ &&\
cp -r $_ESP8089_FIRMWARE rootfs/lib/ &&\
mkfs.jffs2 -s 0x100 -e 0x10000 –pad=0xAF0000 -d rootfs/ -o jffs2.img &&\
dd if=jffs2.img of=flashimg.bin bs=1K seek=5184 conv=notrunc &&\
mv ./flashimg.bin $curPath/$_IMG_FILE &&\
echo “Bin update done!”
echo $(pwd)
1 |
|
root@489c34f2215e:/data# df -T .
Filesystem Type 1K-blocks Used Available Use% Mounted on
osxfs fuse.osxfs 10485760 5287532 5198228 51% /data1
2
3
4
5
### 第七章 烧录
#### 安装烧录工具
首先在mac命令行中执行以下命令,从github上clone下来sunxi-tools的源码
git clone https://github.com/Icenowy/sunxi-tools.git -b f1c100s-spiflash1
2
然后安装libs-usb依赖。 注意这里我是mac,如果你是ubuntu的话,请将brew换成apt-get
brew install libusb1
然后link一下
brew link libusb1
2
最后开始编译
make && make install1
2
3
4
5
6
7
8
9
最终将会生成并安装好sunxi-fel工具
#### 进行烧录
拔掉usb转ttl于电脑的连接,短接flash的1,4两脚,注意,这里是flash的1,4脚,flash是靠近otg接口的那块芯片,上面写着"xt25f128b"之类型号的芯片。
接上usb与电脑的连接,然后松开1,4两脚的连接,这时应该就会进入到fel烧录模式,这时屏幕你观察下,不会再由人很启动或者uboot信息打印出来。
然后通过sunxi-fel工具可以检查是否进入了fel模式:
Kevins-MacBook-Pro:images kzhu$ sudo sunxi-fel version
AWUSBFEX soc=00001663(F1C100s) 00000001 ver=0001 44 08 scratchpad=00007e00 00000000 000000001
如果打印的是以下信息,代表没有进入到fel模式
Kevins-MacBook-Pro:build kzhu$ sudo sunxi-fel version
ERROR: Allwinner USB FEL device not found!1
2
最后进行烧录
sudo sunxi-fel -p spiflash-write 0 /Volumes/DockerShare/firmware.bin
100% [================================================] 16777 kB, 96.3 kB/s`
烧录完后拔掉usb重新上电,接上串口,即可启动并进入到系统,然后就开始愉快的玩耍了。
第八章 参考和感谢
整个过程参考了很多文章,同时感叹下荔枝派nano的资料真心是少,官方文档也应该是没有精力维护。所以非常感激那些编写了相应文章让我能有所参考的玩家们,这里列出一些引用到的文章,如果还有哪些我忘了写的,这里说声抱歉,你跟我说下,然后我添加上去。