Try   HackMD

Embedded Linux Lichee Pi nano

基本觀念可以參考以下筆記:
嵌入式 linux
F1C100S/F1C200S系统构建

此篇僅紀錄開發流程


U-boot

下載u-boot

下載u-boot(非官方板),並切換分支到 nano-v2018.01

sudo git clone https://github.com/Lichee-Pi/u-boot.git # 下載原始碼 cd u-boot # 切換路徑 git branch -a # 查看分支 git checkout nano-v2018.01 # 切換分支

修改配置文件:

設定 u-boot 編譯參數

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- licheepi_nano_spiflash_defconfig # 設置compilor 與 預設config make ARCH=arm menuconfig
  • 取消勾選 "[ ] Enable a default value for bootcmd"
  • 勾選 "[*] Enable boot arguments",並填入其中一項參數
console=ttyS0,115200 panic=5 rootwait root=/dev/mtdblock3 rw rootfstype=jffs2

【仅使用串口输出内核启动打印信息的bootargs】
console=ttyS0,115200 root=/dev/mtdblock3 rootfstype=jffs2 mtdparts=spi0.0:1M(uboot),64K(dtb),4M(kernel),-(rootfs)

【内核和屏幕均输出内核启动打印信息的bootargs】
console=tty0 console=ttyS0,115200 root=/dev/mtdblock3 rootfstype=jffs2 mtdparts=spi0.0:1M(uboot),64K(dtb),4M(kernel),-(rootfs)
  • root=/dev/mtdblock3 為指定 mtd 第3分區
  • rootfstype=jffs2 指的是使用檔案系統格式為 jffs2

如果已指定mtdparts,就不需在kernel的dts中新增分區

根據硬體線路配置LCD螢幕 (沒有LCD螢幕可忽略)

設置 ARM architecture ‣ Enable graphical uboot console on HDMI, LCD or VGA 為 Y

在 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:0

寫入LCD panel backlight pwm pin 為: PE6

修改文件:

  1. 修改文件 include/configs/suniv.h
#define CONFIG_BOOTCOMMAND "sf probe 0 50000000; " \ "sf read 0x80C00000 0x100000 0x10000; " \ "sf read 0x80008000 0x110000 0x400000; " \ "bootz 0x80008000 - 0x80C00000"

宏CONFIG_BOOTCOMMAND 会被uboot自动解析,执行宏里面的内容,宏内容解释如下:

  • sf probe 0 50000000 相当于片选SPI0总线 设置 50000000HZ速度
  • sf read 0x80C00000 0x100000 0x10000 读取Flash里0x100000地址处的设备树文件(0x10000字节),写入 到SDRAM的0x80C00000处
  • sf read 0x80008000 0x110000 0x400000 读取Flash里0x110000地址处的内核文件(0x400000字节),写入到SDRAM的0x80008000处
  • bootz 0x80008000 - 0x80C00000 uboot从0x80008000处加载内核,从0x80C00000处加载dtb,启动内核
分區代號 分區大小 分區作用 地址與名稱
mtd0 1MB(0x100000) spl + uboot 0x0000000:uboot
mtd1 64KB(0x10000) dtb文件 0x0100000:dtb
mtd2 4MB(0x400000) linux kernel 0x0110000:kernel
mtd3 剩下(0xAF0000) 檔案系統 0x0510000:rootfs
  1. 如果使用xt25f128b:需要修改 u-boot/drivers/mtd/spi/spi_flash_ids.c
{"w25q128fw", INFO(0xef6018, 0x0, 64*1024, 256, RD_FULL | WR_QPP | SECT_4K) }, // add "xt25f128b" support {"xt25f128b", INFO(0x0b4018, 0x0, 64*1024, 256, RD_FULL | WR_QPP | SECT_4K) },

編譯 u-boot

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

最後可以得到1份文件

  • ./u-boot-sunxi-with-spl.bin

荔枝派nano上手笔记(一)移植Uboot
荔枝派 Nano 全志 F1C100s 编译运行 Linux ubuntu并升级gcc

Kernel

Kernel 下載與設定

Kernel 所需要的 config 文件

git clone --depth=1 -b f1c100s-480272lcd-test https://github.com/Icenowy/linux.git cd linux wget http://dl.sipeed.com/LICHEE/Nano/SDK/config mv config .config make ARCH=arm menuconfig
  1. 修改SPI驅動
Device Drivers -> SPI support
​	[] Allwinner A10 SoCs SPI controller  # 取消勾选
​	[*]Allwinner A31 SPI Controller       # 勾选这一项
  1. 增加分區相關
Device Drivers -> Memory Technology Device (MTD) support
	[*]Command line partitioning table parsing #解析内核参数传过来的分区信息,如果用设备树应该可以不选
	[*]Caching block device access to MTD devices  #生成/dev/mtdblock*设备,不选会在启动的时候卡在 watiting for device /dev/mtdblock*
  1. 增加jff2s格式支援(全勾)
File systems > Miscellaneous filesystems
	 <*>   Journalling Flash File System v2 (JFFS2) support 
	 等等...

修改文件:

  1. 修改 arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dts
    flash 分區:
默认情况spi0节点信息如下: &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"; reg = <0>; spi-max-frequency = <40000000>; }; }; 现在把这个节点内容修改为下面的 &spi0 { pinctrl-names = "default"; pinctrl-0 = <&spi0_pins_a>; status = "okay"; spi-max-frequency = <50000000>; flash: xt25f128b@0 { #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>; }; }; }; };

LCD螢幕:

根节点下的panel内容是适配了480X272大小的屏幕,内容如下: panel: panel { compatible = "qiaodian,qd43003c0-40", "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>; }; }; }; 而我的屏幕是800*480的,所以修改如下: 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>; }; }; }; 其实就是改了compatible属性,让内核适配屏幕而已,如果参数不合适,自己可以打开这个目录 linux ‣ drivers ‣ gpu ‣ drm ‣ panel 下有许多屏幕的配置,可挑选合适的进行配置;
  1. 修改 flash 支援列表 drivers/mtd/devices/m25p80.c
// 新增 ... ,{"w25q256"},{"xt25f128b"},
  1. 修改 drivers/mtd/spi-nor/spi-nor.c
static const struct flash_info spi_nor_ids[] = { /* 此处省略N行 */ /* { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },*/ { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256,0) }, { "xt25f128b", INFO(0x0b4018, 0, 64 * 1024, 256, 0) }, /* 此处省略N行 */ }

編譯 kernel

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

最後可以得到2份文件

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

Rootfs

從官往下載壓縮包:https://buildroot.org/download.html

wget https://buildroot.org/downloads/buildroot-2021.05.tar.gz # 解壓縮 tar xvf buildroot-2021.05.tar.gz cd buildroot-2021.05.tar.gz/ # wget https://fdvad021asfd8q.oss-cn-hangzhou.aliyuncs.com/migrate/buildroot.config # mv buildroot.config .config make menuconfig

配置文件

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 // 启动时重新挂在文件系统使其可读写 Target packages ---> Networking applications ---> [v] lrzsz // 使用终端传文件给linux

編譯buildroot

# buildroot第一次編譯需要下載套件包會比較久 (buildroot不支援多線程編譯) make

編譯完成的 image 文件會在 buildroot-2021.05/output/images/rootfs.tar
將 image 文件解壓到SD卡根目錄分區即可

檢查 /etc/inittab 有沒有啟動串口

ttyS0::respawn:/sbin/getty -L ttyS0 115200 vt100 # GENERIC_SERIAL // 串口登录使能 tty0::respawn:-bin/sh # LCD

如果掛載權限有問題

cd rootfs/bin ll # 如果看到busybox權限有s : -rwsr-xr-x busybox chmod a-s busybox

將 rootfs.tar 打包為 img

apt-get install mtd-utils # 解壓到rootfs文件夾 tar xzvf rootfs.tar mkfs.jffs2 -s 0x100 -e 0x10000 -p 0xAF0000 -d rootfs/ -o jffs2.img

http://fichugh.blogspot.com/2016/02/buildroot-study.html
https://www.cnblogs.com/arnoldlu/p/9553995.html
buildroot编译文件系统,出现mount: you must be root. can't open /dev/console: Permission denied这种错误。

燒錄到 flash

編譯安裝 sunxi-tools

sudo apt install libz libusb-1.0-0-dev git clone https://github.com/Icenowy/sunxi-tools.git -b f1c100s-spiflash cd sunxi-tools make make install
# 查看CPU資料 sudo sunxi-fel ver # 載入 uboot sudo sunxi-fel uboot 文件名 # 從 0 寫入 flash sudo sunxi-fel -p spiflash-write 0 flashimg.bin

建立bin並燒錄

dd if=/dev/zero of=flashimg.bin bs=1M count=16 dd if=u-boot-sunxi-with-spl.bin of=flashimg.bin bs=1K conv=notrunc dd if=suniv-f1c100s-licheepi-nano.dtb of=flashimg.bin bs=1K seek=1024 conv=notrunc dd if=zImage of=flashimg.bin bs=1K seek=1088 conv=notrunc # mkdir rootfs # tar -xzvf $YOUR_ROOTFS_FILE -C ./rootfs &&\ # cp -r $YOUR_MOD_FILE rootfs/lib/modules/ &&\ # 为根文件系统制作jffs2镜像包 # --pad参数指定 jffs2大小 # 由此计算得到 0x1000000(16M)-0x10000(64K)-0x100000(1M)-0x400000(4M)=0xAF0000 # 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 &&\ sudo sunxi-fel -p spiflash-write 0 flashimg.bin

在 u-boot 中清空 flash

sf probe 0 50000000 0 sf erase 0 0x1000000 reset

燒錄到 SD 卡

LVGL

下載Demo

git clone https://github.com/lvgl/lv_port_linux_frame_buffer.git cd lv_port_linux_frame_buffer git submodule update --init --recursive

config 編譯

編輯 Makefile:

$nano Makefile CC = arm-linux-gnueabi-gcc -std=c99 #-static #靜態編譯 CFLAGS = -O3 -g0 -I$(LVGL_DIR)/ -Wall -Wshadow -Wundef -Wmaybe-uninitialized

如果不想管依賴問題,可以使用 -static 去編譯

更改 lv_conf.h:

#define LV_COLOR_DEPTH 32

編譯:

make

編譯出執行檔 demo , 複製於rootfs中

於Lichee-Pi上執行:

./demo

檢查運行依賴

檢查運行需要的動態連結庫:

/buildroot-2021.05$ output/host/bin/arm-linux-readelf -d ../lv_port_linux_frame_buffer/demo Dynamic section at offset 0x263f10 contains 25 entries: Tag Type Name/Value 0x00000001 (NEEDED) Shared library: [libc.so.6] 0x00000001 (NEEDED) Shared library: [ld-linux.so.3] 0x0000000c (INIT) 0x1059c 0x0000000d (FINI) 0x833b4 0x00000019 (INIT_ARRAY) 0x283f04 0x0000001b (INIT_ARRAYSZ) 4 (bytes) 0x0000001a (FINI_ARRAY) 0x283f08 0x0000001c (FINI_ARRAYSZ) 4 (bytes) 0x6ffffef5 (GNU_HASH) 0x101ac 0x00000005 (STRTAB) 0x103ac 0x00000006 (SYMTAB) 0x1025c 0x0000000a (STRSZ) 220 (bytes) 0x0000000b (SYMENT) 16 (bytes) 0x00000015 (DEBUG) 0x0 0x00000003 (PLTGOT) 0x284000 0x00000002 (PLTRELSZ) 152 (bytes) 0x00000014 (PLTREL) REL 0x00000017 (JMPREL) 0x10504 0x00000011 (REL) 0x104f4 0x00000012 (RELSZ) 16 (bytes) 0x00000013 (RELENT) 8 (bytes) 0x6ffffffe (VERNEED) 0x104b4 0x6fffffff (VERNEEDNUM) 2 0x6ffffff0 (VERSYM) 0x10488 0x00000000 (NULL) 0x0

需要的文件 libc.so.6 ld-linux.so.3 可以在buildroot中尋找,並複製到 rootfs/bin/

cd buildroot-2017.08/output/host/ find -name "libc.so.0"

尋找動態連結庫好麻煩啊 直接 -static 編譯算了 XD

other

番外篇-sf用法:sf 称为SPI flash sub-system,即SPI flash 子系统,用来在uboot里面操作SPI Flash的。下面列举一些sf常用的用法:

sf 用法
1.初始化SPI设备在SPI总线0上,速度是 50000000HZ
sf probe 0 50000000 

2.从flash偏移为0x100000地址处读取0x10000个字节到SDRAM的0x80C00000地址处
sf read 0x80C00000 0x100000 0x10000
                                  
3.从SDRAM的0x82000000地址处读取0x20000个字节写入到flash的 偏移为0x8000地址处
sf write 0x82000000 0x8000 0x20000

4.擦除flash地址偏移为0x0处, 到0x10000之间的擦除块, 擦除操作是以erase block为单位的, 要求offset和len参数必须是erase block对齐的
sf erase 0x0 0x10000     

5. 从sdram的addr地址读取len个字节,然后擦除何写入到flash偏移为 offset地址处          
sf update addr offset len


注意:sf read和sf update命令功能很相似,我们知道flash写前必须保证擦除过了,所以sf read操作前要我们自己保证已经擦除过了,而sf update,是先擦除要写的的地址,然后在自动写入数据。

荔枝派nano上手笔记(一)移植Uboot
荔枝派 Nano 全志 F1C100s 编译运行 Linux ubuntu并升级gcc
荔枝派Nano 全流程指南
编译和使用sunxi-tools
F1C100S/F1C200S系统构建
尝试从零构建F1C100s开发环境
sipeed文件
荔枝派nano 添加i2c
【荔枝派nano】试用体验——WIFI模块使用
WIFI配置
Licheepi Zero LCD驱动指南(BSP)
尝试从一开发F1C100s应用
利用lrz、lsz工具在linux与windows之间传输文件

My Business Card Runs Linux
thirtythreeforty/businesscard-linux
https://licheepizero.us/