zoukankan      html  css  js  c++  java
  • mov pc, r4 @ call kernel

    mov pc, r4          @ call kernel   绝对跳转到r4:40008000处开始执行

    开始进入Image,Image由vmlinux生成,所以从vmlinux开始阅读理解。

    arch/unicore/kernel目录,据其链接脚本,从head.S开始:

    __lookup_processor_type:

    运用相对取址,取出proc_info_list,做出processor对比(因为一个镜像支持一种processor,该processor的信息从协处理器的c0:4d000863中取出)。这里首先要运用相对取值,因为我们编译的内核是按照虚拟地址进行编译链接的,其次是proc_info_list的存储:我们在程序中声明了.section ".proc.info.init",而后链接脚本中显示的定义的该输入section,并且以__proc_info_begin和__proc_info_end作为界限,因此头文件的proc_info_begin结构体根本就没有相应的变量,该section的内容在编译时就确定了。

    __lookup_machine_type:

    验证过程同__lookup_processor_type,因为每个processor所处的环境不同,因此每个板子会有一个相应的machine_type,这在boot阶段就传入了的arch_id:0x9fc,可以与内核镜像中设定的做对比,以此来验证该内核镜像是否可以运行在该开发板上。

    (查看:/arch/unicore/mach-sep0611/mach-tiger-test.c +226

                 /arch/unicore/include/asm/mach/arch.h +53)

    __vet_atags参数地址验证

    __create_page_tables:

    建立内核页表(40007000处,正好据内核起始4K大小,可以建立1K个一级变换条目),因为unicore32支持4M超页,所以建立内核的页表很简单,更具内核编译的起始地址,以及结束地址bss段末尾,为内核建立页表,同时也为DDR2的虚拟地址前4M建立一级超页表映射,当然实际上有点重复了,因为我们内核的链接起始地址是C0008000,而DDR2的欲建立的虚拟起始地址是C0000000。

    ldw r13, __switch_data      @ address to jump to after

                                           @ mmu has been enabled

    adr lr, __enable_mmu        @ return (PIC) address

    add pc, r10, #PROCINFO_INITFUNC (实际上运行.section “.proc.info.init”中的b __ucv2_setup)

    __ucv2_setup:

    cache无效,TLB无效,将系统即将被设置的cache与MMU写入r0,我们采用了中断向量起始0xFFFF0000,I、Dcache使能,Dcache使用write_back策略,地址对其检查使能,Busrt传输使能,MMU使能(注意这些还未写进协控制寄存器),最后执行指令

    mov pc,lr

    因此开始运行__enable_mmu:

    将页表基址写入p0.c2,相对跳转到__turn_mmu_on(注意没有改变lr寄存器值)

    __turn_mmu_on:

        将r0写入pc.c1     movc    p0.c1, r0, #0

    mov pc, r13    从此我们在虚拟地址下运行

    nop; nop; nop; nop; nop; nop; nop; nop(unicore32是八级流水,不过还是多了,当然谁会在意这个呢)

    __switch_data:

    开始建立BSS段,将processor_id、__machine_arch_type、__atags_pointer、cr_alignment存放于固定地址(当然对这几个参数还不是很明白,以后再看看),还有一个栈值init_thread_union + THREAD_START_SP,反汇编是0xc058dff8,位于data段中,这个栈值不理解为什么要如此设置。

    执行b start_kernel跳转到/init/main.c中开始执行第一个C程序。

  • 相关阅读:
    Markdown语法
    负载均衡、反向代理、CDN的概念
    IDEA远程调试
    跨域简介
    java命令:javac/java/javap
    尾递归实现斐波那契数列
    Java集合:框架
    volatile简介与原理
    乐观锁和悲观锁
    移动端布局的心得
  • 原文地址:https://www.cnblogs.com/openix/p/2490600.html
Copyright © 2011-2022 走看看