当前位置: 技术问答>linux和unix
关于armlinux或者uclinux的启动地址的问题?
来源: 互联网 发布时间:2016-07-08
本文导语: 以下来自“源码开放的嵌入式系统软件分析与实践”原文,对此不甚理解: 内核链接脚本文件vmlinux.lds定义各个模块的装载地址。内核的下载一般通过板子上的bootloader来完成,默认下载地址在0xc0008000处,下载地址可...
以下来自“源码开放的嵌入式系统软件分析与实践”原文,对此不甚理解:
内核链接脚本文件vmlinux.lds定义各个模块的装载地址。内核的下载一般通过板子上的bootloader来完成,默认下载地址在0xc0008000处,下载地址可以通过修改arch/arm/Makefile文件的TEXTADDR来设置。TEXTADDR的值在make时传递给arch/arm/vmlinux.lds。在链接时,arm-linux ld将使用vmlinux.lds来定位内核的起始地址。
我们知道,任何二进制文件的装载都是通过装载工具来设置的啊?其装载地址也是自己设定的啊?比如ADS将系统的SDRAM映射到起始地址为0x0处,并将image.ram载入从0x8000开始的SDRAM中,加载后修改pc指针寄存器的值为0x8000并执行(出自“arm应用系统开发详解”)。
再说,假如我的开发板并没有映射那个地址(我映射到其他的地址上去了),vmlinux.lds又如何能确定内核的起始地址呢?怎么能通过这个文件来设置内核的起始地址呢?
一头雾水,望同仁们指定,不甚感激!!
内核链接脚本文件vmlinux.lds定义各个模块的装载地址。内核的下载一般通过板子上的bootloader来完成,默认下载地址在0xc0008000处,下载地址可以通过修改arch/arm/Makefile文件的TEXTADDR来设置。TEXTADDR的值在make时传递给arch/arm/vmlinux.lds。在链接时,arm-linux ld将使用vmlinux.lds来定位内核的起始地址。
我们知道,任何二进制文件的装载都是通过装载工具来设置的啊?其装载地址也是自己设定的啊?比如ADS将系统的SDRAM映射到起始地址为0x0处,并将image.ram载入从0x8000开始的SDRAM中,加载后修改pc指针寄存器的值为0x8000并执行(出自“arm应用系统开发详解”)。
再说,假如我的开发板并没有映射那个地址(我映射到其他的地址上去了),vmlinux.lds又如何能确定内核的起始地址呢?怎么能通过这个文件来设置内核的起始地址呢?
一头雾水,望同仁们指定,不甚感激!!
|
ld脚本有两个地址,一个是VMA,一个是LMA。VMA用来在编译和链接是计算符号的地址,LMA是加载的地址。两者通常是一样的。
但当你把image烧到不同于VMA的地方是,那么你的LMA就要改成你烧写的地方(通过LD脚本的AT语句)。
在内核启动以前,MMU是不生效的,所以代码其实是运行在实模式。在这个阶段,符号地址需要自己去计算。比如你实际代码在0xf0000000而VMA是0xc0000000。那么你在使用jump或者branch类的指令是,你要把符号的位置(0xc。。。。。)转换成代码所在的真正位置(0xf。。。。。)
所以,简单地说,bootloader如果要把kernel加载到0xc0000000这个地址的话,那么它需要先建立MMU,如果不是,bootloader只能把kernel的镜像copy到内存,然后直接jump到kernel开始的位置(head.S)。由于kernel一开始运行在实模式,没有MMU,所以head.S的代码对于jump和branch指令的计算,需要代码自己来做。
但当你把image烧到不同于VMA的地方是,那么你的LMA就要改成你烧写的地方(通过LD脚本的AT语句)。
在内核启动以前,MMU是不生效的,所以代码其实是运行在实模式。在这个阶段,符号地址需要自己去计算。比如你实际代码在0xf0000000而VMA是0xc0000000。那么你在使用jump或者branch类的指令是,你要把符号的位置(0xc。。。。。)转换成代码所在的真正位置(0xf。。。。。)
所以,简单地说,bootloader如果要把kernel加载到0xc0000000这个地址的话,那么它需要先建立MMU,如果不是,bootloader只能把kernel的镜像copy到内存,然后直接jump到kernel开始的位置(head.S)。由于kernel一开始运行在实模式,没有MMU,所以head.S的代码对于jump和branch指令的计算,需要代码自己来做。
|
这个就不是一两个帖子能说清楚的了。Understanding the Linux Kernel里面解释得比较详细。
简单来说就是建立初始的page table,这时要把实模式下的地址也写进这个page table,使得实模式下的地址在保护模式和实模式都可以用。然后通知硬件启用MMU。但对于没有MMU的平台,应该是要通知软件MMU开始运作。
还是参考一下书吧。有些功夫是不能省的,还要结合代码来看。