【ZYNQ Linux开发】使用 boot.scr 启动 Linux 报错 Bad Linux ARM64 Image magic! 调试过程记录

article/2025/6/28 13:36:17

文章目录

  • 1 问题描述
  • 2 解决问题过程
  • 3 问题总结

1 问题描述

       在编写我的系列博客:【ZYNQ Linux移植】6-搭建日常开发的环境 时,尝试在 ZYNQ MP上搭建开发用的镜像,尝试把比特文件和设备树文件从 BOOT.BIN 剥离(只包含 fsblelf 、pmufw.elf 、bl31.elf、u-boot.elf 基本不需要变动的部分),以 Petalinux 生成的 boot.scr 为模版进行修改,试图在 u-boot 加载设备树文件和比特文件(包括手动加载)启动Linux会失败,报错 Bad Linux ARM64 Image magic!

       修改后的 boot.scr 内容如下:

# This is a boot script for U-Boot
# Generate boot.scr:
# mkimage -c none -A arm -T script -d boot.cmd.default boot.scr
#
################for boot_target in ${boot_targets};
doif test "${boot_target}" = "jtag" ; thenbooti 0x00200000 0x04000000 0x00100000exit;fiif test "${boot_target}" = "mmc0" || test "${boot_target}" = "mmc1" ; thenif test -e ${devtype} ${devnum}:${distro_bootpart} /image.ub; thenfatload ${devtype} ${devnum}:${distro_bootpart} 0x10000000 image.ub;bootm 0x10000000;exit;fiif test -e ${devtype} ${devnum}:${distro_bootpart} /Image; thenfatload ${devtype} ${devnum}:${distro_bootpart} 0x00200000 Image;;fiif test -e ${devtype} ${devnum}:${distro_bootpart} /system-top.dtb; thenfatload ${devtype} ${devnum}:${distro_bootpart} 0x00100000 system-top.dtb;fiif test -e ${devtype} ${devnum}:${distro_bootpart} /rootfs.cpio.gz.u-boot; thenfatload ${devtype} ${devnum}:${distro_bootpart} 0x04000000 rootfs.cpio.gz.u-boot;booti 0x00200000 0x04000000 0x00100000exit;fiif test -e ${devtype} ${devnum}:${distro_bootpart} /system.bit; thenfatload ${devtype} ${devnum}:${distro_bootpart} 0x02000000 system.bit;fpga loadb 0 ${fileaddr} ${filesize}fibooti 0x00200000 - 0x00100000exit;fiif test "${boot_target}" = "xspi0" || test "${boot_target}" = "qspi" || test "${boot_target}" = "qspi0"; thensf probe 0 0 0;if test "image.ub" = "image.ub"; thensf read 0x10000000 0xF00000 0x6400000;bootm 0x10000000;exit;fiif test "image.ub" = "Image"; thensf read 0x00200000 0xF00000 0x1D00000;sf read 0x04000000 0x4000000 0x4000000booti 0x00200000 0x04000000 0x00100000exit;fiexit;fiif test "${boot_target}" = "nand" || test "${boot_target}" = "nand0"; thennand infoif test "image.ub" = "image.ub"; thennand read 0x10000000 0x4100000 0x6400000;bootm 0x10000000;exit;fiif test "image.ub" = "Image"; thennand read 0x00200000 0x4100000 0x3200000;nand read 0x04000000 0x7800000  0x3200000;booti 0x00200000 0x04000000 0x00100000exit;fifi
done

       本身是在 Petalinux 生成的 boot.scr 的基础上加入了判断如果有 bit 文件,就加载 bit 文件:

if test -e ${devtype} ${devnum}:${distro_bootpart} /system.bit; thenfatload ${devtype} ${devnum}:${distro_bootpart} 0x02000000 system.bit;fpga loadb 0 ${fileaddr} ${filesize}
fi

       但实际测试发现这样启动最后会报错:Bad Linux ARM64 Image magic!

2 解决问题过程

       尝试在 u-boot 命令行把 boot.scr 的有效内容手动输入:

fatload mmc 1:1 0x00200000 Image;
fatload mmc 1:1 0x00100000 system-top.dtb;
fatload mmc 1:1 0x02000000 system.bit;
fpga loadb 0 ${fileaddr} ${filesize}
booti 0x00200000 - 0x00100000

       可以正常启动系统。

       矛头直至 boot.scr 本身,由于之前是设置 boot_cmd 为直接运行 boot.scr,再尝试手动输入,也会报错。且全套使用 Petalinux,把比特文件和设备树都打包到 BOOT.BIN,也可以启动。这就基本确定是 boot.scr 的问题了。


       boot.scr 本身是 u-boot 下的一个脚本文件。那怎么对其进行调试呢,最简单的,使用万能打印大法,在可能有问题的地方添加打印信息,通过打印内容来判断问题所在。于是,修改 boot.scr 进行测试:

# This is a boot script for U-Boot
# Generate boot.scr:
# mkimage -c none -A arm -T script -d boot.cmd.default boot.scr
#
################for boot_target in ${boot_targets};
doif test "${boot_target}" = "jtag" ; thenecho "point0";booti 0x00200000 0x04000000 0x00100000exit;fiif test "${boot_target}" = "mmc0" || test "${boot_target}" = "mmc1" ; thenecho "point1";if test -e ${devtype} ${devnum}:${distro_bootpart} /image.ub; thenecho "point2";printenv devtype;printenv devnum;printenv distro_bootpart;fatload ${devtype} ${devnum}:${distro_bootpart} 0x10000000 image.ub;bootm 0x10000000;exit;fiif test -e ${devtype} ${devnum}:${distro_bootpart} /Image; thenecho "point3";printenv devtype;printenv devnum;printenv distro_bootpart;fatload ${devtype} ${devnum}:${distro_bootpart} 0x00200000 Image;fiif test -e ${devtype} ${devnum}:${distro_bootpart} /system-top.dtb; thenecho "point4";printenv devtype;printenv devnum;printenv distro_bootpart;fatload ${devtype} ${devnum}:${distro_bootpart} 0x00100000 system-top.dtb;fiif test -e ${devtype} ${devnum}:${distro_bootpart} /rootfs.cpio.gz.u-boot; thenecho "point5";printenv devtype;printenv devnum;printenv distro_bootpart;fatload ${devtype} ${devnum}:${distro_bootpart} 0x04000000 rootfs.cpio.gz.u-boot;booti 0x00200000 0x04000000 0x00100000exit;fiif test -e ${devtype} ${devnum}:${distro_bootpart} /system.bit; thenecho "point6";printenv devtype;printenv devnum;printenv distro_bootpart;fatload ${devtype} ${devnum}:${distro_bootpart} 0x02000000 system.bit;fpga loadb 0 ${fileaddr} ${filesize}fibooti 0x00200000 - 0x00100000exit;fiif test "${boot_target}" = "xspi0" || test "${boot_target}" = "qspi" || test "${boot_target}" = "qspi0"; thensf probe 0 0 0;if test "image.ub" = "image.ub"; thensf read 0x10000000 0xF00000 0x6400000;bootm 0x10000000;exit;fiif test "image.ub" = "Image"; thensf read 0x00200000 0xF00000 0x1D00000;sf read 0x04000000 0x4000000 0x4000000booti 0x00200000 0x04000000 0x00100000exit;fiexit;fiif test "${boot_target}" = "nand" || test "${boot_target}" = "nand0"; thennand infoif test "image.ub" = "image.ub"; thennand read 0x10000000 0x4100000 0x6400000;bootm 0x10000000;exit;fiif test "image.ub" = "Image"; thennand read 0x00200000 0x4100000 0x3200000;nand read 0x04000000 0x7800000  0x3200000;booti 0x00200000 0x04000000 0x00100000exit;fifi
done

       根据调试信息看:

JTAG: Trying to boot script at 0x20000000
## Executing script at 20000000
Wrong image format for "source" command
JTAG: SCRIPT FAILED: continuing...
switch to partitions #0, OK
mmc0(part 0) is current device
** No partition table - mmc 0 **
switch to partitions #0, OK
mmc1 is current device
Scanning mmc 1:1...
Found U-Boot script /boot.scr
2817 bytes read in 15 ms (182.6 KiB/s)
## Executing script at 20000000
point0
Bad Linux ARM64 Image magic!
SCRIPT FAILED: continuing...
** Unable to read file / **
SF: Detected n25q256ax1 with page size 256 Bytes, erase size 64 KiB, total 32 MiB
device 0 offset 0x80000, size 0x1f80000
SF: 33030144 bytes @ 0x80000 Read: OK
QSPI: Trying to boot script at 0x20000000
## Executing script at 20000000
Wrong image format for "source" command
QSPI: SCRIPT FAILED: continuing...

       根据打印信息,发现在 run distro_bootcmd 时,在转换到用 mmc 1:1 启动时,找到了 boot.scr,但由于大循环是从 boot_targets 按顺序取的,而其值默认为:

boot_targets=jtag mmc0 mmc1 qspi0 nand0 usb0 usb1 scsi0 pxe dhcp

       由于 jtag 排在前面,所以在尝试按照默认的地址: 0x00200000(内核)、0x04000000(initramfs)、0x00100000(设备树)加载时导致魔数校验失败


       所以直接的,有两种解决方法。

       一是修改 boot_targets 环境变量,改为:

env set boot_targets "mmc0 mmc1 jtag qspi0 nand0 usb0 usb1 scsi0 pxe dhcp"

       相当于把 jtag 的启动优先级往后排了,但还是可以从 jtag 启动。

       二是在 boot.scr 中直接把关于 jtag 的部分删除掉,但这样就没法从 jtag 启动了。

       后来想想感觉不对啊,为什么这个脚本源于 Petalinux,但使用 Petalinux 的三件套(boot.scr 、BOOT.BIN、image.ub)可以正常启动呢?既然 boot.scr 本身就是从 Petalinux 参考过来的,为了探索问题的原因,还是得回到 Petalinux。

​       先在 FAT 分区放入 Petalinux 的三件套,然后在启动阶段提前看回车,打断 Linux 系统的启动,我们尝试把 boot_targets 打印出来,看一下,结果如下:

boot_targets=mmc1 jtag mmc0 mmc1 qspi0 nand0 usb0 usb1 scsi0 pxe dhcp

       好家伙,原来 Petalinux 也就是把这个环境变量改了,因为在 Petalinux 的设置中,我设置了使用 mmc1 启动,所以它自己就直接在 boot_targets 最前面加了 mm1 ,甚至都不是像我们上面一样,把 mmc1 提前,后面直接没管,相当于如果用 qspi 启动,在次前会两次尝试从 mmc1启动。大家也可以像 Petalinux 这样修改环境变量:

env set boot_targets "mmc1 jtag mmc0 mmc1 qspi0 nand0 usb0 usb1 scsi0 pxe dhcp"

       另外,既然都直到是 u-boot 环境变量的问题,那么能不能直接通过设备树给 u-boot 传递相关环境变量的值呢?比如:

/ {chosen {bootargs = "console=ttyPS0,115200 earlycon root=/dev/mmcblk1p2 rw rootwait";bootcmd = "run distro_bootcmd";boot_targets = "mmc0 mmc1 jtag qspi0 nand0 usb0 usb1 scsi0 pxe dhcp";stdout-path = "serial0:115200n8";};
};

       答案是使用设备树传递环境变量的值肯定是可以的,但是注意!!!如果是生成 BOOT.bin 时不把设备树包含进去,必须要在 u-boot 下修改再保存进 flash,而不能依靠设备树给 u-boot 传递 boot_cmd 和 boot_targets 环境变量的值,因为我们的模式是使用 boot.scr 加载设备,如果我们不提前修改 boot_cmd,就不会自动运行 boot.scr,而由于上面出错在加载设备树前,所以必须提前设置好 boot_targets,不然还会从 jtag 开始尝试启动。

       所有都设置好,就可以正常直接上电就启动系统了,我这里用的是 Debain:

3 问题总结

       问题出现的根本原因在于自己在移植 u-boot 时,没有对 bootcmd 、boot_targets 进行正确的设置,然后就套用了 Petalinux 的 boot.scr 尝试进行启动,在切换到 mmc1:1 (SD 卡 FAT 分区)后,仍然按照默认的 boot_targets 顺序进行尝试,首先尝试 jtag 启动,然后因为对应内存位置没有镜像,从而启动失败。

       对应的,只需要修改 u-boot 中 bootcmd 、boot_targets 两个环境变量的值,再保存到 Flash 做一次性修改即可。


http://www.hkcw.cn/article/jPdpiPoIox.shtml

相关文章

NLP学习路线图(十二):停用词处理

一、 文本预处理的基石:为什么关注停用词? 在自然语言处理(NLP)的流程中,原始文本数据必须经过预处理才能被算法有效理解。文本预处理包括: 分词(Tokenization) 停用词过滤&#x…

vue3项目之大事件管理系统(三) 二级路由:文章分类页,文章管理页

文章目录 一.文章分类页1.封装pageContainer组件2.调用PageContainer组件3.渲染文章分类页ArticleChannel封装api接口页面调用动态渲染父传子优化:添加loading效果优化:无数据返回时的页面渲染 4.添加弹层并显示弹层组件封装ChannelEdit.vue组件在文章列表页ArticleChannel调用…

成都银行14年估值大逆转 政务类业务助力逆袭

2022年以来,中国银行业普遍面临信贷需求不足的难题,资产扩张明显放缓,但成都银行似乎并不存在这个烦恼。2021年至2024年间,上市银行(含港股)总资产合计增长了33%。其中,成都银行异军突起,成为扩张最快的商业银行——期间其总资产增长了63%,居上市银行首位。财报数据显…

端午快乐还是端午安康 祝福语之争引发热议

端午节这天,许多网友在互道祝福时犯了难,到底是祝“端午快乐”还是“端午安康”。其实不必太纠结。说“快乐”没问题,说“安康”也可以。设立端午节的初衷是欢乐喜庆、祛毒平安的。古诗词中也有描绘端午节快乐祥和的诗句,如《端午三殿宴群臣并序》中的“叹节气之循环,美君…

百年陈韵,三代匠心——陈汇堂新会陈皮的传承与新生

百年陈韵,三代匠心——陈汇堂新会陈皮的传承与新生 在五邑大地氤氲的柑橘香里,藏着一段跨越世纪的陈皮传奇。自清末民初的货郎担起第一篓新会柑皮,到如今现代化仓储中静默陈化的岁月瑰宝,陈汇堂三代人用双手编织出一张贯通历史与…

只剩几面烂墙的别墅拍出2683万 瑕疵房产高价成交

近日,在京东资产交易平台上,一栋存在瑕疵的别墅(国有建设用地使用权部分)进行了司法拍卖。起拍价为2073万元,最终以2683万元成交。照片显示,这栋别墅周围搭起了钢架,地面部分只剩几面墙,且部分墙体的钢筋裸露在外,地面散落着碎石,房屋结构已不完整。评估报告显示,此…

吴宣仪《浪姐》助阵嘉宾引粉丝不满 友谊助攻惹争议

近日,吴宣仪选择刘宇作为《乘风2025》总决赛的助演嘉宾,引发部分粉丝不满。吴宣仪在超话中回应称,不应将个人意愿强加于她,她的朋友来助阵应该受到热烈欢迎。她还表示未来还有很多机会,并喜欢听话不乱闹的可爱粉丝。吴宣仪1995年出生于海南海口,2016年正式出道。2018年参…

SkyWalking如何实现跨线程Trace传递

一、概述 SkyWalking 的中构建 Trace 信息时会借助 ThreadLocal来存储一些上下文信息,当遇到跨线程的时候,如果 Trace 的上下文信息没有传递到新线程的ThreadLocal 中,那么链路就断开了。那么SkyWalking是如何解决这个问题的呢? …

日本版安踏在中国“杀”疯了 复古潮流引领销量逆袭

亚瑟士这个品牌虽然名气不如耐克和阿迪达斯,但在地铁通勤、公园晨跑和马拉松比赛中却经常看到人们穿着。亚瑟士被称为“日本版安踏”,近两年在国内越来越受欢迎。亚瑟士的国际化战略与安踏有相似之处。自2006年进入中国市场以来,亚瑟士在中国的表现一直不佳,大部分时间都在…

大明湖一龙舟刚开赛就翻船 网友调侃 北方人不擅水战

北方人不擅长水战这一点再次得到了体现。5月31日,正值端午佳节,山东济南大明湖景区举办了一场龙舟赛,吸引了大量游客前来观赛。比赛于上午9时39分左右开始,两只龙舟敲鼓出发展开角逐。然而,刚一开始,围观的人群中就传来呼声,有游客发现一艘龙舟翻船了,比赛似乎在瞬间结…

杨丞琳发文为42岁陈妍希庆生 愿好友事事顺心

5月31日凌晨,杨丞琳发文为陈妍希庆生,祝福她事事顺心,每天都幸福快乐,并表示永远爱她。2月18日,陈晓和陈妍希在社交平台上宣布离婚。杨丞琳在接受采访时说,作为好友,她尊重陈妍希处理个人事务的方式。得知消息时,她和其他人一样感到意外,但作为姐妹,无论遇到什么转折…

保卫处招硕士研究生 扬州大学回应 非保安岗位需专业背景

近日,有教育机构发布了一则信息,扬州大学计划在2025年招聘人事代理工作人员。其中,学校保卫处需要招聘一名从事校园消防安全与应急管理工作的人员,该岗位要求硕士研究生学历。在扬州大学信息公开网上可以找到这则招聘信息,由学校人力资源处于5月28日发布。该岗位的主要职责…

专家:美断供航发漏算中国国产实力 自主创新迎突破

在当今全球化时代,科技竞争成为国际竞争的核心领域。美国作为科技强国,常利用技术优势对其他国家进行技术封锁以维护自身领先地位。近期,美国突然宣布停止向中国商飞公司提供航空发动机关键技术,目标直指中国自主研发的C919大飞机。这一举措是对中国航空产业的挑战,也是国…

六一儿童节前50份心愿在病房里点亮 为血液病儿童送上温暖

六一儿童节前夕,5月30日,成都市妇女儿童中心医院血液科的护士站忙碌起来。护士和志愿者们将病房里孩子们的心愿礼物包装整齐,准备开启一场特殊的旅程——这是成都市点亮微心愿血液病儿童关爱中心与成都市妇女儿童中心医院连续第七年发起的“心愿计划”,旨在儿童节期间为住院…

一文详谈Linux中的时间管理和定时器编程

(目录) 先说一些在计算机中需要用到时间的地方:系统日志log、OS调度(时间片、定时器)等等~~ 时间的计量 计时的方式发展:日晷、沙漏 -> 机械钟 -> 石英振荡器、晶振 -> 铯原子钟 -> 氢原子钟 计算机中的计时方式&…

88岁谢贤现身公园游玩 风采依旧

5月27日,媒体拍摄到88岁的演艺圈“常青树”谢贤外出逛公园。他坐着轮椅出行,由两位菲佣保姆细心照料。镜头下的谢贤状态不佳,身体状况明显不如从前,即使拄着拐杖也只能缓慢行走一小段路,且需要搀扶。尽管如此,四哥的帅气依旧不减当年。他戴着一顶黑色棒球帽,这个习惯多年…

泰一幼儿园发生食物中毒事件 数百学生受影响

当地时间5月29日,泰国乌隆他尼府一所幼儿园发生集体食物中毒事件,数百名学生出现呕吐、腹部绞痛、腹泻等症状。截至目前,已有超过200名学生出现食物中毒症状,其中88人住院治疗,3人病情严重。责任编辑:zx0001

吴宣仪回应刘宇粉丝 舞台合作我做主

《浪姐6》的舞台从来不缺话题,这次吴宣仪邀请刘宇作为助阵嘉宾,却意外引发粉丝争议。部分粉丝在社交平台表达不满,认为两人的风格不搭,甚至担心会影响吴宣仪的表现。面对质疑,吴宣仪直接回应:“朋友来助阵应该热烈欢迎,别把个人情绪强加到我身上。”这句话瞬间点燃讨论,…

被保姆拐走33年的男婴结婚了 命运的重逢

2018年初,重庆的朱晓娟接到一个电话,询问她26年前是否丢过一个儿子。朱晓娟肯定地回答“是”,并告诉对方丢失的儿子已经被公安机关找回,现在早已长大成人。随后,记者给她发了一张照片,照片上的小孩与朱晓娟的小儿子特别像。这勾起了朱晓娟对1992年的回忆。当时,她和丈夫…

xQueueSendFromISR使用

建议: 在99%的应用中,应该始终使用标准模式: BaseType_t xHigherPriorityTaskWoken pdFALSE; xQueueSendFromISR(..., &xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken);