没有合适的资源?快使用搜索试试~ 我知道了~
首页ARM-Linux内核启动的分析
这是一篇对armlinux内核启动的分析,主要是arch/arm/kernel/head-armv.S文件, head-armv.S文件是整个内核的入口,也就是说bootloader执行完毕后将跳转到head-armv.S的第一条指令,head-armv.S执行完后将跳转到start_kernel(),在head-armv.S的执行过程中也用到了其他一些文件,包括arch/arm/kernel/debug-armv.S、arch/arm/mm/proc-arm920.S等等 由于此分析基于MX1的内核启动过程,因此除了通用代码,只有定义在CONFIG_ARCH_MX1ADS下的代码和proc-arm920.S(arm920是MX1的CPU)的代码被分析
资源详情
资源评论
资源推荐

1.介绍..........................................................................................2
2.相关定义介绍..........................................................................3
2.1.TEXTADDR ......................................................3
2.2.stext....................................................................3
2.3.swapper_pg_dir..................................................4
2.4.(M)pgtbl.............................................................4
2.5.(M)krnladr..........................................................5
2.6..proc.info 段.......................................................5
2.7.__proc_info_begin/__proc_info_end.................6
2.8..arch.info 段 .......................................................7
2.9.__arch_info_begin/__arch_info_end.................8
3.代码分析..................................................................................9
3.1.KERNEL ENTRY..............................................9
3.2.__arm920_setup...............................................11
3.3.__ret .................................................................13
3.4.__mmap_switched ...........................................14
3.5.__lookup_processor_type ................................16
3.6.__lookup_architecture_type.............................16
3.7.__create_page_tables.......................................19

1.介绍
这是一篇对 armlinux 内核启动的分析,主要是 arch/arm/kernel/head-armv.S 文
件, head-armv.S 文件是整个内核的入口,也就是说 bootloader 执行完毕后将跳
转到 head-armv.S 的第一条指令,head-armv.S 执行完后将跳转到 start_kernel(),
在 head-armv.S 的执行过程中也用到了其他一些文件,包括
arch/arm/kernel/debug-armv.S、arch/arm/mm/proc-arm920.S 等等
由于此分析基于 MX1 的内核启动过程,因此除了通用代码,只有定义在
CONFIG_ARCH_MX1ADS 下的代码和 proc-arm920.S(arm920 是 MX1 的 CPU)
的代码被分析
在下面程序流程的说明中,MX1 板子启动过程中的寄存器值将会用绿色字
体表示出来,而对于专门针对 MX1 的代码则会用下划线字体
表示

2.相关定义介绍
2.1.TEXTADDR
TEXTADDR 是内核 Image 的映像地址,也是内核 Image 所处的虚拟地址,
它在系统内核空间起始地址——通常是 0xC0000000(这相对应于物理内存开始
的地方)+32K 的位置,也就是 0xC0008000 处 TEXTADDR 的赋值在
arch/arm/Makefile 文件中:(0xC0008000)
ifeq ($(CONFIG_CPU_32),y)
PROCESSOR = armv
TEXTADDR = 0xC0008000
LDSCRIPT = arch/arm/vmlinux-armv.lds.in
endif
在内核映像之前的 16K 空间用来存放内核的页目录表,这就是为什么
TEXTADDR 要在系统要放在 0xC0008000 的缘故——它必须留出足够的物理空
间来放页表
在 head-armv.S 中 TEXTADDR 将被检测:
#if (TEXTADDR & 0xffff) != 0x8000 //TEXTADDR 必须为 0xXXXX8000
#error TEXTADDR must start at 0xXXXX8000
#endif
2.2.stext
stext 是 TEXTADDR 相对应的物理地址,由于内核空间的起始地址
(0xC0000000)相对应的物理地址就是最低物理内存的地址,因此 stext 就是最
低物理内存+32K 处(虽然这并不是有内核指定,而是由 bootloader 指定),它的
赋值在连接脚本 vmlinux-armv.lds.in 中实现:(0x08008000)
ENTRY(stext)

SECTIONS
{
. = TEXTADDR; //此处的映像地址为 TEXTADDR
.init : { /* Init code and data */
_stext = .; //stext 为此处的物理地址
2.3.swapper_pg_dir
swapper_pg_dir 是页表的映像地址,由于启动页表在内核 Image 之前的 16K
处,因此它等于 0xC0004000,它的定义在 head-armv.S 文件中
.globl SYMBOL_NAME(swapper_pg_dir) //设置 swapper_pg_dir
.equ SYMBOL_NAME(swapper_pg_dir), TEXTADDR - 0x4000
在定义 init 进程的 mm_struct 结构的宏 INIT_MM 中,swapper_pg_dir 作为页表基
址被赋给 init_mm,INIT_MM 定义在 include/linux/sched.h 文件中:
#define INIT_MM(name) \
{ \
…
pgd: swapper_pg_dir, \
…
}
2.4.(M)pgtbl
pgtbl 是一个用于获得启动页表物理地址的宏,它将 stext 减去 16K 给 reg,
它也在 head-armv.S 中定义:
.macro pgtbl, reg, rambase
adr \reg, stext
sub \reg, \reg, #0x4000 //reg=stext-0x4000
.endm

2.5.(M)krnladr
这个宏用于由 pgtable 获得内核空间的起始物理地址的所在的段(MB),将
pgtable,也就是页表地址(和内核空间的起始物理地址在同一个段内)和
0x000FFFFF 相与,因为页表地址后 12 位为零,所以将其和 0x000FF000 相与
/*
* Since the page table is closely related to the kernel start address, we
* can convert the page table base address to the base address of the section
* containing both.
*/
.macro krnladr, rd, pgtable, rambase
bic \rd, \pgtable, #0x000ff000
.endm
2.6..proc.info 段
.proc.info 段中存放的是各种处理器的信息,每个处理器的信息用一个
proc_info_list 结构来表示,这个结构在 include/asm/procinfo.h 文件中声明:
struct proc_info_list {
unsigned int cpu_val; //处理器类型
unsigned int cpu_mask; //处理器类型掩码
unsigned long __cpu_mmu_flags; /* used by head-armv.S */
unsigned long __cpu_flush; /* used by head-armv.S */
const char *arch_name;
const char *elf_name;
unsigned int elf_hwcap;
struct proc_info_item *info;
剩余23页未读,继续阅读

















安全验证
文档复制为VIP权益,开通VIP直接复制

评论0