天天看點

【linux項目】lichee nano linux燒寫

目錄

  • 前言
  • 參考:
  • 安裝交叉編譯鍊
  • 搭建 SPI FLASH 燒錄環境
  • 讓晶片進入燒寫模式
  • sunxi 燒寫指令
  • u-boot 裁剪
    • 拉取 u-boot 源碼
    • 配置 u-boot
    • 檢查 flash 驅動
    • 編譯、燒寫 u-boot
  • linux 裁剪
    • 擷取 linux 源碼
    • 配置 linux
    • 配置裝置樹
    • 編譯、燒寫 linux
  • roofs 裁剪
    • 擷取 buildroot 源碼
    • 配置 buildroot
    • 編譯、燒寫 buildroot
  • SPI FLASH 編譯燒寫
    • 根據自己的配置進行分區
    • 單個燒寫
    • 打包成一個檔案
  • 小知識

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

測試是否安裝成功。注意自己的安裝使用者。

安裝好編譯根據鍊後還需要安裝燒錄固件工具。這裡使用 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 模式。
  • 有一下兩種方法:
    1. 短接 flash 的 1、4 兩腳,重新上電,讓晶片找不到 flash,上電後松開短接,即可重新進入 fel 模式。
    2. 使用 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

           

  1. 确認是否進入 fel 模式指令:

    sudo sunxi-fel ver

  2. 燒錄指令:

    sudo sunxi-fel -p spiflash-write [燒錄的位址] [燒錄的檔案]

# 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

           

按需裁剪,一下為參考:

  • 了解下下面的

    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 晶片驅動。
# 1. 在代碼編輯器中 打開 ./drivers/mtd/spi/spi_flash_ids.c

# 2. 在 170 行左右添加如下代碼
{"xt25f128b",	   INFO(0x0b4018, 0x0,	64 * 1024,   256, RD_FULL | WR_QPP | SECT_4K) },

# 3. 儲存退出
           

編譯:

# 編譯代碼
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
           

目前擷取 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位址
           

# 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:

  • 鏡像檔案生成在 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
           

燒寫:

  1. 進入 fel 模式。
  2. 燒寫固件:

    sudo sunxi-fel -p spiflash-write [燒錄的位址] [燒錄的檔案]

整理的 rootfs 使用 buildroot 。

步驟:

  1. 在 https://buildroot.org/download.html 可以下載下傳到最新的代碼包。
  2. 解壓這個代碼包

    tar -xzvf buildroot-2021.08.tar.gz1

# 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     # 重新挂載根檔案系統到可讀寫

           

# 編譯比較慢,可以配老婆/女朋友聊聊天。 如果編譯不成功 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

           
  1. sudo sunxi-fel -p spiflash-write [燒錄的位址] [燒錄的檔案]

如:

分區序号 分區大小 分區作用 位址空間及分區名
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

。在該目錄下按下面格式建立檔案夾并存放對應固件:

  1. ls
     
     buildroot  linux  u-boot
               
  2. 把下面腳本檔案放到

    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
               
  3. 執行指令燒錄到開發闆:
    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'
           

使用注意:

  1. 在使用 sf 的其他指令之前必須先使用

    sf probe

    操作進行連接配接 flash。
    1. 如:sf probe 0 50000000,初始化總線 0 上的 FLASH,且速度為 50000000 Hz。

uboot bootz 參數

對于 ARM 來講,可以透過

bootz <kernel_addr> <initrd_address> <dtb_address>

的指令來啟動核心。

  • 第一個參數為核心映像的位址。
  • 第二個參數為 initrd 的位址,若不存在 initrd,可以用

    -

    代替。
  • dtb_address 作為 bootz 或者 bootm 的最後一次參數。