L4微内核分析(mips64架构)

pistachio-0.4/kernel/src/glue/v4-mips64/init.cc文件中的startup_system()函数分析:

extern "C" void SECTION(".init") startup_system(word_t a0, word_t a1, word_t a2, word_t a3) 
{
    init_cpu();    初始化CPU,配置
    init_cpu_cache();
    cache_t::init_cpu();  该函数实现在pistachio-0.4/kernel/include/platform/erpcn01/cache.h
      ①、将Config Register(CP0 register 16,Select 0)寄存器的值存入临时temp变量
      ②、清空该寄存器的K0(3bit)字段,该字段用来控制Kseg0 Cache attributes
      ③、设置K0字段为3,表示Cache able,noncoherent,write-back,write alloc特性
      ④、将temp值重新保存到Config Register(CP0 register 16,Select 0)寄存器
      ⑤、初始化dcache和icache,两个cache开始地址KSEG0(0xffffffff80000000),大小均为(16*1024)。
        该过程从KSEG0开始一直到结束,将TagLo和TagHi寄存器的值写入指定索引cache块的tag区,具体参考
        https://blog.csdn.net/xiaoseha/article/details/50981817 init_platform(a0); 该函数实现在pistachio-0.4/kernel/src/platform/u4600/plat.cc中
     ①、plat_cpu_freq[0] = 100000000ul; 向cpu频率数组写入相应频率
     ②、plat_bus_freq[0] = 33300000ul;  向bus频率数组写入bus频率 init_console();
     kdb_consoles[kdb_current_console].init ();该类实现在kernel/kdb/platform/u4600/serial.cc中
                包括串口初始化(init_serial)、串口输出(putc_serial),串口输入(getc_serial) init_hello();  该函数在pistachio-0.4/kernel/src/api/v4/kernelinterface.cc中实现
     printf ("\n" TXT_BRIGHT TXT_FG_YELLOW "%s" TXT_NORMAL "\n",kernel_version_string); init_arch();   该函数是重点函数,在pistachio-0.4/kernel/src/glue/v4-mips64/init.cc中实现
     ①、init_tlb();  初始化tlb,在pistachio-0.4/kernel/src/glue/v4-mips64/tlb.cc中实现
       a)、清PageMask Register(CP0 Register 5,select 0)寄存器
       b)、将Index Register(CP0 Register 0,select 0)寄存器的值存储到Wired Register(CP0 Register 6,select 0)
       c)、分48次将递增索引存储到Index Register和EntryHi Register中,然后将Index Register的内容填充到
         EntryLo0和EntryLo1寄存器中。本过程使用for循环执行48次。
       d)、将Index Register寄存器中的值存储到EntryHi Register寄存器中
     ②、get_interrupt_ctrl()->init_arch();  初始化IRQ中断(通用初始化函数)
       void SECTION (".init") intctrl_t::init_arch(void) 在kernel/src/glue/v4-mips64/intctrl.cc实现
         a)、mips_cpu::cli(); 该函数在kernel/include/arch/mips64/mips_cpu.h实现
           将Status寄存器的值存储到Random寄存器,Random的值与1进行或操作,再将Random的值与1进行异或操作,最后
           把Random的值存储到Status寄存器中。(该操作设定Status寄存器的IE位为1,使能全局中断)
           然后将Index寄存器整体左移3位。
         b)、复制MIPS的异常向量表到KSEG0 0xFFFFFFFF80000000。异常向量表位于kernel/src/glue/v4-mips64/traps.S
          memcpy((void *)(KSEG0), &__mips64_tlb_refill, 0x80);
          memcpy((void *)(KSEG0 + 0x080), &__mips64_xtlb_refill, 0x80);
            memcpy((void *)(KSEG0 + 0x100), &__mips64_cache_error, 0x80);
            memcpy((void *)(KSEG0 + 0x180), &__mips64_interrupt, 0x80);
          memcpy((void *)(KSEG0 + 0x200), &__mips64_extra_vector, 0x80);
         c)、cache_t::flush_cache_all(); 该函数在kernel/include/platform/u4600/cache.h中实现
          blast_dcache16(); blast_icache16();上述两个函数在kernel/include/platform/u4600/cache.h实现
         d)、将MIPS64架构的32个异常复制到异常处理数组,指向同一个处理函数
          for (i=0; i<32; i++)
              exception_handlers[i] = (word_t)&_mips64_exception;
         e)、将MIPS64架构的8个中断处理函数复制到中断处理数组中,指向同一个中断处理函数
          for (i=0; i<8; i++)
              interrupt_handlers[i] = (word_t)spurious_interrupt;
         f)、setup_exception_vectors(); 设置异常向量表,在kernel/src/glue/v4-mips64/intctrl.cc中实现
           此处未加详细说明,会在后期文档进行分析。
    ③、get_interrupt_ctrl()->init_cpu();配置中断(本CPU专属中断)kernel/src/glue/v4-mips64/intctrl.cc实现
      a)、mips_cpu::clear_cp0_status(ST_IM);该函数实现在kernel/include/arch/mips64/mips_cpu.h
          #define ST_IM  (0xff<<8)
          res = read_32bit_cp0_register(status); 在kernel/include/arch/mips64/mipsregs.h实现
          res &= ~clear;
          write_32bit_cp0_register(status, res);  在kernel/include/arch/mips64/mipsregs.h实现
      b)、get_idle_tcb()->arch.int_mask = 0;      int_mask位于idle tcb中,每次CPU中断标识位  
      c)、mips_cpu::clear_cp0_status(ST_BEV);
          #define ST_BEV      (1<<22) 
    ④、get_asid_cache()->init();  初始化所有的ASID cache为无效,在kernel/include/asid.h中实现 
    ⑤、get_asid_cache()->set_valid(0, CONFIG_MAX_NUM_ASIDS-1);  设置ASID cache为有效 

    dump_info();
/* initialize the scheduler */ get_current_scheduler()->init(true); get_idle_tcb ()->notify (finalize_cpu_init, 0); /* get the thing going - we should never return */ get_current_scheduler()->start(); printf("\nShould never get here!\nKernel Halted\n"); /* make sure we don't fall off the edge */ spin_forever(1); }

 

 

猜你喜欢

转载自www.cnblogs.com/xinyin/p/12405109.html