对于ARM的启动,系统升级,烧写过程和文件系统等方面的总结分析

本文所述的ARM的指的是Cortex A系列以及ARM9,ARM11,跑Linux操作系统。对于CortexM系列并不一定完全适用;

谈到ARM以及启动和烧写等方面,首先我们要明确一下几个关键词:Uboot,Cmdline,启动方式选择,文件系统格式,存储介质,如NAND,EMMC,SD卡等

下面一个一个做相关介绍:

启动方式:

  1. 一般CPU都可以配置为从多种介质启动,比如SPI Nor Flash,NAND,EMMC,SD卡,U盘等
  2. 大致原理是CPU内部ROM有一段固化的启动代码,根据CPU配置引脚,判断启动位置,然后从外部介质读取数据启动
  3. 一般启动介质的前一部分代码的作用必须是:初始化硬件参数,自身拷贝
  4. 关于自拷贝:因为CPU内部RAM很小,因此只能读取一部分启动介质的数据即Uboot到内部RAM运行,所以Uboot前一部分的工作需要将自身剩余部分拷贝到外部RAM中,然后加载运行


Uboot:

  1. 主要作用:引导Linux系统(主要是从存储介质的哪个地方读取Kernel,传递什么样的启动参数)
  2. 其他功能:支持很多命令,主要是存储控制和网络命令,最终目的还是引导和升级系统用
  3. 常用操作:TFTP,NAS,Flash操作,UBI操作,Setenv,boot等
  4. 一般升级系统流程:使用tftp方式从主机下载kernel及文件系统等文件,然后使用flash等命令烧写到存储介质如NAND,最后设定启动参数,然后引导系统启动;
  5. 一般调试流程,介绍2种:
    1. 使用NAS从主机直接加载文件系统,直接在线调试,快捷方便
    2. 设定从SD卡启动,从SD卡加载kernel和文件系统调试


CMDLINE:

  1. 一般由Uboot传递给Kernel,或者Kernel中配置写死不过一般很少见
  2. 主要2个参数:
    1. 第一,指定console设备,用于打印输出及做控制台用
    2. 第二,指定rootfs挂载分区和类型
  3. 看2个例子:
    1. 从NAND启动,/proc/cmdline,加载的是UBI文件系统,位置在mtd3
      [cpp]  view plain  copy
      1. console=ttymxc0,115200 ubi.mtd=3 root=ubi0:rootfs rootfstype=ubifs mtdparts=gpmi-nand:5m(boot),10m(kernel),1m(dtb),-(rootfs)  
    2. 从SD卡启动,/proc/cmdline,加载的是ext4文件系统,位置在sd卡第二分区mmcblk0p2
      [cpp]  view plain  copy
      1. console=ttymxc0,115200 root=/dev/mmcblk0p2 rootwait rw rootdelay=5 mem=256M fstype=ext4 mtdparts=gpmi-nand:5m(boot),10m(kernel),1m(dtb),-(rootfs)  

存储介质:

主要介绍Raw  Flash 及 FTL devices区别

Flash特点:写入前需要先擦除,有寿命且不长,而且容易产生坏块

RAW Flash:即裸芯片,没有控制器,针对其主要操作有擦除,读和写

FTL Device: 在裸芯片上加了控制器,比如SD卡,U盘等;加了控制器后,只需要读和写就行了,不需要擦除。控制器做了一系列的工作:擦除,磨损平衡,磨损算法等等,一个控制器算法的好坏直接决定了设备的使用寿命。


文件系统:

  1. FAT:windows常用文件系统,一般U盘,sd卡即为fat格式
  2. ext2/3/4,Linux常用文件系统,一般用于FTL Device,即只有读和写
  3. JFFS2,Linux常用,一般用于容量较小的Flash,且是Raw Flash,MTD设备
  4. UBIFS,Linux常用文件系统,只能用于Raw Flash,因为kernel ubi子系统,有相关的磨损平衡算法,可以保证效率
  5. SD卡启动,文件系统挂载情况:
    [cpp]  view plain  copy
    1. # mount  
    2. /dev/root on / type ext4 (rw,noatime,data=ordered)  
    3. proc on /proc type proc (rw,nosuid,nodev,noexec,noatime)  
    4. sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,noatime)  
    5. tmpfs on /tmp type tmpfs (rw,nosuid,nodev,noatime)  
    6. tmpfs on /dev type tmpfs (rw,nosuid,relatime,size=512k,mode=755)  
    7. devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,mode=600)  
    8. debugfs on /sys/kernel/debug type debugfs (rw,noatime)  
    9. #  
    10. # cat /proc/mtd  
    11. dev:    size   erasesize  name  
    12. mtd0: 00500000 00020000 "boot"  
    13. mtd1: 00a00000 00020000 "kernel"  
    14. mtd2: 00100000 00020000 "dtb"  
    15. mtd3: 0f000000 00020000 "rootfs"  
  6. NAND启动,文件系统挂载情况:
    [cpp]  view plain  copy
    1. # mount  
    2. ubi0:rootfs on / type ubifs (rw,relatime)  
    3. devtmpfs on /dev type devtmpfs (rw,relatime,size=89164k,nr_inodes=22291,mode=755)  
    4. proc on /proc type proc (rw,relatime)  
    5. devpts on /dev/pts type devpts (rw,relatime,gid=5,mode=620)  
    6. tmpfs on /dev/shm type tmpfs (rw,relatime,mode=777)  
    7. tmpfs on /tmp type tmpfs (rw,relatime)  
    8. tmpfs on /run type tmpfs (rw,nosuid,nodev,relatime,mode=755)  
    9. sysfs on /sys type sysfs (rw,relatime)  
    10. #  
    11. # cat /proc/mtd  
    12. dev:    size   erasesize  name  
    13. mtd0: 00500000 00020000 "boot"  
    14. mtd1: 00a00000 00020000 "kernel"  
    15. mtd2: 00100000 00020000 "dtb"  
    16. mtd3: 0f000000 00020000 "rootfs"  


烧写过程:

  1. 一般从SD卡等外部方式启动,在Uboot中,使用flash命令及UBI命令分别烧写uboot,dtb,kernel,rootfs到对应的分区即可
  2. 第二使用芯片厂家的烧写工具,如nxp的 mfgtoos,在pc上通过usb烧写文件
  3. 如已有uboot,在uboot中从sd卡,U盘等读取文件烧写;或tftp从pc下载文件烧写


升级过程:

  1. 此升级指的是Uboot OK的前提下做Uboot,kernel,rootfs等升级
  2. 通过SD卡升级,一般是首先在PC上制作SD卡启动分区,通过官方的工具烧写升级文件到SD卡即可;此处的升级文件分两个方面:
    1. 最小升级内核,并且包含升级脚本,此脚本会将目标文件烧写到存储介质中
    2. 目标升级文件,即要烧写到比如NAND中的文件
  3. 以NXP SD卡升级为例说明此过程:
    1. 首先是Uboot启动过程:
      [cpp]  view plain  copy
      1. U-Boot 2016.03-mys-imx6ulx+gca7b81f (Apr 27 2017 - 07:55:51 +0800)  
      2.   
      3. CPU:   Freescale i.MX6ULL rev1.0 528 MHz (running at 396 MHz)  
      4. CPU:   Commercial temperature grade (0C to 95C) at 39C  
      5. Reset cause: POR  
      6. Board: MX6ULL 14x14 EVK  
      7. I2C:   ready  
      8. DRAM:  512 MiB  
      9. MMC:   FSL_SDHC: 0, FSL_SDHC: 1  
      10. *** Warning - bad CRC, using default environment  
      11.   
      12. Display: TFT43AB (480x272)  
      13. Video: 480x272x24  
      14. In:    serial  
      15. Out:   serial  
      16. Err:   serial  
      17. switch to partitions #0, OK  
      18. mmc0 is current device  
      19. Net:   Board Net Initialization Failed  
      20. No ethernet found.  
      21. Normal Boot  
      22. Hit any key to stop autoboot:  0  
      23. switch to partitions #0, OK  
      24. <span style="color:#FF0000;">mmc0 is current device</span>  
      25. switch to partitions #0, OK  
      26. mmc0 is current device  
      27. <span style="color:#FF0000;">reading boot.scr</span>  
      28. 423 bytes read in 10 ms (41 KiB/s)  
      29. <span style="color:#FF0000;">Running bootscript from mmc ...</span>  
      30. ## Executing script at 80800000  
      31. <span style="color:#FF0000;">reading zImage</span>  
      32. 6789824 bytes read in 302 ms (21.4 MiB/s)  
      33. reading mys-imx6ull-14x14-evk-gpmi-weim.dtb  
      34. 36951 bytes read in 20 ms (1.8 MiB/s)  
      35. Kernel image @ 0x83000000 [ 0x000000 - 0x679ac0 ]  
      36. ## Flattened Device Tree blob at 84000000  
      37.    Booting using the fdt blob at 0x84000000  
      38.    Using Device Tree in place at 84000000, end 8400c056  
      39. <span style="color:#FF0000;">  
      40. Starting kernel ..</span>  
    2. 最小系统加载启动完毕后,运行升级脚本
    3. [cpp]  view plain  copy
      1. VFS: Mounted root (ext4 filesystem) on device 179:2.  
      2. devtmpfs: mounted  
      3. Freeing unused kernel memory: 432K (80b54000 - 80bc0000)  
      4. INIT: version 2.88 booting  
      5. Starting udev  
      6. udevd[114]: starting version 3.1.5  
      7. random: udevd urandom read with 32 bits of entropy available  
      8. EXT4-fs (mmcblk0p2): re-mounted. Opts: data=ordered  
      9. bootlogd: cannot allocate pseudo tty: No such file or directory  
      10. FAT-fs (mmcblk0p1): Volume was not properly unmounted. Some data may be corrupt. Please run fsck.  
      11. ALSA: Restoring mixer settings...  
      12. /usr/sbin/alsactl: load_state:1735: No soundcards found...  
      13. INIT: Entering runlevel: 5  
      14. Starting system message bus: dbus.  
      15.   
      16. System update start ...  
      17. prepare files are okay  


    4. 升级脚本分析:
    5. [cpp]  view plain  copy
      1. root@mys6ull14x14:/run/media/mmcblk0p2# cat usr/bin/flash_nand.sh  
      2. #!/bin/sh  
      3. part_uboot=0  
      4. part_kernel=1  
      5. part_dtb=2  
      6. part_rootfs=3  
      7.   
      8. echo heartbeat > /sys/class/leds/user/trigger  
      9.   
      10. mfg_path=/run/media/mmcblk0p1/mfg-images    
      11.   
      12. //升级目标文件  
      13.   
      14. uboot=${mfg_path}/u-boot.imx   
      15. kernel=${mfg_path}/zImage  
      16. dtb=${mfg_path}/gpmi-weim.dtb  
      17. rootfs=${mfg_path}/core-image-base.rootfs.tar.xz  
      18.   
      19. if [ -d $mfg_path ] && [ -s $uboot ] && [ -s $kernel ] && [ -s $dtb ] && [ -s $rootfs ]  
      20. then  
      21.     echo "prepare files are okay"  
      22. else  
      23.     echo 0 > /sys/class/leds/user/brightness  
      24.     echo "file or directory not exist"  
      25. fi  
      26.   
      27. 直接使用Flash命令烧写Uboot到对应分区  
      28. echo "Flashing uboot"  
      29. flash_erase /dev/mtd${part_uboot} 0 0 && kobs-ng init -x -v ${uboot}  
      30. if [ $? -eq 0 ]  
      31. then  
      32.     echo "Flash uboot okay"  
      33. else  
      34.     echo "Flash uboot failed"  
      35.     echo 0 > /sys/class/leds/user/brightness  
      36.     exit  
      37. fi  
      38.   
      39. 直接使用Flash命令烧写kernel到对应分区  
      40.   
      41.   
      42. echo "Flashing kernel"  
      43. flash_erase /dev/mtd${part_kernel} 0 0 && nandwrite -p /dev/mtd${part_kernel} -p ${kernel}  
      44. if [ $? -eq 0 ]  
      45. then  
      46.     echo "Flash kernel okay"  
      47. else  
      48.     echo "Flash kernel failed"  
      49.     echo 0 > /sys/class/leds/user/brightness  
      50.     exit  
      51. fi  
      52.   
      53. 直接使用Flash命令烧写dtb到对应分区  
      54.   
      55. echo "Flashing dtb"  
      56. flash_erase /dev/mtd${part_dtb} 0 0 && nandwrite -p /dev/mtd${part_dtb} -p ${dtb}  
      57. if [ $? -eq 0 ]  
      58. then  
      59.     echo "Flash dtb file okay"  
      60. else  
      61.     echo "Flash dtb file failed"  
      62.     echo 0 > /sys/class/leds/user/brightness  
      63.     exit  
      64. fi  
      65.   
      66. 烧写rootfs比较特别,此处是使用ubifs,因此需要先使用ubi命令在NAND上建立好文件系统格式  
      67.   
      68. echo "Flashing rootfs"  
      69. flash_erase /dev/mtd${part_rootfs} 0 0  
      70. if [ $? -ne 0 ]  
      71. then  
      72.     echo "erase /dev/mtd${part_rootfs} fail"  
      73.     echo 0 > /sys/class/leds/user/brightness  
      74.     exit  
      75. fi  
      76.   
      77. ubiformat /dev/mtd${part_rootfs}  
      78. if [ $? -ne 0 ]  
      79. then  
      80.     echo "format /dev/mtd${part_rootfs} fail"  
      81.     echo 0 > /sys/class/leds/user/brightness  
      82.     exit  
      83. fi  
      84.   
      85. ubiattach /dev/ubi_ctrl -m ${part_rootfs}  
      86. if [ $? -ne 0 ]  
      87. then  
      88.     echo "attach /dev/mtd${part_rootfs} fail"  
      89.     echo 0 > /sys/class/leds/user/brightness  
      90.     exit  
      91. fi  
      92.   
      93. ubimkvol /dev/ubi0 -Nrootfs -m  
      94. if [ $? -ne 0 ]  
      95. then  
      96.     echo "make volume /dev/mtd${part_rootfs} fail"  
      97.     echo 0 > /sys/class/leds/user/brightness  
      98.     exit  
      99. fi  
      100.   
      101. mkdir -p /run/media/mtd${part_rootfs} \  
      102.  && mount -t ubifs ubi0:rootfs /run/media/mtd${part_rootfs}  
      103. if [ $? -ne 0 ]  
      104. then  
      105.     echo "mount /dev/mtd${part_rootfs} fail"  
      106.     echo 0 > /sys/class/leds/user/brightness  
      107.     exit  
      108. fi  
      109.   
      110. 建立好ubi格式之后,直接将rootfs压缩包解压到对应分区即可;  
      111.   
      112. tar xvf ${rootfs} -C /run/media/mtd${part_rootfs}  
      113. if [ $? -eq 0 ]  
      114. then  
      115.     echo "Flash filesystem okay"  
      116.     sync && sync && sync  
      117.     echo none > /sys/class/leds/user/trigger  
      118.     echo 1 > /sys/class/leds/user/brightness  
      119. else  
      120.     echo "Flash filesystem failed"  
      121.     echo 0 > /sys/class/leds/user/brightness  
      122.     umount /run/media/mtd${part_rootfs}  
      123.     exit  
      124. fi  
      125. umount /run/media/mtd${part_rootfs}  
      126. echo "Programming success"  
      127. echo "You need reboot the board"  



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值