【linux專案】lichee nano linux燒寫
前言
lichee_nano 主控晶片為全志 FC1001S。
本筆記暫時以 lichee nano 為例子,以後可能會直接適配各類 FC1001S 的板子。
注意:使用 lichee nano 板子和 lichee 提供的映象時,需要注意這個板子的 flash 晶片型號,必要時需要修改驅動。
李柱明部落格:https://www.cnblogs.com/lizhuming/p/15487208.html
參考:
- 荔枝派 nano 全流程指南
- lichee 提供了很多指令碼,可以拿出來參考。
- 荔枝派環境搭建
安裝交叉編譯鏈
arm-linux-gnueabi
:
- 可以自己安裝需要的版本。
- 也可以參考下面例子:
- 該工具鏈存放位置自定義。
- 其中環境變數生命週期參考:環境變數生命週期
# 此處為獲取7.2.1版本,您可獲取其他版本或者通過連結直接下載 wget 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 tar -vxJf gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabi.tar.xz sudo cp -r ./gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabi /opt/ sudo vim /etc/bash.bashrc # 在檔案末尾 新增以下內容 PATH="$PATH:/opt/gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabi/bin" # 新增完畢 # 使路徑生效 source /etc/bash.bashrc
安裝好交叉編譯鏈後可用命令 arm-linux-gnueabi-gcc -v
測試是否安裝成功。注意自己的安裝使用者。
搭建 SPI FLASH 燒錄環境
安裝好編譯根據鏈後還需要安裝燒錄韌體工具。這裡使用 sunxi-tools:
# 0. 如果無安裝git 首先安裝git sudo apt-get install git # 1. 拉取 sunxi-tools 這個庫 git clone -b f1c100s-spiflash https://github.com/Icenowy/sunxi-tools.git # 2.進行安裝 cd sunxi-tools make && sudo make install # 3. 錯誤處理 # 3.1 如果出現 fatal error: libusb.h: No such file or directory 錯誤 sudo apt-get install libusb-1.0-0-dev # 3.2 fel.c:32:18: fatal error: zlib.h: 沒有那個檔案或目錄 sudo apt-get install zlib-devel # 4. 不出意外 現在已經安裝成功, 可以使用這個軟體進行燒寫。常用的命令有如下幾個 # 4.1 檢視晶片是否開啟了下載模式, 如果出現晶片資訊既可以燒錄 sudo sunxi-fel ver # 4.2 燒錄到 flash sudo xunxi-fel -p spiflash-write [燒錄的地址] [燒錄的檔案] # 4.3 燒錄到 記憶體中 sudo xunxi-fel -p write [燒錄的記憶體地址] [燒錄的檔案]
讓晶片進入燒寫模式
為了讓晶片能接收燒寫韌體,可讓晶片進入 fel 模式。
- 原理:當 flash 中無 引導資料或者無法找到 flash 晶片時, 便自動進入 fel 模式。
- 有一下兩種方法:
- 短接 flash 的 1、4 兩腳,重新上電,讓晶片找不到 flash,上電後鬆開短接,即可重新進入 fel 模式。
- 使用 U-boot 刪除 flash 中的引導資料:
# 在 u-boot 中使用如下指令進行刪除資料
# 1. 切換到 flash, 其中 0 為選擇的flash,50000000 為速度。官方文件這裡有錯誤。注意!
sf probe 0 50000000
# 2. 擦除flash, 為什麼擦除這段地址,請檢視spiflash編譯章節
sf erase 0 0x10000
# 3. 重啟
reset
# 4. 使用 sunxi-fel ver 即可找到晶片
sudo sunxi-fel ver
AWUSBFEX soc=00001663(F1C100s) 00000001 ver=0001 44 08 scratchpad=00007e00 00000000 00000000
sunxi 燒寫命令
- 確認是否進入 fel 模式命令:
sudo sunxi-fel ver
- 燒錄命令:
sudo sunxi-fel -p spiflash-write [燒錄的地址] [燒錄的檔案]
u-boot 裁剪
拉取 u-boot 原始碼
# 1. 使用git 拉取 u-boot, 這裡可以使用加速
git clone https://github.com/Lichee-Pi/u-boot.git
# 2. 檢視分支,並切換到對應分支
git branch -a
git checkout nano-v2018.01
# 3. 進行配置
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- licheepi_nano_spiflash_defconfig
配置 u-boot
按需裁剪,一下為參考:
- 瞭解下下面的
bootcmd
引數。就是驅動核心前執行的命令。一般主要做資料拷貝&執行啟動,如把裝置樹、kernel 拷貝到記憶體控制器 RAM 中。
# 1. 進行視覺化配置, 進入配置頁面
make ARCH=arm menuconfig
# 1.1 如何出現錯誤,安裝如下的包
sudo apt-get install libncurses5-dev libncursesw5-dev
# 2. 如果使用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
# 如果為 480*272 螢幕
x:480,y:272,depth:18,pclk_khz:10000,le:42,ri:8,up:11,lo:4,hs:1,vs:1,sync:3,vmode:0
LCD panel backlight pwm pin -> PE6 # 具體看原理圖
# 3. 修改 boot arguments ,傳輸到linux的引數
Enable boot arguments -> y
Boot arguments -> console=ttyS0,115200 panic=5 rootwait root=/dev/mtdblock3 rw rootfstype=jffs2
# 4. 修改bootcmd,啟動linux命令。可以具體瞭解一下 bootcmd 程式碼的含義,其中拷貝資料啟動linux
Enable a default value for bootcmd -y
bootcmd -> sf probe 0 50000000; sf read 0x80c00000 0x100000 0x4000; sf read 0x80008000 0x110000 0x400000; bootz 0x80008000 - 0x80C00000
# 5. 儲存退出
檢查 flash 驅動
- 新增自己的 FLASH 晶片驅動。
# 1. 在程式碼編輯器中 開啟 ./drivers/mtd/spi/spi_flash_ids.c
# 2. 在 170 行左右新增如下程式碼
{"xt25f128b", INFO(0x0b4018, 0x0, 64 * 1024, 256, RD_FULL | WR_QPP | SECT_4K) },
# 3. 儲存退出
編譯、燒寫 u-boot
編譯:
# 編譯程式碼
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j11
# 如果最後出現下面語句,編譯成功
BINMAN u-boot-sunxi-with-spl.bin
# 錯誤處理,scripts/Makefile.build:425: recipe for target 'scripts/dtc/pylibfdt' failed
sudo apt-get install swig python-dev python3-dev
編譯成功的檔案在 u-boot 目錄下的,u-boot-sunxi-with-spl.bin
。 把他們燒寫到記憶體或者 flash:
# 燒寫到flash中
sudo sunxi-fel -p spiflash-write 0 u-boot-sunxi-with-spl.bin
# 燒寫到 sram 中,在測試的時候使用(掉電不保護)
sudo sunxi-fel uboot u-boot-sunxi-with-spl.bin
驗證:
# 測試 flash 是否成功,如果出現下面程式碼既成功
sf probe 0 50000000
SF: Detected xt25f128b with page size 256 Bytes, erase size 4 KiB, total 16 MiB
# 測試 讀取
boot
linux 裁剪
獲取 linux 原始碼
目前獲取 uboot 和 linux 原始碼都是獲取 lichee 或者全志官方推薦的。
# 1. 因為 linux太大了,建議只拉取單個分支. 可以使用加速
git clone --depth=1 -b f1c100s-480272lcd-test https://github.com/Icenowy/linux.git
# 2. 下載 .config 檔案,放到原始碼的目錄下,如果檔名稱有變化。改為 .config
替換 .config 檔案:.config
git 拉取有時速度很慢,建議做如下配置:
sudo vim /etc/hosts
# 新增下面兩行
192.30.253.112 github.com
151.101.73.194 github.global.ssl.fastly.net
# 新增完成
# 可自行通過dns檢測網站檢測github.global.ssl.fastly.net,更換為更快的ip地址
配置 linux
# 1. 圖形化配置
make ARCH=arm menuconfig
# 2. 配置 spiflash
Device Drivers
SPI support
Allwinner A10 SoCs SPI controller ->n # 不選擇
Allwinner A31 SPI Controller -> y
# 3. 配置 MTD
Device Drivers
Memory Technology Device (MTD) support
Command line partitioning table parsing -> y
Caching block device access to MTD devices -> y
# 4.新增 File systems
File systems
Miscellaneous filesystems
Journalling Flash File System v2 (JFFS2) support -> y
# 下面全選
# 5. 儲存退出
# 注意, 要把配置的選項選擇為 * 而不是 M
配置裝置樹
-
新增 flash 驅動,需要查看板子使用的 flash 晶片:
# 1. 開啟 ./drivers/mtd/spi-nor/spi-nor.c 1186行. 新增如下程式碼. 對flash支援 { "xt25f128b", INFO(0x0b4018, 0, 64 * 1024, 256, 0) },
-
配置裝置樹,若無顯示器,則顯示部分不用配置:
# 1. 開啟 /arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dts 檔案 # 2. 修改 顯示驅動 panel: panel { # 修改為 800*480 的螢幕 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>; }; }; }; # 3. 新增對spiflash支援 &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>; }; }; }; };
編譯、燒寫 linux
編譯 linux:
- 映象檔案生成在 arch/arm/boot/zImage
- 裝置樹檔案在 arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dtb
- 編譯步驟:
# 1. 編譯 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j11 # 錯誤處理 fatal error: openssl/bio.h: sudo apt-get install libssl-dev
單獨編譯裝置樹:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- dtbs -j11
燒寫:
- 進入 fel 模式。
- 燒寫韌體:
sudo sunxi-fel -p spiflash-write [燒錄的地址] [燒錄的檔案]
roofs 裁剪
整理的 rootfs 使用 buildroot 。
獲取 buildroot 原始碼
步驟:
- 在 https://buildroot.org/download.html 可以下載到最新的程式碼包。
- 解壓這個程式碼包
tar -xzvf buildroot-2021.08.tar.gz1
。
配置 buildroot
# 1. 開啟圖形化介面
make menuconfig
# 2. 選擇處理器
Target options
Target Architecture (ARM (little endian))
Target Variant arm926t
# 3. 啟動軟連結等
System configuration
Use syslinks to /usr .... # 啟動 連結
Enable root login # root 登入
Run a getty after boot # 輸入密碼
remount root filesystem # 重新掛載根檔案系統到可讀寫
編譯、燒寫 buildroot
編譯:
# 編譯比較慢,可以配老婆/女朋友聊聊天。 如果編譯不成功 make clean 重來
make
編譯完成的根目錄在 output/images/rootfs.tar
. 複製出來解壓:
# 複製出來
cp output/images/rootfs.tar ../
# 建立跟目錄資料夾
mkdir rootfs
# 解壓到這個資料夾
tar -xvf rootfs.tar -C rootfs/
# 安裝 jffs2
sudo apt-get install mtd-utils
# 製作映象, 得到 jffs2.img 可以燒錄到開發板
mkfs.jffs2 -s 0x100 -e 0x10000 --pad=0xAF0000 -d rootfs/ -o jffs2.img
燒寫:
- 進入 fel 模式。
- 燒寫韌體:
sudo sunxi-fel -p spiflash-write [燒錄的地址] [燒錄的檔案]
SPI FLASH 編譯燒寫
根據自己的配置進行分割槽
如:
分割槽序號 | 分割槽大小 | 分割槽作用 | 地址空間及分割槽名 |
---|---|---|---|
mtd0 | 1MB (0x100000) | spl+uboot | 0x0000000-0x0100000 : “uboot” |
mtd1 | 64KB (0x10000) | dtb 檔案 | 0x0100000-0x0110000 : “dtb” |
mtd2 | 4MB (0x400000) | linux 核心 | 0x0110000-0x0510000 : “kernel” |
mtd3 | 剩餘 (0xAF0000) | 根檔案系統 | 0x0510000-0x1000000 : “rootfs” |
單個燒寫
-
把
u-boot
燒寫到第一分割槽sudo sunxi-fel -p spiflash-write 0 u-boot-sunxi-with-spl.bin
-
把
dtb
檔案燒寫到第二分割槽sudo sunxi-fel -p spiflash-write 0x0100000 suniv-f1c100s-licheepi-nano.dtb
-
把
zImage
映象檔案燒寫到第三分割槽sudo sunxi-fel -p spiflash-write 0x0110000 zImage
-
我們把
根檔案系統
燒寫到第四分割槽sudo sunxi-fel -p spiflash-write 0x0510000 jffs2.img
打包成一個檔案
上面是一個一個韌體燒寫,我們可以通過指令碼把其打包成一個韌體進行燒寫:
建立一個專門放韌體的目錄,如 my_bin
。在該目錄下按下面格式建立資料夾並存放對應韌體:
-
ls buildroot linux u-boot
-
把下面指令碼檔案放到
my_bin
目錄下,執行,output
為最後輸出的檔案。#! /bin/bash rm -rf ./output mkdir ./output rm -rf ./rootfs mkdir ./rootfs dd if=/dev/zero of=flashimg.bin bs=1M count=16 &&\ dd if=./u-boot/u-boot-sunxi-with-spl.bin of=flashimg.bin bs=1K conv=notrunc &&\ dd if=./linux/suniv-f1c100s-licheepi-nano.dtb of=flashimg.bin bs=1K seek=1024 conv=notrunc &&\ dd if=./linux/zImage of=flashimg.bin bs=1K seek=1088 conv=notrunc &&\ tar -xf ./buildroot/rootfs.tar -C ./rootfs &&\ 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 ./output rm -rf jffs2.img
-
執行命令燒錄到開發板:
sudo sunxi-fel -p spiflash-write 0 flashimg.bin
小知識
uboot sf 命令用法
uboot 中如果支援 spi/qspi flash, 那麼可以使用 sf 的 erase, read, write 命令操作 spi flash。
sf read
用來讀取 flash 資料到記憶體。sf write
寫記憶體資料到 flash。sf erase
擦除指定位置,指定長度的 flash 內容, 在進行寫 flash 的時候一定要先進行擦除,否則會失敗,因為 flash 只能從 1 變為 0。
具體參考:
sf - SPI flash sub-system
Usage:
sf probe [[bus:]cs] [hz] [mode] - init flash device on given SPI bus and chip select
sf read addr offset len - read `len' bytes starting at
`offset' to memory at `addr'
sf write addr offset len - write `len' bytes from memory
at `addr' to flash at `offset'
sf erase offset [+]len - erase `len' bytes from `offset'
`+len' round up `len' to block size
sf update addr offset len - erase and write `len' bytes from memory
at `addr' to flash at `offset'
使用注意:
- 在使用 sf 的其他命令之前必須先使用
sf probe
操作進行連線 flash。- 如:sf probe 0 50000000,初始化匯流排 0 上的 FLASH,且速度為 50000000 Hz。
uboot bootz 引數
對於 ARM 來講,可以透過 bootz <kernel_addr> <initrd_address> <dtb_address>
的命令來啟動核心。
- 第一個引數為核心映像的地址。
- 第二個引數為 initrd 的地址,若不存在 initrd,可以用
-
代替。 - dtb_address 作為 bootz 或者 bootm 的最後一次引數。