当前位置: 首页 > news >正文

海思3519AV100 emmc分区优化与uboot参数调试实战

1. 从一次启动失败说起:为什么emmc分区和uboot参数这么重要?

最近在折腾海思3519AV100的开发板,想把系统从SPI Nor Flash迁移到emmc上,结果烧写完系统镜像,板子直接“砖”了,串口一片寂静。相信很多刚接触海思平台的朋友都遇到过类似的问题,明明编译、烧写步骤都照着手册做了,但系统就是起不来。折腾了半天,最后发现根子出在两个地方:一是emmc的分区规划没和uboot“对上线”,二是uboot里那个关键的bootargs启动参数没配置对。

这其实是一个典型的“最后一公里”问题。SDK编译出来的镜像本身没问题,Hitool工具烧写也成功了,但系统启动是一个环环相扣的过程。海思的芯片启动流程大致是:芯片内部ROM加载uboot -> uboot从存储介质(比如emmc)的指定位置加载内核和设备树 -> 内核启动,并根据uboot传递过来的bootargs参数去找到根文件系统(rootfs)并挂载。如果bootargs里告诉内核“根文件系统在/dev/mmcblk0p3”,但你实际烧写时却把rootfs镜像写到了mmcblk0p2,那内核肯定就找不到家,启动自然失败。

所以,emmc分区优化与uboot参数调试,本质上是在为你的系统搭建一个清晰、准确的“住址导航系统”。分区规划决定了uboot、kernel、rootfs、应用数据各自住在emmc这座“大房子”的哪个房间、门牌号是多少。而uboot参数,尤其是bootargs,就是一张写满了地址的“导航纸条”,在启动时交给内核,告诉它:“嘿,你的根文件系统在/dev/mmcblk0p3,文件系统类型是ext4,可以读写哦。”这张纸条要是写错了,内核就会迷路。

这篇文章,我就结合自己踩过的坑,手把手带你走一遍海思3519AV100在emmc上从分区规划、文件系统制作烧写,到uboot参数调试、分区挂载使用的完整实战流程。目标很明确:让你不仅能照着做成功,更能理解每一步背后的“为什么”,下次遇到问题自己能快速定位。

2. 庖丁解牛:如何规划一块8GB emmc的分区?

拿到一块全新的8GB(实际可用约7456MB)emmc,就像拿到一块空白的画布,分区规划就是你的布局草图。规划得好,系统运行井然有序,升级维护也方便;规划得随意,后期可能就会遇到空间不足、日志爆满、升级失败等各种头疼事。

2.1 分区规划的核心思路与实战方案

我的规划原则是:满足需求、预留余量、方便管理。针对海思3519AV100这类视觉处理SoC的典型应用场景(比如智能摄像头、边缘计算盒子),我设计了下面这个分区方案,你可以直接拿去用,也可以根据你的项目微调。

分区名大小设备节点用途说明
uboot1MB/dev/mmcblk0p1存放U-Boot引导程序。1MB足够,海思的uboot通常几百KB。
kernel10MB/dev/mmcblk0p2存放Linux内核镜像(uImage)和设备树文件(dtb)。10MB对于3519AV100的内核绰绰有余,为后续内核功能增加留了空间。
rootfs256MB/dev/mmcblk0p3存放只读的根文件系统。使用ext4格式,256MB可以容纳一个基本的BusyBox或小体积的Buildroot系统。如果系统复杂,可酌情增大。
config10MB/dev/mmcblk0p4关键分区!存放设备配置文件、网络配置、序列号等需要掉电保存但又可能修改的数据。与rootfs分离,保证系统升级时配置不丢失。
data~7000MB/dev/mmcblk0p5存放应用数据,如录像文件、图片、日志、用户数据等。分配剩余的所有空间。

为什么要把config和data单独分出来?这是嵌入式系统一个非常重要的优化实践。想象一下,如果你的系统需要远程OTA升级,新版本的rootfs镜像会直接覆盖旧的分区。如果配置文件混在rootfs里,升级后所有配置就都恢复出厂设置了,用户肯定要骂娘。把config分区独立出来,升级时只更新rootfs分区,用户的个性化配置完好无损。同样,data分区独立,可以避免应用日志或数据写满整个emmc,导致系统崩溃。

这个方案的总大小加起来大约是1+10+256+10+7000=7277MB,小于emmc总容量7456MB,中间有一些预留的间隙,这是正常的,也是安全的。

2.2 分区表写入:使用Hitool进行可视化操作

规划好了,就要把这张“分区表”写到emmc上。对于海思平台,最常用的就是Hitool工具。这个过程不是在Linux系统里用fdisk命令,而是在烧写镜像的第一步就完成的。

  1. 连接设备:用串口线连接开发板和PC,上电,让设备进入烧写模式(通常是先按住升级键再上电,串口出现“Hit any key to stop autoboot”时快速按回车,进入uboot命令行,执行update命令,具体请参考你的板子手册)。
  2. 打开Hitool:选择你的芯片型号(Hi3519AV100),传输方式选择“串口”并设置好正确的COM口和波特率(通常是115200)。
  3. 进入分区烧写界面:在Hitool的“烧写eMMC”标签页下,你会看到一个分区列表。你需要在这里新建修改分区,使其符合我们的规划。
  4. 添加分区:点击“新建”,依次添加5个分区,分别设置好分区名(如boot)、文件系统(前三个分区通常选noneraw data,因为uboot、kernel是裸数据;rootfs、config、data可以选ext4)、以及最关键的起始地址长度
    • 这里有个大坑:Hitool里的长度单位可能是扇区(Sector),一个扇区通常512字节。所以我们的分区大小需要换算:
      • uboot: 1MB = 1024KB = 1048576字节 = 1048576 / 512 =2048个扇区
      • kernel: 10MB = 10240KB = 10485760字节 =20480个扇区
      • rootfs: 256MB = 262144KB = 268435456字节 =524288个扇区
      • config: 10MB =20480个扇区
      • data: 7000MB ≈ 7000*2048 =14336000个扇区(计算时按1MB=2048扇区估算更简单)
    • 起始地址需要累加。通常uboot从0地址开始,那么:
      • uboot: 起始 0, 长度 2048
      • kernel: 起始 2048, 长度 20480
      • rootfs: 起始 22528 (2048+20480), 长度 524288
      • config: 起始 546816 (22528+524288), 长度 20480
      • data: 起始 567296 (546816+20480), 长度 14336000
  5. 应用分区表:设置好后,先不要着急烧写文件。点击“烧写”按钮,Hitool会先将这个分区表信息写入emmc。这一步非常重要,它决定了后续每个镜像应该烧写到哪个物理位置。

很多新手会忽略这一步,直接去烧写rootfs镜像,导致分区不对齐,启动失败。请务必确保Hitool中的分区布局和你心中规划的一致。

3. 动手制作与烧写:从源码到可启动的ext4根文件系统

分区表建好了,“房子”的格局已经划定。接下来我们要制作“家具”并搬进去,也就是编译生成系统镜像,并烧写到对应的分区。

3.1 编译SDK与制作ext4根文件系统镜像

海思的SDK通常提供了完整的编译脚本。假设你的SDK目录结构是标准的osdrv

# 1. 进入SDK的osdrv目录 cd /your/path/to/sdk/osdrv/ # 2. 执行全量编译 # 注意关键参数:BOOT_MEDIA=emmc,这会影响一些底层配置 make OSDRV_CROSS=arm-himix200-linux CHIP=hi3519av100 BOOT_MEDIA=emmc all

这个过程会比较漫长,因为它会编译uboot、kernel、rootfs等所有组件。编译成功后,在osdrv/pub/目录下,你会找到编译好的根文件系统文件夹,例如rootfs_glibc/。同时,在osdrv/tools/pc/ext4_utils/bin/下,会生成一个叫make_ext4fs的工具,它是海思提供的用于制作ext4镜像的专用工具。

为什么不用标准的mkfs.ext4因为make_ext4fs可以更好地处理嵌入式场景,比如指定文件系统的label,处理selinux上下文等,与海思内核的兼容性更好。

# 3. 使用make_ext4fs制作镜像 # 假设我们在pub目录下操作 cd osdrv/pub/ # -l 参数指定镜像大小,必须与我们规划的rootfs分区大小一致(256M) # -s 参数生成稀疏镜像,节省磁盘空间 # 最后的参数是根文件系统目录 ../tools/pc/ext4_utils/bin/make_ext4fs -l 256M -s rootfs_hi3519av100_256M.ext4 rootfs_glibc/

执行完后,当前目录就会生成一个rootfs_hi3519av100_256M.ext4的文件。这个文件就是我们要烧写到mmcblk0p3分区的根文件系统镜像。

3.2 使用Hitool精准烧写各分区镜像

现在回到Hitool,我们要把编译好的“家具”搬进对应的“房间”。

  1. 烧写uboot:在分区列表中找到boot分区(对应mmcblk0p1),在“文件路径”中选择你编译生成的uboot镜像,通常是u-boot-hi3519av100.bin。勾选该分区,点击“烧写”。uboot必须烧写在起始扇区。
  2. 烧写kernel:找到kernel分区(mmcblk0p2),选择内核镜像uImage和设备树文件hi3519av100.dtb(有时设备树是包含在内核镜像里的,具体看SDK说明),进行烧写。
  3. 烧写rootfs:找到rootfs分区(mmcblk0p3),选择我们刚刚制作好的rootfs_hi3519av100_256M.ext4文件,进行烧写。
  4. config和data分区:这两个分区我们规划了,但暂时没有镜像可烧。可以先不烧写,或者烧写一个空的ext4镜像(可以用dd if=/dev/zero of=empty.ext4 bs=1M count=10mkfs.ext4 empty.ext4制作一个)。更常见的做法是,等系统启动后,在Linux系统内对其进行格式化。

一个关键检查点:烧写时,务必确认Hitool为每个分区选择的“烧写起始地址”是否与我们之前计算的一致。虽然我们通过GUI设置了分区,但有时工具可能会有偏差,手动核对一下能避免低级错误。

全部烧写完成后,重启设备。如果运气好(或者说,如果你前面的分区规划和镜像制作完全正确),系统可能会直接启动。但更大的概率是,串口有uboot输出,但内核启动后卡住,提示找不到根文件系统或者内核恐慌(Kernel Panic)。别慌,这通常就是bootargs参数在“捣鬼”。

4. 打通任督二脉:深度调试uboot的bootargs参数

系统启动失败,串口信息停在了内核试图挂载根文件系统的地方,并报错“VFS: Unable to mount root fs”。这就是uboot传递给内核的“导航纸条”——bootargs环境变量——出了问题。

4.1 bootargs参数详解:内核的启动指南

bootargs是一个字符串,里面包含了用空格分隔的多个参数。内核在启动时会解析它。对于我们这个emmc启动的场景,最关键的是以下几个部分:

  • mem=128M:告诉内核系统有多少可用的物理内存。这个值必须和你的硬件一致,3519AV100通常有512M或更多,这里设为128M是示例,务必根据你的DDR大小修改,例如mem=512M
  • console=ttyAMA0,115200:指定控制台为串口0,波特率115200。这样内核的打印信息才能从串口输出。
  • root=/dev/mmcblk0p3这是最核心的参数!指定根文件系统所在的设备。mmcblk0表示第一个mmc设备(emmc),p3表示第3个分区。这必须和你烧写rootfs镜像的分区号严格对应。如果你烧在了p2,这里就要改成p2
  • rootfstype=ext4:指定根文件系统的类型。我们制作的是ext4镜像,所以这里写ext4。如果是squashfs、jffs2等,需要相应修改。
  • rw:以读写方式挂载根文件系统。早期有些只读文件系统会用ro
  • rootwait:让内核等待根设备就绪后再尝试挂载,对于emmc这种需要初始化的设备很有必要。
  • blkdevparts=mmcblk0:1M(boot),10M(kernel),256M(rootfs),10M(config),7000M(data)这个参数至关重要且容易被忽略!它用于向内核注册我们自定义的分区表。格式是设备名:大小1(名字1),大小2(名字2)...。这里的顺序和大小,必须和我们在Hitool里设置的分区表完全一致。内核需要这个信息来正确识别/dev/mmcblk0p1p5这些设备节点。

4.2 在uboot命令行中动态修改与保存

设备重启,在uboot倒计时阶段快速按任意键(通常是回车),进入uboot命令行。在这里我们可以检查和修改环境变量。

# 1. 查看当前的bootargs参数 printenv bootargs # 可能会显示一个默认的值,比如是从spi flash启动的参数。 # 2. 设置新的、正确的bootargs参数 # 注意:这是一整条命令,参数是一个长字符串。 setenv bootargs 'mem=512M console=ttyAMA0,115200 root=/dev/mmcblk0p3 rootfstype=ext4 rw rootwait blkdevparts=mmcblk0:1M(boot),10M(kernel),256M(rootfs),10M(config),7000M(data)' # 3. 保存环境变量到存储介质(emmc或SPI Nor Flash) saveenv # 4. 重启系统,让新参数生效 reset

执行reset后,uboot会使用新的bootargs启动内核。如果一切配置正确,你应该能看到内核顺利启动,并最终出现根文件系统的命令行提示符(如/ #root@(none):~#)。

调试技巧:如果还是失败,可以在bootargs中加入init=/bin/sh,让内核启动后直接进入shell而不是启动完整的初始化进程。这样即使根文件系统挂载有问题,你也有机会在早期shell里查看/dev/下的设备节点,用mount命令手动尝试挂载,排查是设备节点不对、文件系统类型不对,还是镜像本身有问题。

5. 让系统“活”起来:挂载与应用config、data分区

系统成功启动,登录进去,你会发现/config/mnt/mmc(或者你计划挂载的目录)是空的。这是因为我们还没有格式化并挂载这两个独立的分区。

5.1 检查设备节点与手动挂载

首先,确认内核是否识别出了我们所有的分区。

# 查看emmc相关的设备节点 ls -l /dev/mmcblk0*

你应该能看到类似下面的输出:

brw------- 1 root root 179, 0 Jan 1 00:00 /dev/mmcblk0 # 整个emmc设备 brw------- 1 root root 179, 1 Jan 1 00:00 /dev/mmcblk0p1 # uboot分区 brw------- 1 root root 179, 2 Jan 1 00:00 /dev/mmcblk0p2 # kernel分区 brw------- 1 root root 179, 3 Jan 1 00:00 /dev/mmcblk0p3 # rootfs分区 brw------- 1 root root 179, 4 Jan 1 00:00 /dev/mmcblk0p4 # config分区 brw------- 1 root root 179, 5 Jan 1 00:00 /dev/mmcblk0p5 # data分区

看到p4p5,说明内核通过blkdevparts参数正确识别了我们的分区表。接下来就是格式化和挂载。

5.2 自动化挂载脚本编写

我们当然可以每次手动执行mkfs.ext4mount命令,但更专业的做法是将其写入系统启动脚本,比如/etc/init.d/rcS或者/etc/fstab。这里我分享一个更健壮的脚本片段,它实现了“尝试挂载-失败则格式化-重新挂载”的逻辑。

你可以创建一个脚本,例如/usr/bin/mount_emmc_partitions.sh

#!/bin/sh # 挂载config分区 CONFIG_PART="/dev/mmcblk0p4" CONFIG_MOUNT_POINT="/config" # 创建挂载点目录 mkdir -p ${CONFIG_MOUNT_POINT} # 尝试挂载 mount -t ext4 ${CONFIG_PART} ${CONFIG_MOUNT_POINT} # 检查挂载是否成功 if [ $? -ne 0 ]; then echo "[INFO] Config partition not formatted. Formatting..." # 卸载以防万一(可能是个无效挂载) umount ${CONFIG_MOUNT_POINT} 2>/dev/null # 进行格式化,-F 强制,-L 设置卷标 mkfs.ext4 -F ${CONFIG_PART} # 再次尝试挂载 mount -t ext4 ${CONFIG_PART} ${CONFIG_MOUNT_POINT} if [ $? -eq 0 ]; then echo "[INFO] Config partition formatted and mounted successfully." # 可以在格式化后初始化一些默认配置文件到这里 # cp /etc/default_config/* ${CONFIG_MOUNT_POINT}/ else echo "[ERROR] Failed to mount config partition after formatting!" fi else echo "[INFO] Config partition mounted successfully." fi # 挂载data分区,逻辑同上 DATA_PART="/dev/mmcblk0p5" DATA_MOUNT_POINT="/mnt/mmc" mkdir -p ${DATA_MOUNT_POINT} mount -t ext4 ${DATA_PART} ${DATA_MOUNT_POINT} if [ $? -ne 0 ]; then echo "[INFO] Data partition not formatted. Formatting..." umount ${DATA_MOUNT_POINT} 2>/dev/null mkfs.ext4 -F ${DATA_PART} mount -t ext4 ${DATA_PART} ${DATA_MOUNT_POINT} if [ $? -eq 0 ]; then echo "[INFO] Data partition formatted and mounted successfully." else echo "[ERROR] Failed to mount data partition after formatting!" fi else echo "[INFO] Data partition mounted successfully." fi

给脚本添加执行权限chmod +x /usr/bin/mount_emmc_partitions.sh,并在启动脚本(如/etc/rc.local)中调用它。这样,每次系统启动都会自动检查并挂载这两个分区。

5.3 分区规划的实际价值体现

/config/mnt/mmc成功挂载后,你就能体会到分区规划的优势了。你可以将你的应用程序配置文件全部链接到/config下,将录像存储路径设置为/mnt/mmc/video。当需要进行系统升级时,你只需要用新的rootfs.ext4镜像覆盖mmcblk0p3分区,/config/mnt/mmc里的所有数据都会安然无恙。这极大地提高了系统的可靠性和可维护性。

整个流程走下来,从分区规划到系统稳定运行,最关键的就是一致性:Hitool里的分区表、bootargs里的blkdevparts描述、以及实际烧写镜像的位置,这三者必须严丝合缝。任何一个环节的错位,都会导致启动失败。多花时间理解每个步骤的意义,比盲目复制命令要重要得多。希望这篇实战记录能帮你少走弯路,顺利搞定海思3519AV100的emmc启动。

http://www.jsqmd.com/news/433704/

相关文章:

  • 5个高效技巧:WzComparerR2逆向工程工具如何解析WZ文件与提取游戏资源
  • mooc-dl开源工具:中国大学MOOC资源高效下载解决方案
  • UNIT-00模型实战:解析复杂业务逻辑,自动生成测试用例
  • 幻境·流金效果可视化:i2L在低步数下保留高光/阴影/材质物理逻辑
  • C开发者的网易云音乐API集成指南:从入门到实践
  • 造相Z-Image模型异常处理指南:常见问题与解决方案大全
  • EMQX插件实现物联网数据持久化:从技术原理到落地实践
  • Markdown浏览器扩展全攻略:从安装到高级应用的效率提升指南
  • translategemma-27b-it实际作品:中文农书耕作图→英文农业史学术术语输出
  • 5个突破性功能技巧:用Python工具实现3D电磁场仿真
  • VSCode插件开发:BEYOND REALITY Z-Image提示词智能补全
  • 颠覆式Markdown编辑体验:MarkText的7大突破与效率革命
  • Unlock Music:解除音频加密的创新方案 - 实现音乐文件跨平台自由播放
  • Stable-Diffusion-V1-5 工业设计应用:与CAD软件结合快速生成产品概念图
  • 如何用浏览器扩展打造高效Markdown阅读环境:从安装到个性化全指南
  • SPIRAN ART SUMMONER基础教程:祈祷词语法规范与长文本输入技巧
  • 优化SEGGER Embedded Studio调试体验:Nordic MCU外设寄存器可视化全攻略
  • m3u8-downloader服务端容器化部署解决方案:4个关键步骤打造稳定视频下载服务
  • BGE Reranker-v2-m3作品集:中文学术、电商、政务、医疗四类语料下的重排序效果横向对比
  • 守护代码原创性的智能卫士:JPlag全方位抄袭检测指南
  • cv_unet_image-colorization应用场景:独立游戏开发者——黑白像素美术资源AI上色扩增
  • 5个提升开发效率技巧:CursorCode让中级开发者编码速度提升3倍
  • 颠覆式突破!Demucs 6秒极速六源音频分离技术:重新定义音乐处理效率标准
  • 拓竹打印避坑|今天这只“二哈”,差点栽在这个高频痛点上:针对层纹问题我们可以设置这个参数 可变层高
  • GME-Qwen2-VL-2B模型版本管理与持续集成(CI)实践
  • 重塑Windows 11工作环境:ExplorerPatcher深度定制指南
  • d2dx宽屏补丁:让暗黑破坏神2在现代PC焕发新生的技术方案
  • Ncorr 2D数字图像相关技术实战全流程指南:从问题解决到场景落地
  • 告别低效数据转换:xlsx2csv效率工具的全方位实战指南
  • 实时战场定位:PUBG玩家的战术决策优化方案