返回信息流我看到uboot的代码,do_bootm_linux中通过
theKernel (0, bd->bi_arch_number, bd->bi_boot_params);
跳转到了kernel执行。
这个theKernel的地址是0x50008000,然后搜索了一下发现
arch/arm/boot/compressed/.vmlinux.cmd:cmd_arch/arm/boot/compressed/vmlinux := arm-linux-ld -EL --defsym zreladdr=0x50008000 --defsym params_phys=0x50000100 -p --no-undefined -X /home/wyang2/test/usr/local/arm/4.4.1/bin/../lib/gcc/arm-none-linux-gnueabi/4.4.1/libgcc.a -T arch/arm/boot/compressed/vmlinux.lds arch/arm/boot/compressed/head.o arch/arm/boot/compressed/piggy.o arch/arm/boot/compressed/misc.o -o arch/arm/boot/compressed/vmlinux
就是说这个zreladdr是这个地址,但是我看了arch/arm/boot/compressed/head.S
这个zreladdr是一个待定的空间。网上说是直接跳转到head.S的start,所以有点晕了。
请教大虾
这是一条镜像帖。来源:北邮人论坛 / embedded-system / #9738同步于 2010/11/4
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Embedded_System机器人发帖
arm的板子,从uboot跳转到kernel的话第一个跳转到哪里执行呢?
hman
2010/11/4镜像同步18 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
我一般是下载zImage到某个地址,然后go addr,实际上调用的就是下面这句话,你可以对
比一下,最核心的过程肯定是一样的:把pc的下一个值设为addr
rc = ((ulong(*)(int,int,uint))addr) (0,
gd->bd->bi_arch_number,
gd->bd->bi_boot_params);
【 在 hman (Wizard) 的大作中提到: 】
: 我看到uboot的代码,do_bootm_linux中通过
: theKernel (0, bd->bi_arch_number, bd->bi_boot_params);
: 跳转到了kernel执行。
: ...................
另外在uboot的do_bootm中有这么一句,是启动zImage的。
if (*(ulong *)(addr + 9*4) == LINUX_ZIMAGE_MAGIC)
我看了这个LINUX_ZIMAGE_MAGIC和head.S里面的0x016f2818一样。 但是我怎么也没算明白这个地址为什么要偏移addr + 9*4.
因为我觉得如果这个addr是start的地址,那么偏移就只有addr+4*4?
下面一个事原始的代码,另一个是objdump的结果。
start:
.type start,#function
.rept 8
mov r0, r0
.endr
b 1f
.word 0x016f2818 @ Magic numbers to help the loader
bootm启动的是uImage,uImage是uboot把zImage打包,加了一个XX字节的头,bootm的时候
先解开一下,然后根据头的信息来启动zImage.你说的那个magic number肯定是这个头里的,不知道uImage到底有啥用,启动还要慢个一两秒,
我基本不用
【 在 hman (Wizard) 的大作中提到: 】
: 另外在uboot的do_bootm中有这么一句,是启动zImage的。
: if (*(ulong *)(addr + 9*4) == LINUX_ZIMAGE_MAGIC)
: 我看了这个LINUX_ZIMAGE_MAGIC和head.S里面的0x016f2818一样。 但是我怎么也没算明白这个地址为什么要偏移
: ...................
恩? 不是吧,我的kernel编译出来就是zImage,你可以看看makefile的zImage目标。
zImage load到内存是自己解压缩的
【 在 ArmStrong 的大作中提到: 】
: bootm启动的是uImage,uImage是uboot把zImage打包,加了一个48字节的头,bootm的时候
: 先解开一下,然后根据头的信息来启动zImage.不知道到底有啥用,启动还要慢个一两秒,
: 我基本不用
: ...................
bootm怎么能用zImage呢,会出错的,如果是zImage,那它根本不是bootm命令引导的,而是go命令,就是我贴出来的那句话
【 在 hman (Wizard) 的大作中提到: 】
: 恩? 不是吧,我的kernel编译出来就是zImage,你可以看看makefile的zImage目标。
: zImage load到内存是自己解压缩的
这个是摘自uboot的do_bootm函数的,注释都写的是zImage。是不是uboot的版本不一样?
#ifdef CONFIG_ZIMAGE_BOOT
#define LINUX_ZIMAGE_MAGIC 0x016f2818
if (*(ulong *)(addr + 9*4) == LINUX_ZIMAGE_MAGIC) {
printf("Boot with zImage \n");
addr = virt_to_phys(addr);
hdr->ih_os = IH_OS_LINUX;
hdr->ih_ep = ntohl(addr);
goto after_header_check;
}
#endif
zImage是ARM Linux常用的一种压缩映像文件,uImage是U-boot专用的映像文件,它是在zImage之前加上一个长度为0x40的“头”,说明这个映像文件的类型、加载位置、生成时间、大小等信息。换句话说,如果直接从uImage的0x40位置开始执行,zImage和uImage没有任何区别。另外, Linux2.4内核不支持uImage,Linux2.6内核加入了很多对嵌入式系统的支持,但是uImage的生成也需要设置。
http://blog.csdn.net/pottichu/archive/2009/06/11/4261150.aspx 这个地方转的
之前回帖总结的一段东东
===========================
前两天研究过do_boom命令,这是当时做的笔记,希望对LZ有帮助
bootm中的处理流程
1、定义全局结构体变量header用于保存内核镜像的首部,定义hdr指针指向header
2、若bootm命令带地址参数,则指针addr等于该参数,否则addr=CFG_LOAD_ADDR
3、addr指针已经指向内核镜像,将内核镜像的首部拷贝到header
4、检查header(也就是内核镜像首部)内容并打印:这其中包括对内核镜像整体进行CRC校验
5、通过首部中的压缩类型分别处理:如果是压缩的,将镜像的Data部分解压后复制到header->load_addr(mkeimage中的-a参数决定)指向的位置;如果未经压缩,直接复制,地址同上。
6、对于kernel类型的镜像,按照OS类型进入不同的处理分支,Linux分支:do_bootm_linux函数
7、*kernel=header->Entry Point,给*kernel指针赋值为入口地址(mekimage中的-e参数确定)
8、将gd中开发板相关信息拷贝到kbd当中供内核使用:kbd=gd->bd
===========================
参考:
http://forum.byr.edu.cn/article/Embedded_System/6267
http://bbs.byr.cn/article/Embedded_System/1065
话说不知不觉间版里已经多了好多资料,真不错!!