有了2和3的基础,我们来看一下setup_arch中的内存初始化函数:paging_init()
void __init paging_init(
struct meminfo *mi, //内存的描述信息
struct machine_desc *mdesc) //机器信息,见“平台信息”
{
void *zero_page;
build_mem_type_table(); //根据MEM的策略补充页表的属性
prepare_page_table(mi); //清除段映射(16K一级页表,从地址0开始的)
bootmem_init(mi); //实现在arch\mm\init.c中,初始化bootmem分配信息
//实际上是初始化引导阶段所使用的内存,当内核启动完成,将使用SLUB来管理内存,届时管理方法将和boot阶段会不一样。
devicemaps_init(mdesc); //映射中断向量表(一、二级),注册模块时钟
top_pmd = pmd_off_k(0xffff0000); //获取中断向量的一级页表
//在低端内存中申请一页内存并清0,注意返回的是虚拟地址
zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
memzero(zero_page, PAGE_SIZE);
//获取该虚拟地址对应的页描述符,注意empty_zero_page是全局变量
empty_zero_page = virt_to_page(zero_page);
flush_dcache_page(empty_zero_page); //刷新D-CAHCE内容进RAM中
}
其中bootmem_init()函数见内存分析中,对bootmem.c文件的分析。其他的函数见我后一篇对arch\mmu.c文件的分析。
“平台信息”是我另外一篇文档,因为还未整理完,所以不便放出,先将其中相关部分的说明摘出:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//include\asm-arm\proinfo.h
//处理器(CPU)信息
struct proc_info_list {
unsigned int cpu_val; //ID号
unsigned int cpu_mask; //ID号中MASK的位
unsigned long __cpu_mm_mmu_flags; /* used by head.S */
unsigned long __cpu_io_mmu_flags; /* used by head.S */
unsigned long __cpu_flush; /* used by head.S */
const char *arch_name;
const char *elf_name;
unsigned int elf_hwcap;
const char *cpu_name;
struct processor *proc;
struct cpu_tlb_fns *tlb;
struct cpu_user_fns *user;
struct cpu_cache_fns *cache;
};
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//处理器信息:arch\arm\mm\proc-arm920.s
.section ".proc.info.init", #alloc, #execinstr //声明放入该段中
.type __arm920_proc_info, #object
__arm920_proc_info:
.long 0x41009200 //cpu value
.long 0xff00fff0 //cpu mask
.long PMD_TYPE_SECT | \ //段描述
PMD_SECT_BUFFERABLE | \ //B
PMD_SECT_CACHEABLE | \ //C
PMD_BIT4 | \ //固定为1
PMD_SECT_AP_WRITE | \ //权限读/写
PMD_SECT_AP_READ // __cpu_mm_mmu_flags(规格书P560)
.long PMD_TYPE_SECT | \
PMD_BIT4 | \
PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ // __cpu_io_mmu_flags
b __arm920_setup // __cpu_flush
.long cpu_arch_name // *arch_name
.long cpu_elf_name // *elf_name
.long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB // elf_hwcap
.long cpu_arm920_name // *cpu_name
.long arm920_processor_functions // *proc
.long v4wbi_tlb_fns // *tlb
.long v4wb_user_fns // *user
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH //未定义
.long arm920_cache_fns
#else
.long v4wt_cache_fns // *cache
#endif
.size __arm920_proc_info, . - __arm920_proc_info
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
include\asm-arm\cpu-multi32.h
struct processor {
void (*_data_abort)(unsigned long pc); // get data abort address/flags
void (*_proc_init)(void); // Set up any processor specifics
void (*_proc_fin)(void); // Disable any processor specifics
void (*reset)(unsigned long addr) __attribute__((noreturn)); // Special stuff for a reset
int (*_do_idle)(void); // Idle the processor
void (*dcache_clean_area)(void *addr, int size); // Processor architecture specific
void (*switch_mm)(unsigned long pgd_phys, struct mm_struct *mm);// Set the page table
void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext);// Set a possibly extended PTE
} processor;
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//机器信息
//include\asm-arm\mach\arch.h
struct machine_desc {
unsigned int nr; /* architecture number */
unsigned int phys_io; /* start of physical io */
unsigned int io_pg_offst; /* byte offset for io page tabe entry */
const char *name; /* architecture name */
unsigned long boot_params; /* tagged list */
unsigned int video_start; /* start of video RAM */
unsigned int video_end; /* end of video RAM */
unsigned int reserve_lp0 :1; /* never has lp0 */
unsigned int reserve_lp1 :1; /* never has lp1 */
unsigned int reserve_lp2 :1; /* never has lp2 */
unsigned int soft_reboot :1; /* soft reboot */
void (*fixup)(struct machine_desc *,
struct tag *, char **,
struct meminfo *);
void (*map_io)(void); /* IO mapping function */
void (*init_irq)(void);
struct sys_timer *timer; /* system tick timer */
void (*init_machine)(void);
};
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//arch\arm\mach-s3c2440\mach-utu2440.c
//machine_desc struct
MACHINE_START(UTU2440, "UTU2440")
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = utu2440_map_io, //used in cpu.c
.init_irq = utu2440_init_irq, //used in cpu.c
.init_machine = utu2440_init, //used in cpu.c
.timer = &s3c24xx_timer,
MACHINE_END
#define MACHINE_START(_type, _name) \
static const struct machine_desc __mach_desc_UTU2440 \
__used __attribute__((__section__(".arch.info.init"))) = { \
.nr = MACH_TYPE_UTU2440, \
.name = UTU2440,
#define MACHINE_END \
};