1、set big/little endian mode 2、clear the BEV bit 3、set the TLB bit 4、goto cpu_probe and return 5、set up stack for kernel 6、clear bss 7、goto prom_init and return 8、goto loadmmu and return 9、disable coprocessor 10、goto kernel start 11、goto 10
前6步是正确的设置寄存器 1、设置大端/小端字节模式 2、清除引导异常向量位,确定以后使用正确的异常向量 3、TLB的设置,不同mpu的tlb进入数是可能有差异的 4、cpu类型探测(简单实现的mips代码如下) LEAF(cpu_probe) la t3,mips_cputype li t2,MYCPU /* include/asm-mips/bootinfo.h */ b probe_done sw t2,(t3) END(cpu_probe) 注:bootinfo.h中有cputye(MYCPU)和机器组(MY_MACH_GROUP)的入口 ,mips_cputype变量需要cpu_probe函数来更新。使用此值来终止 异常处理和MMU程序。 5、初始化内核堆栈 6、清除内核映像的bss 7、将控制权交到init prom,刷新TLB和缓冲 8、载入mmu程序,loadmmu中内置缓冲处理函数 9、处理器0完成后禁止其他协处理器 10、跳转启动start_kernel()
int __init prom_init(int argc, char **argv, char **envp) { unsigned long mem_limit, mem_detected, mem_use; unsigned long mem_start, mem_end, bootmap_size; int i;
// clear ERL and EXL in case the bootloader got us here through an // exception. this is mostly to make kernel debugger happy write_32bit_cp0_register(CP0_STATUS, 0);
// set upper limit to vr41xx maximum physical RAM (64MB) mem_limit = 64 << 20;
// the bootloader passes us argc/argv[], but the kernel wants one big string // put it in arcs_cmdline, which later gets copied to command_line // (see arch/mips/kernel/setup.c) // we skip the first argument which is the program file name strcpy(arcs_cmdline, ""); for (i = 1; i < argc; i++) { // is it the "mem=" option? if ( memcmp(argv[i], "mem=", 4) == 0 ) { // limit to amount of memory specified in megabytes mem_limit = simple_strtoul(argv[i] + 4, 0, 10) << 20;
printk("Command line argument limits memory to %dMB.\n", (int)mem_limit >> 20);
// don’t pass this arg on to the kernel continue; }
irq_setup = myplatform_irq_setup; /* * mips_io_port_base is the beginning *of the address space to which x86 * style I/O ports are mapped. */
mips_io_port_base = 0xa0000000;
/* * platform_io_mem_base is the beginning of I/O bus memory space as * seen from the physical address bus. This may or may not be ident- * ical to mips_io_port_base, e.g. the former could point to the
beginning of PCI *memory space while the latter might indicate PCI I/O * space. The two values are used in different sets of macros. This * must be set to a correct value by the platform setup code. */
platform_io_mem_base=0x10000000;
/* * platform_mem_iobus_base is the beginning of main memory as seen * from the I/O bus, and must be set by the platform setup code. */
platform_mem_iobus_base=0x0;
#ifdef CONFIG_REMOTE_DEBUG
/* * Do the minimum necessary to set up debugging */