linux内核镜像的加载地址和入口地址

copy from :https://blog.csdn.net/whahu1989/article/details/85255538  https://wenku.baidu.com/view/2670021c195f312b3069a532.html

linux内核启动时几个关键地址  
1、名词解释
ZTEXTADDR  解压代码运行的开始地址。没有物理地址和虚拟地址之分,因为此时MMU处于关闭状态。这个地址不一定时RAM的地址,可以是支持读写寻址的flash等存储中介。

ZRELADDR  内核启动在RAM中的物理地址。压缩的内核映像被解压到这个地址,然后执行。  
           This is the address where the decompressed kernel will be written, and eventually executed. The following constraint must be valid:     
                      __virt_to_phys(TEXTADDR) == ZRELADDR  The initial part of the kernel is carefully coded to be position independent.  
                      
TEXTADDR  内核启动的虚拟地址,与ZRELADDR相对应。一般内核启动的虚拟地址为RAM的第一个bank地址加上0x8000。        
          TEXTADDR = PAGE_OFFSET + TEXTOFFST  Virtual start address of kernel, normally PAGE_OFFSET + 0x8000.
          This is where the kernel image ends up. With the latest kernels, it must be located at 32768 bytes into a 128MB region.
          Previous kernels placed a restriction of 256MB here.   
          
TEXT_OFFSET  内核偏移地址,即内核起始位置相对于内存起始位置的偏移,对于相对于物理内存还是相对于虚拟内存都是一样的结果。在arch/arm/makefile中设定。

PHYS_OFFSET  RAM第一个bank的物理起始地址,即物理内存的起始地址。
             Physical start address of the first bank of RAM.   
             PAGE_OFFSET  RAM第一个bank的虚拟起始地址,即内核虚拟地址空间的起始地址。
              
2、小结  
从上面分析可知道,linux内核被bootloader拷贝到RAM后,解压代码从ZTEXTADDR开始运行(这段代码是与位置无关的PIC)。
内核被解压缩到ZREALADDR处,也就是内核启动的物理地址处。
相应地,内核启动的虚拟地址被设定为TEXTADDR,满足如下条件:
  TEXTADDR = PAGE_OFFSET + TEXT_OFFSET 内核启动的物理地址和虚拟地址满足入下条件:  
  ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET)= virt_to_phys(TEXTADDR)
  假定开发板为smdk2410,则有:
  内核启动的虚拟地址 TEXTADDR  = 0xC0008000 内核启动的物理地址   ZRELADDR  = 0x30008000  
  如果直接从flash中启动还需要设置ZTEXTADDR地址。

uboot引导linux内核镜像(uImage)启动时,会有2个地址

加载地址(Load Address),即内核镜像整体要放置的内存空间位置
入口地址(Entry Point),即从内核镜像中开始执行的地址
示意图如下,

其中,内核镜像的加载地址是100,入口地址是180,也就是说内核镜像本身要加载到内存地址为100的地方,然后从地址180开始执行内核代码(一般是_start指示的tag位置)。

uboot启动内核的步骤是

先把内核镜像uImage拷贝到内存某个位置上
然后使用bootm命令去启动内存里的内核镜像
如果我们没有把内核镜像uImage拷贝到指定的加载地址,那么bootm就会把内核镜像在内存中移动到指定的加载地址上,然后再去从内核的入口地址开始执行。

加载地址和入口地址在uImage的开头部分有定义,这是编译内核镜像时指定的。
————————————————
版权声明:本文为CSDN博主「爱是恒久忍耐1989」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/whahu1989/article/details/85255538

原文地址:https://www.cnblogs.com/Oude/p/12217750.html

时间: 2024-10-01 05:05:22

linux内核镜像的加载地址和入口地址的相关文章

Linux内核启动及加载根文件系统

</pre></h1><p><span style="font-family:KaiTi_GB2312;font-size:18px;">上接博文<<a target=_blank href="http://blog.csdn.net/gqb_driver/article/details/8931775" style="text-decoration: none; font-family: 'Mi

Uboot 引导内核时加载地址与入口地址问题

如果使用 mkimage 生成内核镜像文件的话,会在内核的前头加上了 64 bytes 的信息头,供建立 tag 之用.bootm 命令会首先判断 bootm xxx 这个指定的地址 xxx 与 -a 指定的加载地址是否相同. 如果不同的话会从这个地址开始提取出这个 64 bytes 的头部,对其进行分析,然后把去掉头部的内核复制到 -a 指定的加载地址去运行; 如果相同的话那就让其原封不同的放在那,但 -e 指定的入口地址会推后 64 bytes,以跳过这 64 bytes 的头部. 我们来看

Linux程序动态库加载优化

作者:zhanhailiang 日期:2014-10-26 linux程序动态库加载流程简介 linux从程序(program或对象)变成进程(process或进程),简单说来需要经过三步: fork进程,在内核创建进程相关内核项,加载进程可执行文件: 查找依赖的.so,逐一加载映射虚拟地址: 初始化程序变量: 如下例通过strace查看pwd命令执行过程: [root@~/wade/codeReview/learningc]# strace pwd execve("/bin/pwd"

简单的Linux 驱动模块编译,加载过程

简单的Linux 驱动模块编译,加载过程 2010-03-14 14:48:24|  分类: Driver |  标签: |字号大中小 订阅 本文记录我的第一个Linux设备驱动程序的编译过程.遇到问题的解决方法. 环境:2.4.18-14的内核,Linux内核源码:2.4.18.       Linux内核源码路径:/usr/src/linux(这个源码是从kernel.org网站download的2.4.18版本)        按照<linux设备驱动开发详解>一书中的步骤实现经典例子&

Linux进程2——进程加载

Linux每个可执行程序都具有相同的虚拟地址分配,当OS启动进程时,是如何加载程序呢? 1. 进程结构体 每个进程都具有task_struct结构体,该结构体的mm字段负责对程序内存的虚拟地址映射. mm中每个vm_area_struct对应可执行程序的段虚拟地址空间,例如.text等.当程序被执行时,程序的这些虚拟地址 就被填入不同的vm_area_struct中. struct vm_area_struct { ... ... unsigned long vm_start; //虚拟地址开始

简单的Linux驱动程序以及如何加载/卸载驱动

今天记录一下简单的Linux驱动程序怎么写以及如何加载/卸载驱动 以hello.c为例: hello.c #ifndef __KERNEL__ # define __KERNEL__ #endif #ifndef MODULE # define MODULE #endif #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> MODULE_LICENSE("Dua

加载CDN加速服务地址

Jquery是个非常流行的JS前端框架,在很多网站都能看到它的身影.很多网站都喜欢采用一些Jquery CDN加速服务,这样网站加载jquery会更快.之前火端网络的一些网站都是使用Google的jquery CDN,如:http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js ,但是由于最近Google打不开,这些CDN地址也无法访问,而JS往往放在网页的head里,JS无法访问导致网站打开非常慢,只能是全部替换掉CDN链接

Android获取其他进程加载的模块基地址

获取目标进程模块(.so)加载地址是通过解析/proc/[pid]/maps得到的. 可以通过adb shell手动获取: ①. 首先通过ps命令查看进程的pid ②. cat /proc/[pid]/maps 使用程序实现如下代码: #include <stdio.h> int main(int argc, char* argv[]) { if (argc != 3) { printf("pid or soName error\r\n"); return 1; } pid

使a标签失效的js,加载a标签链接地址内容到指定容器

$(function(){           $(".pagination > ul >li > a").click(           function(){             $.ajax({               type: "POST",               url:$(this).attr("href"),    //取得a标签链接地址               data:ajaxpage=1