charles的edit在哪里:powerpc 启动过程

来源:百度文库 编辑:偶看新闻 时间:2024/05/03 17:25:26
head32.S
启动第一阶段
在arch/powerpc/kernel/下
head32.S
关键函数
1、early_init()早期初始化,清BBS 识别CPU
2、mmu_off 关闭MMU 汇编代码
3、reloc_offset()
4、relocate_kernel()->copy_and_flush 16M
5、turn_on_mmu打开MMU
turn_on_mmu:
    mfmsr    r0
    ori    r0,r0,MSR_DR|MSR_IR
    mtspr    SPRN_SRR1,r0
    lis    r0,start_here@h
    ori    r0,r0,start_here@l  //调用start_here函数
    mtspr    SPRN_SRR0,r0
    SYNC
    RFI  //跳转到start_here
。。
/*
 * This is where the main kernel code starts.
 */
start_here:
    /* ptr to current */
    lis    r2,init_task@h
    ori    r2,r2,init_task@l
    /* Set up for using our exception vectors */
    /* ptr to phys current thread */
    tophys(r4,r2)
    addi    r4,r4,THREAD    /* init task's THREAD */
    CLR_TOP32(r4)
    mtspr    SPRN_SPRG_THREAD,r4
    li    r3,0
    mtspr    SPRN_SPRG_RTAS,r3    /* 0 => not in RTAS */

    /* stack */
    lis    r1,init_thread_union@ha
    addi    r1,r1,init_thread_union@l
    li    r0,0
    stwu    r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
/*
 * Do early platform-specific initialization,
 * and set up the MMU.
 */
    mr    r3,r31
    mr    r4,r30
    bl    machine_init   //->probe_machine()->
    bl    __save_cpu_setup
    bl    MMU_init //初始化mmu

/*
 * Go back to running unmapped so we can load up new values
 * for SDR1 (hash table pointer) and the segment registers
 * and change to using our exception vectors.
 */
    lis    r4,2f@h
    ori    r4,r4,2f@l
    tophys(r4,r4)
    li    r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
    FIX_SRR1(r3,r5)
    mtspr    SPRN_SRR0,r4
    mtspr    SPRN_SRR1,r3
    SYNC
    RFI
/* Load up the kernel context */
2:    bl    load_up_mmu

#ifdef CONFIG_BDI_SWITCH
    /* Add helper information for the Abatron bdiGDB debugger.
     * We do this here because we know the mmu is disabled, and
     * will be enabled for real in just a few instructions.
     */
    lis    r5, abatron_pteptrs@h
    ori    r5, r5, abatron_pteptrs@l
    stw    r5, 0xf0(r0)    /* This much match your Abatron config */
    lis    r6, swapper_pg_dir@h
    ori    r6, r6, swapper_pg_dir@l
    tophys(r5, r5)
    stw    r6, 0(r5)
#endif /* CONFIG_BDI_SWITCH */

/* Now turn on the MMU for real! */
    li    r4,MSR_KERNEL
    FIX_SRR1(r4,r5)
    lis    r3,start_kernel@h
    ori    r3,r3,start_kernel@l
    mtspr    SPRN_SRR0,r3
    mtspr    SPRN_SRR1,r4
    SYNC
    RFI  //调到start——kernel 第一阶段的硬件设置完成
**********************
void probe_machine(void)
{
    extern struct machdep_calls __machine_desc_start;
    extern struct machdep_calls __machine_desc_end;

    /*
     * Iterate all ppc_md structures until we find the proper
     * one for the current machine type
     */
    DBG("Probing machine type ...\n");

    for (machine_id = &__machine_desc_start;
         machine_id < &__machine_desc_end;
         machine_id++) {
        DBG("  %s ...", machine_id->name);
        memcpy(&ppc_md, machine_id, sizeof(struct machdep_calls));
        if (ppc_md.probe()) {
            DBG(" match !\n");
            break;
        }
        DBG("\n");
    }
    /* What can we do if we didn't find ? */
    if (machine_id >= &__machine_desc_end) {
        DBG("No suitable machine found !\n");
        for (;;);
    }

    printk(KERN_INFO "Using %s machine description\n", ppc_md.name);
}


/*
__machine_desc_start, __machine_desc_end在vmlinux.lds.S文件中定义,系统编译完成后初始化这两个变量
*/
*********************
__secondary_start
start  到start_kernel

第二阶段
start_kernel 到kernel_thread函数创建init进程。

early init函数

bl early_init
early_init函数主要功能是判断当前处理器系统使用的内核类型,并作出相应的初始操作。函数在/arch/powerpc/kernel/setup_32.c文件中定义

Linux Powerpc 从early_init 返回 之后调用mathine_init 定义同上。主要作用是1、分析OF Tree结构,获取当前内存使用情况,2、确定当前的处理器的PPC—md结构