balo.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:4k
- /*
- * balo.c: BAget LOader
- *
- * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
- */
- #include <linux/kernel.h>
- #include <asm/system.h>
- #include <asm/ptrace.h>
- #include <asm/addrspace.h>
- #include <asm/baget/baget.h>
- #include "balo.h" /* Includes some kernel symbol values */
- static char *banner = "nBaget Linux Loader v0.2n";
- static void mem_move (long *to, long *from, long size)
- {
- while (size > 0) {
- *to++ = *from++;
- size -= sizeof(long);
- }
- }
- static volatile int *mem_limit = (volatile int*)KSEG1;
- static volatile int *mem_limit_dbe = (volatile int*)KSEG1;
- static int can_write (volatile int* p) {
- return p < (int*)(KSEG1+BALO_OFFSET) ||
- p >= (int*)(KSEG1+BALO_OFFSET+BALO_SIZE);
- }
- static volatile enum balo_state_enum {
- BALO_INIT,
- MEM_INIT,
- MEM_PROBE,
- START_KERNEL
- } balo_state = BALO_INIT;
- static __inline__ void reset_and_jump(int start, int mem_upper)
- {
- unsigned long tmp;
- __asm__ __volatile__(
- ".settnoreordernt"
- ".settnoatnt"
- "mfc0t$1, $12nt"
- "nopnt"
- "nopnt"
- "nopnt"
- "orit$1, $1, 0xff00nt"
- "xorit$1, $1, 0xff00nt"
- "mtc0t$1, $12nt"
- "nopnt"
- "nopnt"
- "nopnt"
- "movet%0, %2nt"
- "jrt%1nt"
- "nopnt"
- ".settatnt"
- ".settreorder"
- : "=&r" (tmp)
- : "Ir" (start), "Ir" (mem_upper)
- : "memory");
- }
- static void start_kernel(void)
- {
- extern char _vmlinux_start, _vmlinux_end;
- extern char _ramdisk_start, _ramdisk_end;
- outs( "Relocating Linux... " );
- mem_move((long*)KSEG0, (long*)&_vmlinux_start,
- &_vmlinux_end-&_vmlinux_start);
- outs("done.n");
- if (&_ramdisk_start != &_ramdisk_end) {
- outs("Setting up RAMDISK... ");
- if (*(unsigned long*)RAMDISK_BASE != 0xBA) {
- outs("Bad RAMDISK_BASE signature in system image.n");
- balo_hungup();
- }
- *(unsigned long*)RAMDISK_BASE = (unsigned long)&_ramdisk_start;
- *(unsigned long*)RAMDISK_SIZE = &_ramdisk_end -&_ramdisk_start;
- outs("done.n");
- }
- {
- extern void flush_cache_low(int isize, int dsize);
- flush_cache_low(256*1024,256*1024);
- }
- balo_printf( "Kernel entry: %xnn", START);
- balo_state = START_KERNEL;
- reset_and_jump(START, (int)mem_limit-KSEG1+KSEG0);
- }
- static void mem_probe(void)
- {
- balo_state = MEM_PROBE;
- outs("RAM: <");
- while(mem_limit < mem_limit_dbe) {
- if (can_write(mem_limit) && *mem_limit != 0)
- break; /* cycle found */
- outc('.');
- if (can_write(mem_limit))
- *mem_limit = -1; /* mark */
- mem_limit += 0x40000;
- }
- outs(">n");
- start_kernel();
- }
- volatile unsigned int int_cause;
- volatile unsigned int epc;
- volatile unsigned int badvaddr;
- static void print_regs(void)
- {
- balo_printf("CAUSE=%x EPC=%x BADVADDR=%xn",
- int_cause, epc, badvaddr);
- }
- void int_handler(struct pt_regs *regs)
- {
- switch (balo_state) {
- case BALO_INIT:
- balo_printf("nBALO: trap in balo itself.n");
- print_regs();
- balo_hungup();
- break;
- case MEM_INIT:
- if ((int_cause & CAUSE_MASK) != CAUSE_DBE) {
- balo_printf("nBALO: unexpected trap during memory init.n");
- print_regs();
- balo_hungup();
- } else {
- mem_probe();
- }
- break;
- case MEM_PROBE:
- balo_printf("nBALO: unexpected trap during memory probe.n");
- print_regs();
- balo_hungup();
- break;
- case START_KERNEL:
- balo_printf("nBALO: unexpected kernel trap.n");
- print_regs();
- balo_hungup();
- break;
- }
- balo_printf("nBALO: unexpected return from handler.n");
- print_regs();
- balo_hungup();
- }
- static void mem_init(void)
- {
- balo_state = MEM_INIT;
- while(1) {
- *mem_limit_dbe;
- if (can_write(mem_limit_dbe))
- *mem_limit_dbe = 0;
- mem_limit_dbe += 0x40000; /* +1M */
- }
- /* no return: must go to int_handler */
- }
- void balo_entry(void)
- {
- extern void except_vec3_generic(void);
- cli();
- outs(banner);
- memcpy((void *)(KSEG0 + 0x80), &except_vec3_generic, 0x80);
- mem_init();
- }
- /* Needed for linking */
- int vsprintf(char *buf, const char *fmt, va_list arg)
- {
- outs("BALO: vsprintf called.n");
- balo_hungup();
- return 0;
- }