- 简述
- boot 地址侧
- 虚拟内存侧
- 实例
- smdk 2410
- qemu virt arm32 板
- 硬件相关
- PHYS_OFFSET
- uImage 相关
- Load Address
- Entry Point
- zImage 相关
- ZTEXTADDR
- ZBSSADDR
- INITRD_VIRT
- Image 相关
- 虚拟地址
- PAGE_OFFSET
- TEXT_OFFSET
- TEXTADDR
- swapper_pg_dir
- VMALLOC
- DATAADDR
- 物理地址
- ZRELADDR
- INITRD_PHYS
- PARAMS_PHYS
- 线性映射中 物理地址和虚拟地址的转换
- 其他
- TASK_SIZE
uboot 通过 tftp 下载 uImage 到 ddr 到 地址 A uboot 根据 uImage 的要求 搬运 zImage 到 地址 B zImage boot zImage 根据 是否会覆盖Image 搬运 自身 到 地址 C zImage 跳转到 地址C处的 zImage zImage 解压 出 Image 到某地址 到 地址 D Image boot 过程中涉及到 4个boot 地址(ABCD) 地址A : tftp 0x60003000 uImage; bootm 0x60003000 中的 0x60003000 地址B : ZTEXTADDR // 值于 Load Address 相同 // Entry Point 一般也和 Load Address 一致 地址C : TODO 地址D : ZRELADDR虚拟内存侧
uboot 在 加载 内核最后一步, MMU 肯定是关的 // 不太关心 uboot 过程中会不会开MMU zImage 运行过程中 , MMU 全程关闭 Image 运行过程中 , MMU 会在 start_kernel 前 打开 开了 MMU 之后 物理地址 : 虚拟地址 ZRELADDR : TEXTADDR实例 smdk 2410
Image启动的虚拟地址 TEXTADDR = 0xC0008000 Image启动的物理地址 ZRELADDR = 0x30008000qemu virt arm32 板
地址A : 没有研究 qemu virt arm32 的 u-boot 地址B : 0x40010000 // 即 ZTEXTADDR 地址C : 0x41B3C460 地址D : 0x40208000 // 即 ZRELADDR
PHYS_OFFSET : 0x40000000
PAGE_OFFSET : 0xc0000000 TEXT_OFFSET : 0x00208000 TEXTADDR : 0xc0208000 swapper_pg_dir : 0xc0204000
ZBSSADDR := ALIGN(8)
硬件相关 PHYS_OFFSET
PHYS_OFFSET Physical start address of the first bank of RAM. RAM第一个bank的物理起始地址,即物理内存的起始地址。 ram的起始地址 : 例如 qemu virt arm 的 0x40000000uImage 相关 Load Address
https://blog.csdn.net/u011011827/article/details/82995261
Load Address 是 zImage 的住宿地址 // 和 bootm的参数没有关系
make LOADADDR=0x60004000 uImage // 指定 LOADADDR
//arch/arm/boot/Makefile // 关注 : UIMAGE_LOADADDR
ifneq ($(LOADADDR),) // 可通过 make LOADADDR=0x60004000 uImage 指定 LOADADDR
UIMAGE_LOADADDR=$(LOADADDR)
else
ifeq ($(CONFIG_ZBOOT_ROM),y)
UIMAGE_LOADADDR=$(CONFIG_ZBOOT_ROM_TEXT)
else
UIMAGE_LOADADDR=$(ZRELADDR)
endif
endif
————————————————
版权声明:本文为CSDN博主「__pop_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u011011827/article/details/82995261
Entry Point
https://blog.csdn.net/u011011827/article/details/82995261
Entry Point 是 zImage 的控制地址,(从这个地址接收控制权)
// scripts/Makefile.lib // 关注 : UIMAGE_ENTRYADDR
UIMAGE_LOADADDR ?= arch_must_set_this
UIMAGE_ENTRYADDR ?= $(UIMAGE_LOADADDR)
...
cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(UIMAGE_ARCH) -O linux
-C $(UIMAGE_COMPRESSION) $(UIMAGE_OPTS-y)
-T $(UIMAGE_TYPE)
-a $(UIMAGE_LOADADDR) -e $(UIMAGE_ENTRYADDR)
-n $(UIMAGE_NAME) -d $(UIMAGE_IN) $(UIMAGE_OUT)
————————————————
版权声明:本文为CSDN博主「__pop_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u011011827/article/details/82995261
zImage 相关
zImage 的代码是位置无关码,随意扔到哪里都可以ZTEXTADDR
ZTEXTADDR Start address of decompressor. There'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. 解压代码(zImage)运行的开始地址。 没有虚拟地址的概念,因为此时MMU处于关闭状态。 这个地址不一定时RAM的地址,可以是支持读写寻址的flash等存储中介。ZBSSADDR
ZBSSADDR Start address of zero-initialised work area for the decompressor. This must be pointing at RAM. The decompressor will zero initialise this for you. Again, the MMU will be off.INITRD_VIRT
INITRD_VIRT Virtual address of the initial RAM disk. The following constraint must be valid: __virt_to_phys(INITRD_VIRT) == INITRD_PHYSImage 相关 虚拟地址 PAGE_OFFSET
PAGE_OFFSET Virtual start address of the first bank of RAM. During the kernel boot phase, virtual address PAGE_OFFSET will be mapped to physical address PHYS_OFFSET, along with any other mappings you supply. This should be the same value as TASK_SIZE. RAM第一个bank的虚拟起始地址,即内核虚拟地址空间的起始地址。 #define PAGE_OFFSET UL(CONFIG_PAGE_OFFSET)TEXT_OFFSET
TEXT_OFFSET 内核偏移地址,即内核起始位置相对于内存起始位置的偏移, 对于相对于物理内存还是相对于虚拟内存都是一样的结果。 在arch/arm/makefile中设定。 TEXT_OFFSET := $(textofs-y) 140 # Text offset. This list is sorted numerically by address in order to 141 # provide a means to avoid/resolve conflicts in multi-arch kernels. 142 # Note: the 32kB below this value is reserved for use by the kernel 143 # during boot, and this offset is critical to the functioning of 144 # kexec-tools. 145 textofs-y := 0x00008000 可取范围 0x008000 0x208000 0x408000 ...TEXTADDR
// 目前好像没有这个宏了?
TEXTADDR
内核启动的虚拟地址,与ZRELADDR相对应。一般内核启动的虚拟地址为RAM的第一个bank地址加上0x8000。
TEXTADDR = PAGE_OFFSET + TEXT_OFFSET
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.
TEXTADDR
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.
相应地,内核启动的虚拟地址被设定为TEXTADDR,满足如下条件:
TEXTADDR = PAGE_OFFSET + TEXT_OFFSET
内核启动的物理地址和虚拟地址满足入下条件:
ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET)= virt_to_phys(TEXTADDR)
swapper_pg_dir
swapper_pg_dir 的 值 为 "TEXTADDR - 0x4000" boot时 用来存储 临时页表 运行时 用来存储 内核页表VMALLOC
VMALLOC_START arch/arm/include/asm/pgtable.h #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) VMALLOC_END Virtual addresses bounding the vmalloc() area. There must not be any static mappings in this area; vmalloc will overwrite them. The addresses must also be in the kernel segment (see above). Normally, the vmalloc() area starts VMALLOC_OFFSET bytes above the last virtual RAM address (found using variable high_memory). #define VMALLOC_END 0xff800000UL 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. #define VMALLOC_OFFSET (8*1024*1024)DATAADDR
DATAADDR // 没有这个宏 Virtual address for the kernel data segment. Must not be defined when using the decompressor.物理地址 ZRELADDR
// 就是 Load Address 中的那个 ZRELADDR , 如果实在没办法了, 就将 ZRELADDR 的值 赋值给 UIMAGE_LOADADDR 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. 值有要求,值 = PHYS_OFFSET + TEXT_OFFSET 20 # Note: the following conditions must always be true: 21 # ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET) 22 # PARAMS_PHYS must be within 4MB of ZRELADDR 23 # INITRD_PHYS must be in RAM 24 ZRELADDR := $(zreladdr-y) 25 PARAMS_PHYS := $(params_phys-y) 26 INITRD_PHYS := $(initrd_phys-y)INITRD_PHYS
INITRD_PHYS Physical address to place the initial RAM disk. Only relevant if you are using the bootpImage stuff (which only works on the old struct param_struct).PARAMS_PHYS
PARAMS_PHYS Physical address of the struct param_struct or tag list, giving the kernel various parameters about its execution environment.线性映射中 物理地址和虚拟地址的转换
Taken from list archive at http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2001-July/004064.html Initial definitions ------------------- The following symbol definitions rely on you knowing the translation that __virt_to_phys() does for your machine. This macro converts the passed virtual address to a physical address. Normally, it is simply: phys = virt - PAGE_OFFSET + PHYS_OFFSET其他 TASK_SIZE
TASK_SIZE The maximum size of a user process in bytes. Since user space always starts at zero, this is the maximum address that a user process can access+1. The user space stack grows down from this address. Any virtual address below TASK_SIZE is deemed to be user process area, and therefore managed dynamically on a process by process basis by the kernel. I'll call this the user segment. Anything above TASK_SIZE is common to all processes. I'll call this the kernel segment. (In other words, you can't put IO mappings below TASK_SIZE, and hence PAGE_OFFSET).
Architecture Specific Macros ---------------------------- BOOT_MEM(pram,pio,vio) `pram' specifies the physical start address of RAM. Must always be present, and should be the same as PHYS_OFFSET. `pio' is the physical address of an 8MB region containing IO for use with the debugging macros in arch/arm/kernel/debug-armv.S. `vio' is the virtual address of the 8MB debugging region. It is expected that the debugging region will be re-initialised by the architecture specific code later in the code (via the MAPIO function). BOOT_PARAMS Same as, and see PARAMS_PHYS. FIXUP(func) Machine specific fixups, run before memory subsystems have been initialised. MAPIO(func) Machine specific function to map IO areas (including the debug region above). INITIRQ(func) Machine specific function to initialise interrupts.



