balo.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:4k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * balo.c: BAget LOader
  3.  *
  4.  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
  5.  */
  6. #include <linux/kernel.h>
  7. #include <asm/system.h>
  8. #include <asm/ptrace.h>
  9. #include <asm/addrspace.h>
  10. #include <asm/baget/baget.h>
  11. #include "balo.h"  /* Includes some kernel symbol values */
  12. static char *banner = "nBaget Linux Loader v0.2n";
  13. static void mem_move (long *to, long *from, long size)
  14. {
  15. while (size > 0) { 
  16. *to++ = *from++;
  17. size -= sizeof(long);
  18. }
  19. }
  20. static volatile int *mem_limit     = (volatile int*)KSEG1;
  21. static volatile int *mem_limit_dbe = (volatile int*)KSEG1;
  22. static int can_write (volatile int* p) {
  23.         return p <  (int*)(KSEG1+BALO_OFFSET) ||
  24.                p >= (int*)(KSEG1+BALO_OFFSET+BALO_SIZE);
  25. }
  26. static volatile enum balo_state_enum {
  27. BALO_INIT,
  28. MEM_INIT,
  29. MEM_PROBE,
  30. START_KERNEL
  31. } balo_state = BALO_INIT;
  32. static __inline__ void reset_and_jump(int start, int mem_upper)
  33. {
  34. unsigned long tmp;
  35. __asm__ __volatile__(
  36.                 ".settnoreordernt"
  37.                 ".settnoatnt"
  38.                 "mfc0t$1, $12nt"
  39.                 "nopnt"
  40.                 "nopnt"
  41.                 "nopnt"
  42.                 "orit$1, $1, 0xff00nt"
  43.                 "xorit$1, $1, 0xff00nt"
  44.                 "mtc0t$1, $12nt"
  45.                 "nopnt"
  46.                 "nopnt"
  47.                 "nopnt"
  48. "movet%0, %2nt"
  49. "jrt%1nt"
  50. "nopnt"
  51.                 ".settatnt"
  52.                 ".settreorder"           
  53.                 : "=&r" (tmp)
  54.                 : "Ir" (start), "Ir" (mem_upper)
  55.                 : "memory");
  56. }
  57. static void start_kernel(void)
  58. {
  59. extern char _vmlinux_start, _vmlinux_end;
  60. extern char _ramdisk_start, _ramdisk_end;
  61.         outs( "Relocating Linux... " );
  62. mem_move((long*)KSEG0, (long*)&_vmlinux_start, 
  63.                  &_vmlinux_end-&_vmlinux_start);
  64. outs("done.n");
  65. if (&_ramdisk_start != &_ramdisk_end) {
  66. outs("Setting up RAMDISK... ");
  67. if (*(unsigned long*)RAMDISK_BASE != 0xBA) {
  68. outs("Bad RAMDISK_BASE signature in system image.n");
  69.                         balo_hungup();
  70. }
  71. *(unsigned long*)RAMDISK_BASE = (unsigned long)&_ramdisk_start;
  72. *(unsigned long*)RAMDISK_SIZE = &_ramdisk_end -&_ramdisk_start;
  73. outs("done.n");
  74. }
  75. extern void flush_cache_low(int isize, int dsize);
  76. flush_cache_low(256*1024,256*1024);
  77. }
  78.         balo_printf( "Kernel entry: %xnn", START);
  79. balo_state = START_KERNEL;
  80. reset_and_jump(START, (int)mem_limit-KSEG1+KSEG0);
  81. }
  82. static void mem_probe(void)
  83. {
  84. balo_state = MEM_PROBE;
  85. outs("RAM: <");
  86. while(mem_limit < mem_limit_dbe) {
  87.                 if (can_write(mem_limit) && *mem_limit != 0) 
  88.                         break; /* cycle found */
  89. outc('.');
  90. if (can_write(mem_limit)) 
  91.                         *mem_limit = -1; /* mark */
  92.                 mem_limit += 0x40000;
  93. }
  94. outs(">n");
  95. start_kernel();
  96. }
  97. volatile unsigned int int_cause;
  98. volatile unsigned int epc;
  99. volatile unsigned int badvaddr;
  100. static void print_regs(void)
  101. {
  102.         balo_printf("CAUSE=%x EPC=%x BADVADDR=%xn",
  103.                     int_cause, epc, badvaddr);
  104. }
  105. void int_handler(struct pt_regs *regs)
  106.         switch (balo_state) {
  107. case BALO_INIT:
  108.                 balo_printf("nBALO: trap in balo itself.n");
  109. print_regs();
  110.                 balo_hungup();
  111. break;
  112. case MEM_INIT:
  113.                 if ((int_cause & CAUSE_MASK) != CAUSE_DBE) {
  114.                         balo_printf("nBALO: unexpected trap during memory init.n");
  115. print_regs();
  116.                         balo_hungup();
  117. } else {
  118. mem_probe();
  119. }
  120. break;
  121. case MEM_PROBE:
  122.                 balo_printf("nBALO: unexpected trap during memory probe.n");
  123. print_regs();
  124.                 balo_hungup();
  125. break;
  126. case START_KERNEL:
  127.                 balo_printf("nBALO: unexpected kernel trap.n");
  128. print_regs();
  129.                 balo_hungup();
  130. break;
  131. }
  132.         balo_printf("nBALO: unexpected return from handler.n");
  133. print_regs();
  134.         balo_hungup();
  135. }
  136. static void mem_init(void)
  137. {
  138. balo_state = MEM_INIT;
  139. while(1) {
  140. *mem_limit_dbe;
  141. if (can_write(mem_limit_dbe)) 
  142. *mem_limit_dbe = 0;
  143. mem_limit_dbe += 0x40000; /* +1M */
  144. }
  145.         /*  no return: must go to int_handler */
  146. }
  147. void balo_entry(void)
  148. {
  149.         extern void except_vec3_generic(void);
  150. cli(); 
  151. outs(banner);
  152.         memcpy((void *)(KSEG0 + 0x80), &except_vec3_generic, 0x80);
  153. mem_init();
  154. }
  155. /* Needed for linking */
  156. int vsprintf(char *buf, const char *fmt, va_list arg)
  157. {
  158. outs("BALO: vsprintf called.n");
  159. balo_hungup();
  160. return 0;
  161. }