一、eMMC介绍
eMMC (Embedded Multi Media Card)即嵌入式多媒体卡,是MMC协会订立、主要针对手机或平板电脑等产品的内嵌式存储器标准规格。eMMC在封装中集成了一个控制器,提供标准接口并管理闪存,简单描述如下:
eMMC=Nand Flash+控制器+标准封装
接口速度高达每秒400MBytes,eMMC具有快速、可升级的性能。同时其接口电压可以是1.8V或者是3.3V。
eMMC具有以下优势:
1.简化类手机产品存储器的设计。
2.更新速度快。
3.加速产品研发速度。
二、手动格式化eMMC操作
使用fdisk查看eMMC分区情况:
fdisk /dev/mmcblk1
Command (m for help): m ---键入m 获取使用说明
Command action
a toggle a bootable flag
b edit bsd disklabel
c toggle the dos compatibility flag
d delete a partition
l list known partition types
m print this menu
n add a new partition
o create a new empty DOS partition table
p print the partition table
q quit without saving changes
s create a new empty Sun disklabel
t change a partition's system id
u change display/entry units
v verify the partition table
w write table to disk and exit
x extra functionality (experts only)
接下来键入n,创建分区:n
Command (m for help): n ---键入n创建新的分区
接下来键入p,选择主分区:p
Select (default p): p ---键入p创建主分区
Partition number (1-4, default 1): 1 ---键入分区号
First sector (2048-31116287, default 2048): ---键入该分区的起始地址
2048
Last sector, +sectors or +size{K,M,G} (2048-31116287, default 31116287): 258047 ---键入该分区的结束地址
以上第一个分区建立完成。
再创建第二个分区,键入n,创建分区:n
Command (m for help): n ---键入n创建新的分区
接下来键入p,选择主分区:p
Select (default p): p ---键入p创建主分区
Partition number (1-4, default 1): 2 ---键入分区号
First sector (2048-31116287, default 2048): ---键入该分区的起始地址
258048
Last sector, +sectors or +size{K,M,G} (2048-31116287, default 31116287): 7262208 ---键入该分区的结束地址
以上第二个分区建立完成。
键入p查看分区情况,发现还差设置启动分区、各个分区的文件类型通过p查看帮助,手动设置。
修改分区类型
Command (m for help): t ---修改分区的系统类型
Partition number (1-4): 1 ---选择要修改的分区号
Hex code (type L to list codes): c ---设置第一分区为W95 FAT32 (LBA)格式
Changed system type of partition 1 to c (W95 FAT32 (LBA))
最后,保存键入w:
Command (m for help): w ---保存分区设置并退出
查看系统分区情况
cat /proc/partitions
接下来将eMMC第二个分区格式化为ext4格式。
mkfs.ext4 /dev/mmcblk1p2
三、手动烧录eMMC步骤
我以SD卡为嵌入式启动卡启动,将SD卡文件拷贝到eMMC的分区。
root@linux-arm:/run/media# cd mmcblk1p1/
root@linux-arm:/run/media/mmcblk1p1# ls
root@linux-arm:/run/media/mmcblk1p1# cd ..
root@linux-arm:/run/media# mount /dev/mmcblk1p1 /run/media/mmcblk1p1
root@linux-arm:/run/media# ls
mmcblk0p1 mmcblk1p1
root@linux-arm:/run/media# cd mmcblk1p1/
root@linux-arm:/run/media/mmcblk1p1# ls
MLO 'System Volume Information'u-boot.img
root@linux-arm:/run/media/mmcblk1p1# ls
MLO 'System Volume Information' u-boot.img
root@linux-arm:/run/media/mmcblk1p1# cd ..
root@linux-arm:/run/media# ls
mmcblk0p1 mmcblk1p1
root@linux-arm:/run/media# cd mmcblk1p1/
root@linux-arm:/run/media/mmcblk1p1# ls
MLO 'System Volume Information' u-boot.img
root@linux-arm:/run/media/mmcblk1p1# cp ../mmcblk0p1/* ./ -rdf
root@linux-arm:/run/media/mmcblk1p1#
root@linux-arm:/run/media# mkdir mmcblk0p2/
root@linux-arm:/run/media# mkdir mmcblk1p2/
root@linux-arm:/run/media# mount /dev/mmcblk0p2 /run/media/mmcblk0p2
root@linux-arm:/run/media#
root@linux-arm:/run/media# mount /dev/mmcblk1p2 /run/media/mmcblk1p2
root@linux-arm:/run/media# ls
mmcblk0p1 mmcblk0p2 mmcblk1p1 mmcblk1p2
root@linux-arm:/run/media# cp /run/me^Cmmcblk1p2/ -rdf
四、自动化脚本格式化和烧录eMMC
执行mkemmcboot.sh 完成格式化、烧录eMMC。
cat mkemmcboot.sh
#!/bin/bash
set -e
cur_dir=$(dirname $0)
. ${cur_dir}/utils.sh
erase_env
partition_emmc
${cur_dir}/mk_emmc_boot.sh
${cur_dir}/mk_emmc_fs.sh
cat utils.sh
# Description: Utility functions.
# Copyright 2019 Tronlong Elec. Tech. Co. Ltd. All Rights Reserved.
# Print error message with time.
err() {
echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $@" >&2
}
# Check file existence.
function ck_file_ext() {
if [[ ! -e $1 ]]; then
err "ERROR! File not exist: $1"
err "Abort, work not done!"
exit 1
fi
}
# Get MTD partition number
# Usage: MTD_NUM=$(get_mtd_num nand.env)
get_mtd_num() {
num=$(cat /proc/mtd | grep $1 | awk -F ':' '{print $1}' | awk -F 'mtd' '{print $2}')
if [[ -z "${num}" ]]; then
err "ERROR! Get MTD partition number of $1 failed!"
err "Abort, work not done!"
exit 1
fi
echo ${num}
}
# Erase spi.env and nand.env
erase_env() {
num=$(cat /proc/mtd | grep spi.env | awk -F ':' '{print $1}' | awk -F 'mtd' '{print $2}')
if [[ ! -z "${num}" ]]; then
flash_erase /dev/mtd${num} 0 0
echo "spi.env erase done!"
fi
num=$(cat /proc/mtd | grep nand.env | awk -F ':' '{print $1}' | awk -F 'mtd' '{print $2}')
if [[ ! -z "${num}" ]]; then
flash_erase /dev/mtd${num} 0 0
echo "nand.env erase done!"
fi
}
partition_emmc() {
echo "Partitioning /dev/mmcblk1..."
# umount them in case mounted already.
for i in $(cat /proc/mounts | grep /dev/mmcblk1p | awk '{print $1}'); do
umount $i 2>/dev/null
done
emmc_dev=/dev/mmcblk1
# Clear the head of emmc.
dd if=/dev/zero of=${emmc_dev} bs=1024 count=1024
# Get the partition information
total_size=$(($(fdisk -s ${emmc_dev}) * 1024))
total_cyln=$((total_size / 255 / 63 / 512))
# Offsets. 128M for boot, 60% - 128M for rootfs, 40% for data.
pc1_start=0
pc1_end=$((128 * 1024 * 1024 / $((255 * 63 * 512)) )) # 128M
pc2_end=$((${total_cyln} * 3 / 5))
parted -s ${emmc_dev} mklabel msdos
parted -s ${emmc_dev} unit cyl mkpart primary fat32 -- 0 ${pc1_end}
parted -s ${emmc_dev} set 1 boot on
parted -s ${emmc_dev} unit cyl mkpart primary ext4 -- ${pc1_end} ${pc2_end}
parted -s ${emmc_dev} unit cyl mkpart primary ext4 -- ${pc2_end} -2
sleep 5 #FIXME Make sure partition emmc is finished
echo "partition done!"
}
cat mk_emmc_boot.sh
#!/bin/bash
set -e
# Description: Burn boot files to eMMC.
# Copyright 2019 Tronlong Elec. Tech. Co. Ltd. All Rights Reserved.
# Load utility functions from utils.sh.
. $(dirname $0)/utils.sh
#### Defines ####
DEVICE=/dev/mmcblk1
#### Main Entrance ####
# Make sure device is exist.
dev1=$(ls -1 ${DEVICE} 2>/dev/null)
if [[ -z "${dev1}" ]]; then
echo "ERROR: ${DEVICE} is not exist."
fi
# Make boot as FAT32 format.
echo "Formating boot partition..."
dev1=$(cat /proc/mounts | grep ${DEVICE}p1 | awk '{print $1}')
if [[ ! -z "${dev1}" ]]; then
umount ${DEVICE}p1 # Umount boot in case mounted alraady.
fi
mkfs.vfat -F 32 -n BOOT ${DEVICE}p1
#FIXME Make sure format is finished
for ((i=0; $i<=100; i++))
do
dev1=$(ls -1 ${DEVICE}p1 2>/dev/null)
if [[ ! -z "${dev1}" ]]; then
break;
fi
sleep 0.1
done
echo "Format done!"
# Mount boot partition.
boot_mp="/tmp/$$-boot" # Mount points of boot partition.
if [[ ! -d ${boot_mp} ]]; then
mkdir -p ${boot_mp}
fi
mount ${DEVICE}p1 ${boot_mp}
# Copy file to boot.
echo "Copying boot files to ${DEVICE}p1..."
cp -rf /run/media/mmcblk0p1/* ${boot_mp}
# Umount boot.
dev1=$(cat /proc/mounts | grep ${DEVICE}p1 | awk '{print $1}')
if [[ ! -z "${dev1}" ]]; then
umount ${DEVICE}p1
fi
echo "Make eMMC boot partition done!"
cat mk_emmc_fs.sh
#!/bin/bash
set -e
# Description: Burn filesystem to eMMC. Make a data partition by the way.
# Copyright 2019 Tronlong Elec. Tech. Co. Ltd. All Rights Reserved.
# Load utility functions from utils.sh.
. $(dirname $0)/utils.sh
#### Defines ####
DEVICE=/dev/mmcblk1
#### Main Entrance ####
# Make rootfs and data partition as ext4 format.
echo "Formating rootfs and data partition..."
dev2=$(cat /proc/mounts | grep ${DEVICE}p2 | awk '{print $1}')
dev3=$(cat /proc/mounts | grep ${DEVICE}p3 | awk '{print $1}')
if [[ ! -z "${dev2}" ]]; then
umount ${DEVICE}p2 # Umount in case mounted alraady.
fi
if [[ ! -z "${dev3}" ]]; then
umount ${DEVICE}p3 # Umount in case mounted alraady.
fi
mkfs.ext4 -F -L rootfs ${DEVICE}p2
mkfs.ext4 -F -L data ${DEVICE}p3
#FIXME Make sure format is finished
for ((i=0; $i<=100; i++))
do
dev2=$(ls -1 ${DEVICE}p2 2>/dev/null)
dev3=$(ls -1 ${DEVICE}p3 2>/dev/null)
if [[ ! -z "${dev2}" ]] && [[ ! -z "${dev3}" ]]; then
break;
fi
sleep 0.1
done
echo "Format done!"
# Mount rootfs partition.
rootfs_mp="/tmp/$$-rootfs" # Mount points of rootfs partition.
if [[ ! -d ${rootfs_mp} ]]; then
mkdir -p ${rootfs_mp}
fi
mount ${DEVICE}p2 ${rootfs_mp}
# Copy file to rootfs from backup partition of SD.
echo "Copying rootfs files to ${DEVICE}p2..."
sd_p3_mp=$(df /dev/mmcblk0p3 | grep /dev/mmcblk0p3 | awk '{print $6}')
cp -rf ${sd_p3_mp}/. ${rootfs_mp}
# Umount boot.
dev2=$(cat /proc/mounts | grep ${DEVICE}p2 | awk '{print $1}')
if [[ ! -z "${dev2}" ]]; then
umount ${DEVICE}p2
fi
echo "Make eMMC rootfs partition done!"
感谢阅读,祝君成功!
-by aiziyou