注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

deisp的博客

 
 
 

日志

 
 

linux 的重要文件和配置文件config makefile  

2008-05-24 21:30:05|  分类: Makefile 与 Kcon |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

几个重要的内核文件介绍

Linux服务器内核编译基础

--几个重要的RedHat Linux内核文件介绍

在网络中,不少服务器采用的是Linux系统。为了进一步提高服务器的性能,可能需要根据特定的硬件及需求重新编译Linux内核。编译Linux内核,需要根据规定的步骤进行,编译内核过程中涉及到几个重要的文件。比如对于RedHat Linux,在/boot目录下有一些与Linux内核有关的文件,进入/boot执行:ls –l,如图所示。编译过RedHat Linux内核的人对其中的System.map 、vmlinuz、initrd-2.4.7-10.img印象可能比较深刻,因为编译内核过程中涉及到这些文件的建立等操作。那么这几个文件是怎么产生的?又有什么作用呢?本文对此做些介绍。

一、vmlinuz

vmlinuz是可引导的、压缩的内核。“vm”代表“Virtual Memory”。Linux 支持虚拟内存,不像老的操作系统比如DOS有640KB内存的限制。Linux能够使用硬盘空间作为虚拟内存,因此得名“vm”。vmlinuz是可执行的Linux内核,它位于/boot/vmlinuz,它一般是一个软链接,比如图中是vmlinuz-2.4.7-10的软链接。

vmlinuz的建立有两种方式。一是编译内核时通过“make zImage”创建,然后通过:

“cp /usr/src/linux-2.4/arch/i386/linux/boot/zImage /boot/vmlinuz”产生。zImage适用于小内核的情况,它的存在是为了向后的兼容性。二是内核编译时通过命令make bzImage创建,然后通过:“cp /usr/src/linux-2.4/arch/i386/linux/boot/bzImage /boot/vmlinuz”产生。bzImage是压缩的内核映像,需要注意,bzImage不是用bzip2压缩的,bzImage中的bz容易引起误解,bz表示“big zImage”。 bzImage中的b是“big”意思。

zImage(vmlinuz)和bzImage(vmlinuz)都是用gzip压缩的。它们不仅是一个压缩文件,而且在这两个文件的开头部分内嵌有gzip解压缩代码。所以你不能用gunzip 或 gzip –dc解包vmlinuz。

内核文件中包含一个微型的gzip用于解压缩内核并引导它。两者的不同之处在于,老的zImage解压缩内核到低端内存(第一个640K),bzImage解压缩内核到高端内存(1M以上)。如果内核比较小,那么可以采用zImage 或bzImage之一,两种方式引导的系统运行时是相同的。大的内核采用bzImage,不能采用zImage。

vmlinux是未压缩的内核,vmlinuz是vmlinux的压缩文件。

二、 initrd-x.x.x.img

initrd是“initial ramdisk”的简写。initrd一般被用来临时的引导硬件到实际内核vmlinuz能够接管并继续引导的状态。图中的initrd-2.4.7-10.img主要是用于加载ext3等文件系统及scsi设备的驱动。比如,使用的是scsi硬盘,而内核vmlinuz中并没有这个scsi硬件的驱动,那么在装入scsi模块之前,内核不能加载根文件系统,但scsi模块存储在根文件系统的/lib/modules下。为了解决这个问题,可以引导一个能够读实际内核的initrd内核并用initrd修正scsi引导问题。initrd-2.4.7-10.img是用gzip压缩的文件,下面来看一看这个文件的内容,操作步骤如下图所示:

从图中linuxrc这个脚本的内容可以看到,initrd实现加载一些模块和安装文件系统等。

initrd映象文件是使用mkinitrd创建的。mkinitrd实用程序能够创建initrd映象文件。这个命令是RedHat专有的。其它Linux发行版或许有相应的命令。这是个很方便的实用程序。具体情况请看帮助:man mkinitrd

下面的命令创建initrd映象文件:

三、 System.map

System.map是一个特定内核的内核符号表。它是你当前运行的内核的System.map的链接。

内核符号表是怎么创建的呢? System.map是由“nm vmlinux”产生并且不相关的符号被滤出。对于本文中的例子,编译内核时,System.map创建在/usr/src/linux-2.4/System.map。像下面这样:

nm /boot/vmlinux-2.4.7-10 > System.map

下面几行来自/usr/src/linux-2.4/Makefile:

nm vmlinux | grep -v '(compiled)|(.o$$)|( [aUw] )|(..ng$$)|(LASH[RL]DI)' | sort > System.map

然后复制到/boot:

cp /usr/src/linux/System.map /boot/System.map-2.4.7-10

下图是System.map文件的一部分:

在进行程序设计时,会命名一些变量名或函数名之类的符号。Linux内核是一个很复杂的代码块,有许许多多的全局符号。

Linux内核不使用符号名,而是通过变量或函数的地址来识别变量或函数名。比如不是使用size_t BytesRead这样的符号,而是像c0343f20这样引用这个变量。

对于使用计算机的人来说,更喜欢使用那些像size_t BytesRead这样的名字,而不喜欢像c0343f20这样的名字。内核主要是用c写的,所以编译器/连接器允许我们编码时使用符号名,当内核运行时使用地址。

然而,在有的情况下,我们需要知道符号的地址,或者需要知道地址对应的符号。这由符号表来完成,符号表是所有符号连同它们的地址的列表。上图就是一个内核符号表,由上图可知变量名checkCPUtype在内核地址c01000a5。

Linux 符号表使用到2个文件:

/proc/ksyms

System.map

下图是/proc/ksyms的一部分。

/proc/ksyms是一个“proc file”,在内核引导时创建。实际上,它并不真正的是一个文件,它只不过是内核数据的表示,却给人们是一个磁盘文件的假象,这从它的文件大小是0可以看出来。然而,System.map是存在于你的文件系统上的实际文件。当你编译一个新内核时,各个符号名的地址要发生变化,你的老的System.map具有的是错误的符号信息。每次内核编译时产生一个新的System.map,你应当用新的System.map来取代老的System.map。

虽然内核本身并不真正使用System.map,但其它程序比如klogd, lsof和ps等软件需要一个正确的System.map。如果你使用错误的或没有System.map,klogd的输出将是不可靠的,这对于排除程序故障会带来困难。没有System.map,你可能会面临一些令人烦恼的提示信息。

另外少数驱动需要System.map来解析符号,没有为你当前运行的特定内核创建的System.map它们就不能正常工作。

Linux的内核日志守护进程klogd为了执行名称-地址解析,klogd需要使用System.map。System.map应当放在使用它的软件能够找到它的地方。执行:man klogd可知,如果没有将System.map作为一个变量的位置给klogd,那么它将按照下面的顺序,在三个地方查找System.map:

/boot/System.map

/System.map

/usr/src/linux/System.map

System.map也有版本信息,klogd能够智能地查找正确的映象(map)文件。

 Makefile分析(2.4内核arm版)

一、内核源码中makefile文件的分类

      

       Linux-roy内核源码中的makefiles(不含动态生成的.flags文件)主要分为以下四类:

 

1. 主目录下的Makefile(不妨称为main-makefile)

它主要有两个作用:生成vmlinux(内核映像)和modules(模块)。

 

2. 主目录下的Rules.make

Rules.make中定义通用规则供main-makefile和subdir-makefiles调用。

变量subdir-y为用于构建vmlinux(内核)的目录,变量subdir-m为用于构建modules(模块)的目录;subdir-n和subdir-中的目录将不参加构建工作。

变量obj-y为内核的目标文件列表,在各subdir-y中会对其赋相应的值。如:lib/Makefile的第13-14行。变量obj-m为各模块的目标文件列表,在各subdir-m中会对其赋相应的值。如在drivers/Makefile中,在第13行对subdir-y赋值,并在第14行将此列表复制给subdir-m。从第17行开始对subdir-y和subdir-m进行补充,这两个列表的建立完成。obj-n和obj-中所有的目标将被忽略。

 

3. arch/*/目录下的Makefile(不妨称为arch-makefiles)

arch-makefiles是与特定的体系结构相关的,它们分别是针对特定CPU的makefiles。

 

4. 除arch外的子目录下的Makefile(不妨称为subdir-makefiles)

subdir-makefiles只负责在自己的目录中生成目标文件。它们接受来自上层Make传递下来的信息,并根据这些信息来构造一个需要编译的文件列表,并交由Rules.make处理。subdir-makefiles都比较简短,因为通用的规则都已在Rules.make定义了。一般subdir-makefiles的主要工作是对obj-*或subdir-*变量赋值。

 

二、内核和模块构建的过程

 

       下面分析内核编译的动态过程。

 

第一步:make ARCH=arm menuconfig

目标menuconfig的定义在main-makefile的第306行。main-makefile的第308行调用Menuconfig 工具(scripts/Menuconfig),让它根据arch/$(ARCH)/config.in文件的内容在主目录下生成.config文件供以后调用(main-makefile的第37行)。

 

第二步:make ARCH=arm CROSS_COMPILE=arm-linux- dep

include/linux/autoconf.h根据.config文件生成,其内容是若干#define和#undef宏。这些宏通知编译器哪些组件需要编译而哪些不需要,是编译进内核还是编译成模块。这两个文件中的变量是相互对应的。例如.config的第4行是:

CONFIG_ARM=y

这是编译进内核的情况。相应地,include/linux/autoconf.h的第5行是:

#define CONFIG_ARM 1

       编译成模块的例子见.config的第216行:

CONFIG_BINFMT_AOUT=m

       相应地,autoconf.h的第217和218行是:

#undef CONFIG_BINFMT_AOUT

#define CONFIG_BINFMT_AOUT_MODULE 1

 

接下来main-makefile调用split-include工具(scripts/split-include.c)(main-makefile的第314行),分割解析autoconf.h并在include/config目录下生成相应的头文件。autoconf.h的路径通过第一个参数传递给split-include(scripts/split-include.c的第71行)根据刚才提到的autoconf.h的第5行的内容,split-include工具会在include/config/目录下生成arm.h文件,其内容就是一行:

#define CONFIG_ARM 1

 

include/linux/config.h的第4行嵌入了autoconf.h,而内核源码中很多c文件又嵌入这个config.h(例如kernel/printk.c的第28行),于是间接地嵌入了autoconf.h,可见config.h起到的是一个桥梁的作用。

 

在这一步骤中,makefile会调用mkdep工具(scripts/mkdep.c)生成两种包含依赖关系的文件:.hdepend和.depend。

.hdepend只有一个,在主目录下,它表示相应的头文件又依赖于哪些其它的头文件。.hdepend是在main-makefile的第496行执行后生成的。如果存在.hdepend文件,Rules.make会嵌入它(Rules.make第295-297行)。

.depend文件有很多,它表示相应的目标文件依赖哪些源文件(*.c)和头文件(*.h)。主目录下的.depend文件是在main-makefile的第497行执行后生成的。mkdep读取*.c文件,分析出其所依赖的文件。下面以mm/page_alloc.c举例。page_alloc.c的第15-23行为(“…”表示省略):

#include <linux/config.h>

#include <linux/mm.h>

#include <linux/module.h>

mkdep就会在mm/.depend中的第110-118行中写入:

page_alloc.o: page_alloc.c \

   /usr/src/arm-linux/linux-roy/include/linux/mm.h \

   …

   /usr/src/arm-linux/linux-roy/include/linux/module.h \

但接下来的第119行和上面的写法有些不同:

$(wildcard /usr/src/arm-linux/linux-roy/include/config/discontigmem.h) \

   这是因为page_alloc.c中的第244行的内容如下:

#ifndef CONFIG_DISCONTIGMEM

这需要判断discontigmem.h的存在性,而mm目录下的.depend文件的第119行正是起到了这样的作用(若存在则返回文件名,若不存在则返回空)。

 

第三步:make ARCH=arm CROSS_COMPILE=arm-linux- clean

目标clean在main-makefile的第444-449行定义,它所清除文件的文件和目录列表(CLEAN_FILES和CLEAN_DIRS)在203-229行被赋值。

 

第四步:make ARCH=arm CROSS_COMPILE=arm-linux- zImage

make zImage执行后会生成一个用gzip压缩过的内核。对于arm类型的CPU,目标zImage是在arch/arm/boot/Makefile的第146行定义的。它依赖于compressed/vmlinux。而在第152行,又说明了compressed/vmlinux依赖于主目录下的vmlinux。它的生成规则在main-makefile的第281-289行:

vmlinux: include/linux/version.h $(CONFIGURATION) init/main.o init/version.o \

init/do_mounts.o linuxsubdirs

       $(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o init/do_mounts.o \

              --start-group \

              $(CORE_FILES) \

              $(DRIVERS) \

              $(NETWORKS) \

              $(LIBS) \

              --end-group \

              -o vmlinux

ZLDFLAGS是在arch/arm/boot/Makefile的第14行定义的。如果我们指定CROSS_COMPILE 为arm-linux-,则LD为arm-linux-ld(main-makefile的第29行)。LINKFLAGS在arch/arm/Makefile的第10行定义:

LINKFLAGS :=-p -X -T arch/arm/vmlinux.lds

       它指定了链接脚本为arch/arm/vmlinux.lds。

 

make从主目录Makefile开始执行,从中获得与体系结构无关的变量和依赖关系,并同时从arch-makefiles中获得体系特定的变量等信息,这些信息继承并扩展了主目录Makefile提供的变量。先是所有通过“:=”赋值的变量在这个过程中被赋值,然后是所有通过“=”赋值的变量被赋值(实际上类似于宏替换)。然后,main-makefile向下递归调用子目录中的Makefile,把部分变量传递给子目录Makefile。此时构建内核需要的子目录Makefile根据配置信息决定编译哪些源文件,从而构建出一个需要编译的文件列表。在make zImage的时候make会递归进入列表subdir-y里的目录,根据其定义的编译规则决定这些文件的编译方式。然后,make会根据依赖关系树执行命令,编译生成一系列的目标文件,最后根据vmlinux的生成规则(main-makefile的第281-289行),通过链接脚本把这些目标文件链接成vmlinux(例如arch/arm/Makefile第267行)。

 

第五步:make ARCH=arm CROSS_COMPILE=arm-linux- modules

       make module用于生成内核模块(modules),它的规则在main-makefile的388-389行定义。在make modules的时候make会递归进入列表subdir-m里的目录。

vmlinux:

       第六步:make ARCH=arm CROSS_COMPILE=arm-linux- INSTALL_MOD_PATH=<root fs>modules_install

       make module用于安装内核模块,它的规则在main-makefile的396行定义。

 

三、几点说明

 

main-makefile的第37行是:

MAKEFILES = $(TOPDIR)/.config

       MAKEFILES是一个环境变量,如果你的当前环境中定义了MAKEFILES,那么,make会把这个变量中的值做一个类似于include的动作。这个变量中的值是其它的Makefile,用空格分隔。只是,它和include 不同的是,从这个环境变中引入的Makefile 中的目标不会起作用,如果环境变量中定义的文件发现错误,make 也会忽略。子目录中的Makefile与Rules.make都没有嵌入.config文件,它们就是通过main-makefile向下传递MAKEFILES变量得到相关信息的。

 

       在main-makefile的第48-67行所完成的工作是这样的:首先all被定义为第一个目标,然后在55-58行判断.config文件和.depend文件的存在性,如果存在就包含进来。如果.config文件不存在,则把do-it-all设为config(第66行)。目标conifg在第310行定义。如果.config文件存在而.depend文件不存在,则把do-it-all设为depend(第62行)。目标depend在第506行定义。在执行make后,主目录下会生成配置文件.config(如果原来存在.config文件,则被更名为.config.old)。

      

makemrproper用于重新构建内核,它做的清除工作比make clean更加彻底:除了做makeclean的工作外,还要删除.config,.depend等文件,把核心源码恢复到最原始的状态。它在main-makefile的第451-455行定义,它所清除文件的文件和目录列表(MRPROPER_FILES和MRPROPER_DIRS)在232-256行被赋值。

 

递归的make 必须使用MAKE变量,而不是直接用make 命令。如main-makefile的第279行:

@$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" -C arch/$(ARCH)/boot

当使用“-C”参数来make下层Makefile时,“-w”参数就会被自动打开,即在处理makefile

之前和之后,显示工作目录,所以在make的时候会看到屏幕上反复出现Entering directory[some dir]和Leaving directory [some dir]。

 

       一对反引号(`)的作用相当于shell函数,里面的内容是系统shell命令(例如main-make的第496行)。

 

如果在编译的第一步用的是xconfig,则可以参见第302行的定义。在xconfig中,会使用wish程序调用scripts目录下的tk脚本形成图形界面供用户配置。

 

在编译的第二步中,为什么要通过mkdep和split-include工具,而不是通过gcc加上-MM参数来建立依赖关系呢?上文提到过,很多c源文件都会通过linux/config.h而嵌入autoconf.h,如果按照通常方法建立文件依赖关系(.depend),只要更新过autoconf.h,就会造成所有源代码的重新编译。为了优化make过程,减少不必要的重新编译,linux开发了专用的mkdep工具,用它来生成.depend文件。配置内核时,split-include会检查旧的子文件的内容,确定是不是要更新它们。这样,不管autoconf.h修改日期如何,只要其配置不变,make就不会重新编译内核。

 

Rules.make把当前目录下所有的目标文件称为O_TARGET,它的生成规则在第96-102行,最终生成一系列的.o文件;把当前目录下所有的库文件称为L_TARGET,它的生成规则在第114-116行,最终生成一系列的.a文件。注意第62-65行、第104-107行、118-121行、279-282行和304-317行实现了一种增量编译的机制。make每编译一个源文件时会生成一个.flags文件。例如编译mm/swap.c时,会在相同的目录下生成.swap.o.flags文件。它本质上也是Makefile文件,其代码的功能是测试当前的编译选项与上次相比是否作过改动,若改动过就将自己对应的目标文件加入FILES_FLAGS_UP_TO_DATE列表。生成这个文件是供下一次编译用的。下次编译时,当make进入某个子目录,会搜索其中的.flags文件,如果存在则将它们嵌入(第309-312行)。Make会得到FILES_FLAGS_UP_TO_DATE列表,它的内容是不需要更新的目标。于是,系统从编译对象表中删除它们,从而得到FILES_FLAGS_CHANGED列表(第314-317行),这个列表的内容就是需要更新的目标。

 

       Main-makefile的第281-289行起定义vmlinux的生成(链接)规则。vmlinux 是由 HEAD、main.o、version.o、CORE_FILES、DRIVERS、NETWORKS 和 LIBS 组成的。其中,CORE_FILES、NETWORKS、DRIVERS 和LIBS在main-makefile中定义,由 arch-makefiles扩充。而HEAD在arch-makefiles 中定义(例如arch/arm/Makefile的第193行)。HEAD列表中的目标文件需要最先被链接到 vmlinux 中。

       链接脚本(*.lds文件)是通过*.lds.in文件生成的,对于arm,就是vmlinux-armo.lds.in。arch/arm/Makefile的第269-274行定义了.lds的生成规则。vmlinux-armo.lds.in实际上是一个链接脚本模板,只不过相关参数没有确定。arch/arm/Makefile的第274行就是完成“填空”工作(为TEXTADDR、DATAADDR等赋上具体的值),并把完整的信息保存到arch/arm/vmlinux.lds中。

Linux 内核配置系统浅析 linux 的重要文件和配置文件config makefile - liudefang111 - deisp的博客
linux 的重要文件和配置文件config makefile - liudefang111 - deisp的博客
linux 的重要文件和配置文件config makefile - liudefang111 - deisp的博客
linux 的重要文件和配置文件config makefile - liudefang111 - deisp的博客
linux 的重要文件和配置文件config makefile - liudefang111 - deisp的博客
内容:
linux 的重要文件和配置文件config makefile - liudefang111 - deisp的博客
配置系统的基本结构
Makefile
配置文件
实例
参考资料
关于作者
linux 的重要文件和配置文件config makefile - liudefang111 - deisp的博客
在 Linux 专区还有:
linux 的重要文件和配置文件config makefile - liudefang111 - deisp的博客
教程
工具与产品
代码与组件
文章
linux 的重要文件和配置文件config makefile - liudefang111 - deisp的博客
linux 的重要文件和配置文件config makefile - liudefang111 - deisp的博客

随着 Linux 操作系统的广泛应用,特别是 Linux 在嵌入式领域的发展,越来越多的人开始投身到 Linux 内核级的开发中。面对日益庞大的 Linux 内核源代码,开发者在完成自己的内核代码后,都将面临着同样的问题,即如何将源代码融入到 Linux 内核中,增加相应的 Linux 配置选项,并最终被编译进 Linux 内核。这就需要了解 Linux 的内核配置系统。

众所周知,Linux 内核是由分布在全球的 Linux 爱好者共同开发的,Linux 内核每天都面临着许多新的变化。但是,Linux 内核的组织并没有出现混乱的现象,反而显得非常的简洁,而且具有很好的扩展性,开发人员可以很方便的向 Linux 内核中增加新的内容。原因之一就是 Linux 采用了模块化的内核配置系统,从而保证了内核的扩展性。

本文首先分析了 Linux 内核中的配置系统结构,然后,解释了 Makefile 和配置文件的格式以及配置语句的含义,最后,通过一个简单的例子--TEST Driver,具体说明如何将自行开发的代码加入到 Linux 内核中。在下面的文章中,不可能解释所有的功能和命令,只对那些常用的进行解释,至于那些没有讨论到的,请读者参考后面的参考文献。

$@'

 @sed 's/TEXTADDR/$(TEXTADDR)/;s/DATAADDR/$(DATAADDR)/' $(LDSCRIPT) >$@

vmlinux-armv.lds.in文件的内容:

OUTPUT_ARCH(arm)

ENTRY(stext)

SECTIONS

{

    . = TEXTADDR;

    .init : {           /* Init code and data       */

        _stext = .;

        __init_begin = .;

            *(.text.init)

        __proc_info_begin = .;

            *(.proc.info)

        __proc_info_end = .;

        __arch_info_begin = .;

            *(.arch.info)

        __arch_info_end = .;

        __tagtable_begin = .;

            *(.taglist)

        __tagtable_end = .;

            *(.data.init)

        . = ALIGN(16);

        __setup_start = .;

            *(.setup.init)

        __setup_end = .;

        __initcall_start = .;

            *(.initcall.init)

        __initcall_end = .;

        . = ALIGN(4096);

        __init_end = .;

    }

   

其中TEXTADDR就是内核启动的虚拟地址,定义在kernel/arch/arm/Makefile中:

ifeq ($(CONFIG_CPU_32),y)

PROCESSOR    = armv

TEXTADDR     = 0xC0008000

LDSCRIPT     = arch/arm/vmlinux-armv.lds.in

endif

需要注意的是这里是虚拟地址而不是物理地址。

一般情况下都在生成vmlinux后,再对内核进行压缩成为zImage,压缩的目录是kernel/arch/arm/boot。

下载到flash中的是压缩后的zImage文件,zImage是由压缩后的vmlinux和解压缩程序组成,如下图所示:

            |------------------|\    |------------------|

            |                     | \   |                     |

            |                     |  \  | decompress code |

            |     vmlinux     |   \ |------------------|    zImage

            |                     |    \|                     |

            |                     |     |                     |

            |                     |     |                     |   

            |                     |     |                     |

            |                     |    /|------------------|

            |                     |   /

            |                     |  /

            |                     | /

            |------------------|/

zImage链接脚本也叫做vmlinux.lds,位于kernel/arch/arm/boot/compressed。

是由同一目录下的vmlinux.lds.in文件生成的,内容如下:

OUTPUT_ARCH(arm)

ENTRY(_start)

SECTIONS

 {

   . = LOAD_ADDR;

   _load_addr = .;

 

   . = TEXT_START;

   _text = .;

 

   .text : {

     _start = .;

    

其中LOAD_ADDR就是zImage中解压缩代码的ram偏移地址,TEXT_START是内核ram启动的偏移地址,这个地址是物理地址。

在kernel/arch/arm/boot/Makefile文件中定义了:

ZTEXTADDR   =0

ZRELADDR     = 0xa0008000

ZTEXTADDR就是解压缩代码的ram偏移地址,ZRELADDR是内核ram启动的偏移地址,这里看到指定ZTEXTADDR的地址为0,

明显是不正确的,因为我的平台上的ram起始地址是0xa0000000,在Makefile文件中看到了对该地址设置的几行注释:

# We now have a PIC decompressor implementation.  Decompressors running

# from RAM should not define ZTEXTADDR.  Decompressors running directly

# from ROM or Flash must define ZTEXTADDR (preferably via the config)

他的意识是如果是在ram中进行解压缩时,不用指定它在ram中的运行地址,如果是在flash中就必须指定他的地址。所以这里将ZTEXTADDR指定为0,也就是没有真正指定地址。

在kernel/arch/arm/boot/compressed/Makefile文件有一行脚本:

SEDFLAGS    = s/TEXT_START/$(ZTEXTADDR)/;s/LOAD_ADDR/$(ZRELADDR)/;s/BSS_START/$(ZBSSADDR)/

使得TEXT_START = ZTEXTADDR,LOAD_ADDR = ZRELADDR。

这样vmlinux.lds的生成过程如下:

vmlinux.lds:    vmlinux.lds.in Makefile $(TOPDIR)/arch/$(ARCH)/boot/Makefile $(TOPDIR)/.config

 @sed "$(SEDFLAGS)" < vmlinux.lds.in > $@

 

以上就是我对内核启动地址的分析,总结一下内核启动地址的设置:

1、设置kernel/arch/arm/Makefile文件中的

   TEXTADDR     = 0xC0008000

   内核启动的虚拟地址

2、设置kernel/arch/arm/boot/Makefile文件中的

   ZRELADDR     = 0xa0008000

   内核启动的物理地址

   如果需要从flash中启动还需要设置

   ZTEXTADDR地址 

  评论这张
 
阅读(1544)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017