Ubuntu18.04烧录U-Boot时格式化SD卡的文件类型(RAW 格式)

前言

本文只讨论U-Boot的烧录问题,也就是说,假定已经make生成bl1.bin——即BL1镜像、bl2.bin——BL2镜像、u-boot.bin——uboot镜像。也不讨论内核的移植。
结论是:Ubuntu18.04烧录U-Boot时格式化SD卡,是RAW 格式的无名分区。无名分区在Windows 和 Linux 操作系统下均不可见,存放的是 u-boot.ais。1

1、问题的提出

在烧录U-boot之前,要对SD卡进行格式化。但是,这个格式化并不能用fdisk进行分区、再用mkfs对分区格式化文件类型。

2、分析问题

BL1(第一引导加载程序)是从SD卡的 512B 的偏移量处开始烧录,BL2是从SD卡的Block17处开始烧录。如下图:2

BL1镜像从512B的位置开始写入
但是,fdisk是从第2048个扇区开始第一个分区,明显与BL1的位置是不同的。所以,烧录U-Boot是不能用fdisk对SD卡分区的。那么,也就不能用mkfs对分区写入文件系统,也就不能用mount挂载SD卡。
只能用dd命令来格式化。

3、用dd命令格式化SD卡

dd命令:

用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换。3

dd if=/dev/zero of=/dev/sdb bs=1024 count=102400

参数:

  1. if=文件名:输入文件名,缺省为标准输入。即指定源文件。< if=input file >
  2. of=文件名:输出文件名,缺省为标准输出。即指定目的文件。< of=output file >
  3. bs=bytes:同时设置读入/输出的块大小为bytes个字节。4M一般没有问题。
  4. count=blocks:仅拷贝blocks个块,块大小等于ibs指定的字节数。

这里,我理解是1个bs有1k字节,共有count=102400个bs。也就是说,给1k*100k个字节写入zero。

4、SD卡的烧录

  1. 首先,用fdisk -l查看是否能够识别SD卡。每个人的分区情况会不一样,一般/dev/sda是主硬盘。 /dev/sdb、 /dev/sdc、 /dev/sdd都有可能是SD卡,可以根据容量大小来判断。假定 /dev/sdb是SD卡,那么执行脚本烧写一定是对 /dev/sdb进行烧写。
sudo fdisk -l | grep sd
Disk /dev/sda:20 GiB,21474836480 字节,41943040 个扇区
/dev/sda1  *     2048 41940991 41938944  20G 83 Linux
Disk /dev/sdb:967.5 MiB,1014497280 字节,1981440 个扇区

此时,/dev/sdb是不能用mount挂载到/mnt下的。这是因为文件系统错误。

sudo mount /dev/sdb /mnt
mount: /mnt: can't read superblock on /dev/sdb.
  1. 在~/u-boot-2022.01-rc4-cbt4412/sd_fuse/tiny4412文件夹下,有sd_fusing.sh脚本可以烧写U-boot。脚本内容如下:
#
# Copyright (C) 2011 Samsung Electronics Co., Ltd.
#              http://www.samsung.com/
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
####################################

if [ -z $1 ]
then
    echo "usage: ./sd_fusing.sh <SD Reader's device file>"
    exit 0
fi

if [ -b $1 ]
then
    echo "$1 reader is identified."
else
    echo "$1 is NOT identified."
    exit 0
fi

####################################
#<verify device>

BDEV_NAME=`basename $1`
BDEV_SIZE=`cat /sys/block/${BDEV_NAME}/size`

if [ ${BDEV_SIZE} -le 0 ]; then
	echo "Error: NO media found in card reader."
	exit 1
fi

if [ ${BDEV_SIZE} -gt 32000000 ]; then
	echo "Error: Block device size (${BDEV_SIZE}) is too large"
	exit 1
fi

####################################
# check files

E4412_UBOOT=../../u-boot.bin
E4412_UBOOT_SPL=../../spl/u-boot-spl.bin
MKBL2=../mkbl2

if [ ! -f ${E4412_UBOOT} ]; then
	echo "Error: u-boot.bin NOT found, please build it & try again."
	exit -1
fi

if [ ! -f ${MKBL2} ]; then
	echo "Error: can not find host tool - mkbl2, stop."
	exit -1
fi

#<make bl2>
${MKBL2} ${E4412_UBOOT_SPL} bl2.bin 14336

####################################
# fusing images

signed_bl1_position=1
bl2_position=17
uboot_position=49
#tzsw_position=705
tzsw_position=1649

#<BL1 fusing>
echo "---------------------------------------"
echo "BL1 fusing"
dd iflag=dsync oflag=dsync if=./E4412_N.bl1.bin of=$1 seek=$signed_bl1_position

#<BL2 fusing>
echo "---------------------------------------"
echo "BL2 fusing"
dd iflag=dsync oflag=dsync if=./bl2.bin of=$1 seek=$bl2_position

#<u-boot fusing>
echo "---------------------------------------"
echo "u-boot fusing"
dd iflag=dsync oflag=dsync if=${E4412_UBOOT} of=$1 seek=$uboot_position

#<TrustZone S/W fusing>
echo "---------------------------------------"
echo "TrustZone S/W fusing"
dd iflag=dsync oflag=dsync if=./E4412_tzsw.bin of=$1 seek=$tzsw_position

#<flush to disk>
sync

####################################
#<Message Display>
echo "---------------------------------------"
echo "U-boot image is fused successfully."
echo "Eject SD card and insert it again."

执行SD烧写脚本:

sudo ./sd_fusing.sh /dev/sdb

结果如下:2

sudo ./sd_fusing.sh /dev/sdb
/dev/sdd reader is identified.
---------------------------------------
BL1 fusing
记录了16+0 的读入
记录了16+0 的写出
8192 bytes (8.2 kB, 8.0 KiB) copied, 0.295506 s, 27.7 kB/s
---------------------------------------
BL2 fusing
记录了28+0 的读入
记录了28+0 的写出
14336 bytes (14 kB, 14 KiB) copied, 1.05636 s, 13.6 kB/s
---------------------------------------
u-boot fusing
记录了541+1 的读入
记录了541+1 的写出
277260 bytes (277 kB, 271 KiB) copied, 8.7953 s, 31.5 kB/s
---------------------------------------
TrustZone S/W fusing
记录了184+0 的读入
记录了184+0 的写出
94208 bytes (94 kB, 92 KiB) copied, 3.84811 s, 24.5 kB/s
---------------------------------------
U-boot image is fused successfully.
Eject SD card and insert it again.

这样就把u-boot烧写进入SD卡。可以看出,

烧写内容block位置block个数
BL1block 1~block1616
BL2block 17 ~ block 4428
u-bootblock 49 ~ block 715666
TrustZoneblock 1649 ~ block 1832184

烧写完毕将卡插到开发板,启动设备选择开关拨到SD启动,开发板的串口线连接到
电脑,打开串口助手,设置串口端口号、波特率115200、数据位8b、停止位1b、无奇偶校验位。打开串口,然后打开发板电源就能看见u-boot启动过程。

U-Boot 2022.01-rc4-ga469d789-dirty (Jan 30 2023 - 08:33:53 +0800) for CBT4412

CPU:   Exynos4412 @ 1.4 GHz
Model: CBt4412 board based on Exynos4412
DRAM:  1 GiB
WARNING: Caches not enabled
MMC:   SAMSUNG SDHCI: 0, EXYNOS DWMMC: 1
Loading Environment from MMC... MMC Device 2 not found
*** Warning - No MMC card found, using default environment

Net:   dm9000_initialize(bis) was runned
dm9000
Warning: dm9000 (eth0) using random MAC address - ca:d5:d0:72:30:c1

Hit any key to stop autoboot:  0 
Wrong Image Format for bootm command
ERROR: can't get kernel image!
CBT4412 #mmc list
SAMSUNG SDHCI: 0
EXYNOS DWMMC: 1

5、再谈SD卡的分区

1、SD 系统启动卡共有 FAT32、 EXT3 两个格式分区,还包含 RAW 格式的无名分区。其中 FAT32 格式分区在 Windows 系统下可见,EXT3 格式分区在 Windows 系统下不可见,两分区在 Linux 系统下均可见。无名分区在Windows 和 Linux 操作系统下均不可见。 无名分区存放 u-boot.ais, FAT32 格式分区存放内核文件 uImage、系统启动脚本等文件, EXT3 格式分区存放文件系统。1

2、由U-Boot的启动过程可以看出,linux_kernel和linux_ramdisk在不同的Block位置,如下图。

----linux_kernel

reading linux kernel..device 0 Start 46113, Count 12288 

MMC read: dev # 0, block # 46113, count 12288 ... 12288 blocks read: OK

completed

----linux_ramdisk

reading linux ramdisk..device 0 Start 58401, Count 2048 

MMC read: dev # 0, block # 58401, count 2048 ... 2048 blocks read: OK

所以,在修改U-Boot源码的时候,需要修改fastboot.c文件,修改U-Boot分区表。确定“BootLoader”、“kernel”、“system”、“userdata”、“reserved”分区的起始地址和长度。4
那么,在烧写U-Boot、内核、文件系统的时候,就要按照U-Boot分区表中的地址分别进行烧写。

以下是另一篇博文的内容,作分区和各分区作用参考。5

由于emmc在系统启动后,分为了mmcblk0p1~mmcblk0p5>五个分区。其中:
mmcblk0p1是存放的vendor信息的分区。
mmcblk0p2是IDBlock分区,存放的是loader.bin文件。
mmcblk0p3是kernel分区,存放的是kernel.img文件。
mmcblk0p4是rootfs分区,存放的是rootfs.img文件。
mmcblk0p5分区是数据分区,主要存储拍照和录像的数据。


  1. 嵌入式Linux SD系统启动卡制作方法 ↩︎ ↩︎

  2. 关于tiny4412开发板SD卡烧写u-boot脚本sd_fusing.sh的解释 ↩︎ ↩︎

  3. 《Ubuntu — dd命令的使用》 ↩︎

  4. 刘志强. 基于项目驱动的嵌入式Linux应用设计开发.北京:清华大学出版社.2020,12:108-109. ↩︎

  5. linux 中fdisk 和 mkfs.vfat命令的使用总结 ↩︎

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值