文章目录
-
- 简述
-
- 实例
-
-
- smdk 2410
- qemu virt arm32 板
-
- 硬件相关
-
- uImage 相关
-
- zImage 相关
-
-
- ZTEXTADDR
- ZBSSADDR
- INITRD_VIRT
- Image 相关
-
- 虚拟地址
-
- PAGE_OFFSET
- TEXT_OFFSET
- TEXTADDR
- swapper_pg_dir
- VMALLOC
- DATAADDR
- 物理地址
-
- ZRELADDR
- INITRD_PHYS
- PARAMS_PHYS
- 线性映射中 物理地址和虚拟地址的转换
- 其他
-
简述
boot 地址侧
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
地址C : TODO
地址D : ZRELADDR
虚拟内存侧
uboot 在 加载 内核最后一步, MMU 肯定是关的
zImage 运行过程中 , MMU 全程关闭
Image 运行过程中 , MMU 会在 start_kernel 前 打开
开了 MMU 之后
物理地址 : 虚拟地址
ZRELADDR : TEXTADDR
实例
smdk 2410
Image启动的虚拟地址 TEXTADDR = 0xC0008000
Image启动的物理地址 ZRELADDR = 0x30008000
qemu virt arm32 板
地址
$ ls -l arch/arm/boot/Image
-rwxrwxr-x 1 suweishuai suweishuai 26430588 May 27 21:19 arch/arm/boot/Image
$ ls -l arch/arm/boot/zImage
-rwxrwxr-x 1 suweishuai suweishuai 10019328 May 27 21:20 arch/arm/boot/zImage
$ ls arch/arm/boot/Image -l
-rwxrwxr-x 1 suweishuai suweishuai 26430588 May 27 21:19 arch/arm/boot/Image
$ file arch/arm/boot/Image
arch/arm/boot/Image: data
地址A : 没有研究 qemu virt arm32 的 u-boot
地址B : 0x40010000
地址C : 0x41B3C460
地址D : 0x40208000
PHYS_OFFSET : 0x40000000
PAGE_OFFSET : 0xc0000000
TEXT_OFFSET : 0x00208000
TEXTADDR : 0xc0208000
swapper_pg_dir : 0xc0204000
ZBSSADDR := ALIGN(8)
c1b9ee68 B _end
c0208000 T _text
页表
页表描述
arm32 两级映射,对于section 映射,只有1级别
下面所有的表项都是PGD表项(即PMD表项)
每个表项4字节,寻址1M空间
0xc0205000: 0x00000000 0x00000000 0x00000000 0x40311c0e
0xc0207000: 0x40011c0e 0x40111c0e 0x40211c0e 0x40311c0e
0xc0207010: 0x40411c0e 0x40511c0e 0x40611c0e 0x40711c0e
0xc0207020: 0x40811c0e 0x40911c0e 0x40a11c0e 0x40b11c0e
0xc0207030: 0x40c11c0e 0x40d11c0e 0x40e11c0e 0x40f11c0e
0xc0207040: 0x41011c0e 0x41111c0e 0x41211c0e 0x41311c0e
0xc0207050: 0x41411c0e 0x41511c0e 0x41611c0e 0x41711c0e
0xc0207060: 0x41811c0e 0x41911c0e 0x41a11c0e 0x41b11c0e
0xc0207fe0: 0x48011c0e 0x48111c0e 0x00000000 0x00000000
arm32 40000000 - 40204000是干啥的?为啥virt板要预留这么多
arm32为什么要从 40000000 创建映射, arm64 为啥不用?
arm32 只有一个pgd(里面有mmu_on,Image,dtb) , 而 arm64 为什么创建两个 pgd(分别是mmu_on,Image)
硬件相关
PHYS_OFFSET
PHYS_OFFSET
Physical start address of the first bank of RAM.
RAM第一个bank的物理起始地址,即物理内存的起始地址。
ram的起始地址 : 例如 qemu virt arm 的 0x40000000
uImage 相关
Load Address
https:
Load Address 是 zImage 的住宿地址
make LOADADDR=0x60004000 uImage
ifneq ($(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:
Entry Point
https:
Entry Point 是 zImage 的控制地址,(从这个地址接收控制权)
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:
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_PHYS
Image 相关
虚拟地址
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
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:
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.