移植¶
选自邮件列表归档:http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2001-July/004064.html
初始定义¶
以下符号定义依赖于您了解 __virt_to_phys() 在您的机器上执行的地址转换。此宏将传入的虚拟地址转换为物理地址。通常,它很简单:
phys = virt - PAGE_OFFSET + PHYS_OFFSET
解压器符号¶
- ZTEXTADDR
解压器的起始地址。在这里讨论虚拟地址或物理地址毫无意义,因为在你调用解压器代码时 MMU 是关闭的。通常你会在这个地址调用内核来启动它。它不必位于 RAM 中,可以位于 flash 或其他只读或可读写的可寻址介质中。
- ZBSSADDR
解压器零初始化工作区的起始地址。这必须指向 RAM。解压器会为你将其初始化为零。同样,MMU 也是关闭的。
- ZRELADDR
这是解压后的内核将被写入并最终执行的地址。必须满足以下约束:
__virt_to_phys(TEXTADDR) == ZRELADDR
内核的初始部分经过精心编写,具备位置无关性。
- INITRD_PHYS
放置初始 RAM 盘的物理地址。仅在使用 bootpImage 相关内容时适用(该内容仅适用于旧的
struct param_struct)。- INITRD_VIRT
初始 RAM 盘的虚拟地址。必须满足以下约束:
__virt_to_phys(INITRD_VIRT) == INITRD_PHYS
- PARAMS_PHYS
struct param_struct或标签列表(tag list)的物理地址,用于向内核提供其执行环境的各种参数。
内核符号¶
- PHYS_OFFSET
第一块 RAM 的物理起始地址。
- PAGE_OFFSET
第一块 RAM 的虚拟起始地址。在内核引导阶段,虚拟地址 PAGE_OFFSET 将连同您提供的任何其他映射一起,被映射到物理地址 PHYS_OFFSET。该值应该与 TASK_SIZE 相同。
- TASK_SIZE
用户进程的最大大小(以字节为单位)。由于用户空间总是从零开始,因此这是用户进程可以访问的最大地址 + 1。用户空间栈从该地址向下增长。
TASK_SIZE 以下的任何虚拟地址都被视为用户进程区域,因此由内核按进程进行动态管理。我将其称为用户段。
TASK_SIZE 以上的所有内容对所有进程而言都是公共的。我将其称为内核段。
(换句话说,您不能将 IO 映射放在 TASK_SIZE 之下,从而也不能放在 PAGE_OFFSET 之下)。
- TEXTADDR
内核的虚拟起始地址,通常为 PAGE_OFFSET + 0x8000。这是内核镜像最终存放的位置。对于最新内核,它必须位于 128MB 区域内从起始处偏移 32768 字节的地方。先前的内核对此处施加了 256MB 的限制。
- DATAADDR
内核数据段的虚拟地址。使用解压器时不得定义此项。
- VMALLOC_START / VMALLOC_END
界定
vmalloc()区域的虚拟地址边界。该区域中绝不能有任何静态映射;vmalloc 会覆盖它们。这些地址也必须位于内核段中(见上文)。通常,vmalloc()区域从最后一个虚拟 RAM 地址(通过变量 high_memory 获得)上方 VMALLOC_OFFSET 字节处开始。- VMALLOC_OFFSET
通常合并到 VMALLOC_START 中的偏移量,用于在虚拟 RAM 和 vmalloc 区域之间留出一个空洞。我们这样做是为了能够捕获越界内存访问(例如,有代码写入了已映射内存映射的末尾之外)。通常设置为 8MB。
体系结构特定宏¶
- BOOT_MEM(pram,pio,vio)
pram 指定了 RAM 的物理起始地址。必须始终存在,且应与 PHYS_OFFSET 相同。
pio 是一个 8MB 区域的物理地址,该区域包含用于 arch/arm/kernel/debug-armv.S 中调试宏的 IO。
vio 是该 8MB 调试区域的虚拟地址。
预计该调试区域稍后会由体系结构特定的代码(通过 MAPIO 函数)重新初始化。
- BOOT_PARAMS
与 PARAMS_PHYS 相同,请参见 PARAMS_PHYS。
- FIXUP(func)
机器特定的修复,在内存子系统初始化之前运行。
- MAPIO(func)
用于映射 IO 区域的机器特定函数(包括上述调试区域)。
- INITIRQ(func)
用于初始化中断的机器特定函数。