嵌入式Linux--U-Boot(九)通过TFT/NFS网络更新U-Boot、Kernel、DTB文件

参考一:嵌入式Linux–U-Boot(四)MMC命令使用
参考二:嵌入式Linux–U-Boot(六)FAT和EXT格式文件系统命令使用

O、恍然大悟

迷迷糊糊、曲曲折折、来来回回,恍然大悟!

  • 有文件系统格式的就用带文件系统格式的命令操作
  • 没有文件系统格式的就直接用mmc操作

1、EMMC上面有3个分区

  • (1)分区0是没有文件系统格式
  • (2)分区1是FAT文件系统格式
  • (3)分区2是EXT4文件系统格式

证明:各个分区的文件格式:

=> fstype mmc 1:0
Failed to mount ext2 filesystem...
** Unrecognized filesystem type **
=> fstype mmc 1:1
fat
=> fstype mmc 1:2
ext4

2、分区0介绍

  • (1)前两个块/扇区存放了分区表,因此可以被mmc part识别到,这个分区表里面规定了分区1和分区2的大小(那为啥本身自己分区0没有被识别到呢?)。
  • (2)从第三个块/扇区开始存放uboot.imx文件,这也是更新Uboot的基础。

证明:由于分区0有分区表所以可以识别出来:

  • 第一步:设置分区0为当前设备分区
  • 第二步:使用mmc part识别
=> mmc dev 1 0
switch to partitions #0, OK
mmc1(part 0) is current device
=> mmc part

Partition Map for MMC device 1  --   Partition Type: DOS

Part    Start Sector    Num Sectors     UUID            Type
  1     20480           262144          3092ce11-01     0c
  2     282624          14987264        3092ce11-02     83

3、分区1介绍

  • (1)分区1是FAT的文件系统格式,因此可以使用fatls mmc 1:1命令来识别该分区下的文件和目录
  • (2)分区1里面一般存储的是kernel和dtb文件(内核和设备树文件),所有操作以文件名为对象。
  • (3)由于分区1里面没有分区表,所以无法被mmc part命令识别到

证明:

=> fatls mmc 1:1
  6788696   zimage
    38823   imx6ull-14x14-emmc-4.3-800x480-c.dtb
    39655   imx6ull-14x14-emmc-hdmi.dtb

3 file(s), 0 dir(s)

证明无法被识别到分区表:

  • 第一步:设置分区1为当前设备分区
  • 第二步:使用mmc part识别
=> mmc dev 1 1
switch to partitions #1, OK
mmc1(part 1) is current device
=> mmc part

Partition Map for MMC device 1  --   Partition Type: DOS

Part    Start Sector    Num Sectors     UUID            Type
bad MBR sector signature 0x0000

4、分区2介绍

  • (1)分区2是EXT4的文件系统格式,因此可以使用ext4ls mmc 1:2来识别该分区下的文件和目录
  • (2)分区2里面一般存储着的是根文件系统
  • (3)由于分区2里面没有分区表,所以无法被mmc part命令识别到
=> ext4ls mmc 1:2
<DIR>       4096 .
<DIR>       4096 ..
<DIR>      16384 lost+found
<DIR>       4096 bin
<DIR>       4096 boot
<DIR>       4096 dev
<DIR>       4096 etc
<DIR>       4096 home
<DIR>       4096 lib
<DIR>       4096 media
<DIR>       4096 mnt
<DIR>       4096 opt
<DIR>       4096 proc
<DIR>       4096 run
<DIR>       4096 sbin
<DIR>       4096 sys
<SYM>          8 tmp
<DIR>       4096 usr
<DIR>       4096 var
<DIR>       4096 .cache

证明无法被识别到分区表:

  • 第一步:设置分区2为当前设备分区
  • 第二步:使用mmc part识别
=> mmc dev 1 2
switch to partitions #2, OK
mmc1(part 2) is current device
=> mmc part

Partition Map for MMC device 1  --   Partition Type: DOS

Part    Start Sector    Num Sectors     UUID            Type
bad MBR sector signature 0x0000

一、前提

更新前得知道EMMC里面的存储空间的分配!比如:

  • Uboot从哪里开始到哪里结束:可以知道从哪里开始(从第三个块也就是块2开始),结束由uboot的文件大小决定(大小/512有余数就加1)也是以块为单位,没有具体的物理地址(?)。
  • kernel从哪里开始到哪里结束:没有必要知道从哪开始从哪里结束!因为kernel已经是作为一个文件存放在文件系统里面了,更新时只需要由文件名来进行更新即可。
  • dtb从哪里开始到哪里结束:和kernel一样,都是已经放在文件系统里面的了,没有必要知道从哪开始从哪里结束!

1、获取一些基本信息

(1)mmc info基本信息

=> mmc info
Device: FSL_SDHC
Manufacturer ID: 15
OEM: 100
Name: 8GTF4
Tran Speed: 52000000
Rd Block Len: 512
MMC version 4.0
High Capacity: Yes
Capacity: 7.3 GiB
Bus Width: 8-bit
Erase Group Size: 512 KiB

 当前选中的MMC设备是EMMC,版本为4.0,容量为7.3GiB(EMMC
为 8GB),速度为 52000000Hz=52MHz,8 位宽的总线,每个块的大小是512Byte,每一次擦的最小单位是512KB。

(2)mmc part分区分布

  • 通过Uboot的mmc dev命令来选择设备

    • mmc dev 0 :SD卡设备
    • mmc dev 1 :EMMC 设备
  • 通过Uboot的mmc part命令来查看这些存储设备的分区

  • 首先设置分区0为当前设备:mmc dev 1 0,如果设置其他分区为当前设备会显示bad MBR sector signature 0x0000

  • 再查看其分区:mmc part

=> mmc dev 1 0
switch to partitions #0, OK
mmc1(part 0) is current device
=> mmc part

Partition Map for MMC device 1  --   Partition Type: DOS

Part    Start Sector    Num Sectors     UUID            Type
  1     20480           262144          3092ce11-01     0c
  2     282624          14987264        3092ce11-02     83

从上面可以看出,此时 EMMC 有两个分区,并由mmc info命令可知每个块的大小是512Byte:

  • 分区1:开始块 20480,块数量:262144
  • 分区2:开始块 282624,块数量:14987264

推理出:

分区起始块结束块块数量分区大小
第0分区0204802048010MiB
第1分区20480282624262144128MiB
第2分区28262415269888149872647318MiB

如果 EMMC 里面烧写了 Linux 系统的话,EMMC 是有3 个分区的:

  • 第 0 个分区存放 uboot
  • 第 1 个分区存放 Linux 镜像文件和设备树
  • 第 2 个分区存放根文件系统

 但是在上面只有两个分区,那是因为第 0 个分区没有格式化,所以识别不出来,实际上第 0 个分区是存在的。

=> fatls mmc 1:1
  6788696   zimage
    38823   imx6ull-14x14-emmc-4.3-800x480-c.dtb
    39655   imx6ull-14x14-emmc-hdmi.dtb

3 file(s), 0 dir(s)

2、总结

  • 使用mmc dev命令来选择当前设备分区的时候,只有分区0是可以被mmc part识别出分区大小的,那是因为只有分区0的前两个块/扇区里面保存着分区表,其他分区都没有保存分区表
  • 如果要使用fatls mmc 1:x命令查看各个分区,只有分区1是可以被识别出来的,因为分区0和分区2没有被初始化为FAT文件格式所以无法被fat的命令识别。

二、在Uboot中更新Uboot

 可以使用命令“mmc write”来升级 uboot,也就是在 uboot 中更新 uboot。这里要用到 nfs 或者 tftp 命令,通过 nfs 或者 tftp 命令将新的 u-boot.imx 下载到开发板的 DRAM 中,然后再使用命令“mmc write”将其写入到 MMC设备中。

=> tftp 80800000 u-boot.imx
FEC1 Waiting for PHY auto negotiation to complete.... done
Using FEC1 device
TFTP from server 192.168.0.120; our IP address is 192.168.0.121
Filename 'u-boot.imx'.
Load address: 0x80800000
Loading: ###########################
         36.1 KiB/s
done
Bytes transferred = 384000 (5dc00 hex)

 u-boot.imx 大小为 384000 字节,384000/512=750,所以我们要向 EMMC 中写入750 个块,如果有小数的话就要加 1 个块。使用命令“mmc write”从 EMMC分区 0 第 2 个块(扇区)开始烧写,一共烧写 750(0x2EE)个块。

千万不要写 SD 卡或者 EMMC 的前两个块(扇区),里面保存着分区表!

EMMC更新

mmc dev 1 0               //切换到 EMMC 分区 0
tftp 80800000 u-boot.imx  //下载 u-boot.imx 到 DRAM
mmc write 80800000 2 2EE  //烧写 u-boot.imx 到 EMMC 中
mmc partconf 1 1 0 0      //分区配置,EMMC 需要这一步!

SD卡更新

mmc dev 0 0               //切换到 SD卡 分区 0
tftp 80800000 u-boot.imx  //下载 u-boot.imx 到 DRAM
mmc write 80800000 2 2EE  //烧写 u-boot.imx 到 SD卡 中

三、在Uboot中更新Kernel和DTB

 uboot 默认没有使能 fatwrite 命令,需要修改板子配置头文件,比如 mx6ullevk.h、mx6ull_alientek_emmc.h 等等,板子不同,其配置头文件也不同。找到自己开发板对应的配置头文件然后添加如下一行宏定义来使能 fatwrite 命令:

#define CONFIG_FAT_WRITE /* 使能 fatwrite 命令 */

 fatwirte 命令用于将 DRAM 中的数据写入到 MMC 设备中,命令格式如下:

fatwrite <interface> <dev[:part]> <addr> <filename> <bytes>

 interface 为接口,比如 mmc,dev 是设备号,part 是分区,addr 是要写入的数据在 DRAM中的起始地址,filename 是写入的数据文件名字,bytes 表示要写入多少字节的数据。

 我们可以通过 fatwrite 命令在 uboot 中更新 linux 镜像文件和设备树。我们以更新 linux 镜像文件 zImage为例,首先将正点原子 I.MX6U-ALPHA 开发板提供的 zImage 镜像文件拷贝到 Ubuntu 中的tftpboot 目录下,zImage 镜像文件放到了开发板光盘中,路径为:开发板光盘->8、开发板系统 镜像->zImage。

1、拷贝kernel和dtb到DDR

  • 使用命令将内核映像文件从tft服务器下载到DDR地址0x80800000tft 80800000 zImage
  • 使用命令将设备树文件从tft服务器下载到DDR地址0x83000000tft 83000000 imx6ull_liefyuan_emmc.dtb
=> tftp 80800000 zImage
Using FEC1 device
TFTP from server 192.168.0.120; our IP address is 192.168.0.121
Filename 'zImage'.
Load address: 0x80800000
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ########
         2.4 MiB/s
done
Bytes transferred = 6786368 (678d40 hex)
=> tftp 83000000 imx6ull_liefyuan_emmc.dtb
Using FEC1 device
TFTP from server 192.168.0.120; our IP address is 192.168.0.121
Filename 'imx6ull_liefyuan_emmc.dtb'.
Load address: 0x83000000
Loading: ###
         2.1 MiB/s
done
Bytes transferred = 38823 (97a7 hex)

可知:

  • 内核映像文件大小为:0x678d40(6786368Byte)
  • 设备树映像文件大小为:0x97a7(38823Byte)

2、从DDR写到EMMC设备

更新之前:

分区1内有3个文件分别为:

  • 内核文件(大小为:6788696Byte):zimage
  • 设备树文件一(大小为:38823Byte):imx6ull-14x14-emmc-4.3-800x480-c.dtb
  • 设备树文件二(大小为:39655Byte):imx6ull-14x14-emmc-hdmi.dtb
=> mmc dev 1
switch to partitions #0, OK
mmc1(part 0) is current device
=> fatls mmc 1:1
  6788696   zimage
    38823   imx6ull-14x14-emmc-4.3-800x480-c.dtb
    39655   imx6ull-14x14-emmc-hdmi.dtb

3 file(s), 0 dir(s)

开始更新:

使用fatwrite命令写数据:

  • 使用命令将DDR地址0x80800000开始的0x678d40个字节的数据(内核映象文件)写入到EMMC分区1:fatwrite mmc 1:1 80800000 zImage 0x678d40
  • 使用命令将DDR地址0x83000000开始的0x97a7个字节的数据(设备树文件)写入到EMMC分区1:fatwrite mmc 1:1 80800000 zImage 0x678d40

=> fatwrite mmc 1:1 80800000 zImage 0x678d40
writing zImage
6786368 bytes written
=> fatwrite mmc 1:1 83000000 imx6ull_liefyuan_emmc.dtb 0x97a7
writing imx6ull_liefyuan_emmc.dtb
38823 bytes written

更新之后:

更新之后,EMMC分区1内的文件增加到了4个:

  • 内核文件(大小为:6786368Byte):zimage
  • 设备树文件一(大小为:38823Byte):imx6ull-14x14-emmc-4.3-800x480-c.dtb
  • 设备树文件二(大小为:39655Byte):imx6ull-14x14-emmc-hdmi.dtb
  • 设备树文件三(大小为:38823Byte):imx6ull_liefyuan_emmc.dtb
=> mmc dev 1
switch to partitions #0, OK
mmc1(part 0) is current device
=> fatls mmc 1:1
  6786368   zimage
    38823   imx6ull-14x14-emmc-4.3-800x480-c.dtb
    39655   imx6ull-14x14-emmc-hdmi.dtb
    38823   imx6ull_liefyuan_emmc.dtb

4 file(s), 0 dir(s)

列个表比较一下:

更新前文件名更新前大小更新后文件名更新后大小
zimage6788696zimage6786368
imx6ull-14x14-emmc-4.3-800x480-c.dtb38823imx6ull-14x14-emmc-4.3-800x480-c.dtb38823
imx6ull-14x14-emmc-hdmi.dtb39655imx6ull-14x14-emmc-hdmi.dtb39655
imx6ull_liefyuan_emmc.dtb38823

从更新前后的数据比较可得:

  • 遵循文件系统的操作:(脱离物理存储规律虚拟地址,可以做到以文件名为操作对象)
    • 更新时分区1中如果有文件名相同的将会将会替换它
    • 如果文件名不同将直接写入一个新的文件

四、测试一下:新的kernel和设备树

1、设置从emmc上加载kernel和dtb文件

setenv bootcmd 'fatload mmc 1:1 80800000 zImage; fatload mmc 1:1 83000000 imx6ull_liefyuan_emmc.dtb; bootz 80800000 - 83000000'

=> setenv bootcmd 'fatload mmc 1:1 80800000 zImage; fatload mmc 1:1 83000000 imx6ull_liefyuan_emmc.dtb; bootz 80800000 - 83000000'
=> saveenv
Saving Environment to MMC...
Writing to MMC(1)... done
=> boot

2、设置从nfs服务器上加载根文件系统

setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.0.120:/home/liefyuan/linux/nfs/rootfs,proto=tcp rw ip=192.168.0.121:192.168.1.120:192.168.0.1:255.255.255.0::eth0:off'

setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.0.120:/home/liefyuan/linux/nfs/rootfs,proto=tcp rw ip=192.168.0.121:192.168.1.120:192.168.0.1:255.255.255.0::eth0:off' //设置 bootargs
saveenv
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页