phys = virt - PAGE_OFFSET PHYS_OFFSET 解压缩器的地址地址。由于当你调用解压缩器代码时,通常关闭MMU,因此这里并不讨论虚拟地址和物理地址的问题。通常你在这个地址处调用内核,开始引导内核。它不需要在RAM中,只需要位于FLASH或其他只读或读/写的可寻址的存储设备中。
l ZBSSADDR
解压缩器的初始化为0的工作区的起始地址。必须位于RAM中,解压缩器会替你把它初始化为0,此外,需要关闭MMU。
l ZRELADDR
解压缩内核将被写入的地址和最终的执行地址。必须满足:
__virt_to_phys(TEXTADDR) == ZRELADDR
内核的开始部分被编码为与位置无关的代码。
l INITRD_PHYS
放置初始RAM盘的物理地址。仅当你使用bootpImage时相关(这是一种非常老的param_struct结构)
l INITRD_ⅥRT
初始RAM盘的虚拟地址。必须满足:
__virt_to_phys(INITRD_ⅥRT) == INITRD_PHYS
l PARAMS_PHYS
param_struct 结构体或tag lis的物理地址,用于给定内核执行环境下的不同参数。 RAM第一个BANK的物理地址地址。
l PAGE_OFFSET
RAM第一个BANK的虚拟地址地址。在内核引导阶段,虚拟地址PAGE_OFFSE将被映射为物理地址PHYS_OFFSET,它应该与TASK_SIZE具有相同的值。
l TASK_SIZE
一个用户进程的最大值,单位为byte。用户空间的堆栈从这个地址处向下增长。
任何一个低于TASK_SIZE的虚拟地址对用户进程来说都是不可见的,因此,内核通过进程偏移对每个进行进行动态的管理。我把这叫做用户段。任何高于TASK_SIZE的对所有进程都是相同的,称之为内核段。(换句话说,你不能把IO映射放在低于TASK_SIZE和PAGE_OFFSET的位置处。)
l TEXTADDR
内核的虚拟起始地址,通常为PAGE_OFFSET 0x8000。内核映射必须在此结束。
l DATAADDR
内核数据段的虚拟地址,不能在使用解压缩器的情况下定义。
l VMALLOC_START
l VMALLOC_END
用于限制vmalloc()区域的虚拟地址。此地址必须位于内核段。通常,vmalloc()区域在最后的虚拟RAM地址以上开始VMALLOC_OFFSET字节。
l VMALLOC_OFFSET
Offset normally incorporated into VMALLOC_START to provide a hole between virtual RAM and the vmalloc area. We do this to allow out of bounds memory accesses (eg,something writing off the end of the mapped memory map) to be caught. Normally set to 8MB. pram——指定了RAM起始的物理地址,必须始终存在,并应等于PHYS_OFFSET。
pio——是供arch/arm/kernel/debug-armv.S中的调试宏使用的,包含IO的8 MB区域的物理地址。
vio——是8MB调试区域的虚拟地址。
这个调试区域将被位于代码中(通过MAPIO函数)的随后的构架相关代码再次进行初始化。
l BOOT_PARAMS
参见 PARAMS_PHYS.
l FⅨUP(func)
机器相关的修正,在存储子系统被初始化前运行。
l MAPIO(func)
机器相关的函数,用于IO区域的映射(包括上面的调试区)。
l INITIRQ(func)
用于初始化中断的机器相关的函数 。
1. 内核启动地址ZTEXTADDR
解压代码运行的开始地址。没有物理地址和虚拟地址之分,因为此时MMU处于关闭状态。这个地址不一定时RAM的地址,可以是支持读写寻址的flash等存储中介。
Start address of decompressor. here's no point in talking about virtual or physical addresses here, since the MMU will be off at the time when you call the decompressor code. You normally call the kernel at this address to start it booting. This doesn't have to be located in RAM, it can be in flash or other read-only or read-write addressable medium.
在arch/arm/boot/compressed/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)
# FIXME: Previous assignment to ztextaddr-y is lost here. See SHARK
ifeq ($(CONFIG_ZBOOT_ROM),y)
ZTEXTADDR := $(CONFIG_ZBOOT_ROM_TEXT)
ZBSSADDR:= $(CONFIG_ZBOOT_ROM_BSS)
else
ZTEXTADDR := 0
ZBSSADDR:= ALIGN(8)
endif
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.
一般定义在项目目录下,比如:
arch/arm/mach-at91/Makefile.boot: zreladdr-y += 0x70008000
arch/arm/mach-at91/Makefile.boot: zreladdr-y += 0x20008000
arch/arm/mach-cns3xxx/Makefile.boot: zreladdr-y += 0x00008000
arch/arm/mach-davinci/Makefile.boot: zreladdr-y += 0xc0008000
arch/arm/mach-davinci/Makefile.boot: zreladdr-y += 0x80008000
arch/arm/mach-dove/Makefile.boot: zreladdr-y += 0x00008000
arch/arm/mach-ebsa110/Makefile.boot: zreladdr-y += 0x00008000
arch/arm/mach-exynos/Makefile.boot: zreladdr-y += 0x40008000
arch/arm/mach-footbridge/Makefile.boot: zreladdr-y += 0x00008000
arch/arm/mach-gemini/Makefile.boot: zreladdr-y += 0x00008000
arch/arm/mach-gemini/Makefile.boot: zreladdr-y += 0x10008000
arch/arm/mach-integrator/Makefile.boot: zreladdr-y += 0x00008000
arch/arm/mach-iop13xx/Makefile.boot: zreladdr-y += 0x00008000
在arch/arm/boot/Makefile中被赋值:
ZRELADDR := $(zreladdr-y)
PARAMS_PHYS := $(params_phys-y)
INITRD_PHYS := $(initrd_phys-y)
... ...
ifneq ($(LOADADDR),)
UIMAGE_LOADADDR=$(LOADADDR)
else
ifeq ($(CONFIG_ZBOOT_ROM),y)
UIMAGE_LOADADDR=$(CONFIG_ZBOOT_ROM_TEXT)
其实这个MMU是CPU的一个功能单元。。。 说白了就是电路。linux每个进程在内核空间中会有一个页表,切到进程时间片后这个页表会装载到MMU(跟寄存器差不多), MMU硬件会自动关联物理寻址和虚拟寻址。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)