• 【linux项目】lichee nano linux烧写



    前言

    lichee_nano 主控芯片为全志 FC1001S。

    本笔记暂时以 lichee nano 为例子,以后可能会直接适配各类 FC1001S 的板子。

    注意:使用 lichee nano 板子和 lichee 提供的镜像时,需要注意这个板子的 flash 芯片型号,必要时需要修改驱动。

    李柱明博客:https://www.cnblogs.com/lizhuming/p/15487208.html

    参考:

    安装交叉编译链

    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 模式
    • 有一下两种方法:
      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
    
    

    sunxi 烧写命令

    1. 确认是否进入 fel 模式命令:sudo sunxi-fel ver
    2. 烧录命令: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
    

    烧写:

    1. 进入 fel 模式。
    2. 烧写固件:sudo sunxi-fel -p spiflash-write [烧录的地址] [烧录的文件]

    roofs 裁剪

    整理的 rootfs 使用 buildroot 。

    获取 buildroot 源码

    步骤:

    1. https://buildroot.org/download.html 可以下载到最新的代码包。
    2. 解压这个代码包 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
    
    

    烧写:

    1. 进入 fel 模式。
    2. 烧写固件: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。在该目录下按下面格式创建文件夹并存放对应固件:

    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 的最后一次参数。
  • 相关阅读:
    16、cgminer学习之:popen函数和system函数详解(执行系统命令)
    16、cgminer学习之:pthread_mutex_init和pthread_cond_init
    15、python学习手册之:元组、文件及其他
    15、python学习手册之:列表和字典
    Chorme浏览器中使用flash debug版本
    Best Practices
    Titled-Contributing to Tiled
    Titled
    VS2010配合SVN搭建使用
    Google code问题记录
  • 原文地址:https://www.cnblogs.com/lizhuming/p/15487208.html
Copyright © 2020-2023  润新知