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);
}
原文:https://www.cnblogs.com/xinyin/p/12405109.html