当前位置:  技术问答>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又如何能确定内核的起始地址呢?怎么能通过这个文件来设置内核的起始地址呢?

一头雾水,望同仁们指定,不甚感激!!

|
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指令的计算,需要代码自己来做。

|


这个就不是一两个帖子能说清楚的了。Understanding the Linux Kernel里面解释得比较详细。
简单来说就是建立初始的page table,这时要把实模式下的地址也写进这个page table,使得实模式下的地址在保护模式和实模式都可以用。然后通知硬件启用MMU。但对于没有MMU的平台,应该是要通知软件MMU开始运作。

还是参考一下书吧。有些功夫是不能省的,还要结合代码来看。

    
 
 

您可能感兴趣的文章:

  • 关于armlinux启动时间~~
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 怎么进入armlinux???
  • armlinux环境下,液晶屏频闪严重,请教解决办法!
  • 交叉编译armlinux模块出错!???


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3