boot.c (4730B)
1 /* $Id: //depot/blt/boot/boot.c#3 $ 2 ** 3 ** Copyright 1998 Brian J. Swetland 4 ** All rights reserved. 5 ** 6 ** Redistribution and use in source and binary forms, with or without 7 ** modification, are permitted provided that the following conditions 8 ** are met: 9 ** 1. Redistributions of source code must retain the above copyright 10 ** notice, this list of conditions, and the following disclaimer. 11 ** 2. Redistributions in binary form must reproduce the above copyright 12 ** notice, this list of conditions, and the following disclaimer in the 13 ** documentation and/or other materials provided with the distribution. 14 ** 3. The name of the author may not be used to endorse or promote products 15 ** derived from this software without specific prior written permission. 16 ** 17 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /* Stage Two Bootloader -- init paged memory, map the kernel, and 30 * relocate to k_start() 31 */ 32 #define noDIAG 33 34 #include "types.h" 35 #include "boot.h" 36 #include <multiboot.h> 37 38 #ifdef DIAG 39 #include "../include/blt/conio.h" 40 #endif 41 42 void (*k_start)(void); 43 44 struct _kinfo 45 { 46 uint32 memsize; 47 uint32 entry_ebp; 48 boot_dir *bd; 49 unsigned char *param; 50 } *kinfo = (struct _kinfo *) 0x00102000; 51 52 static unsigned int multiboot[] __attribute__ ((__section__ (".text"))) = 53 { 54 0x1badb002, 55 0x00010002, 56 (unsigned int) 0 - 0x1badb002 - 0x00010002, 57 (unsigned int) multiboot, 58 0x100000, 59 0x14a000, 60 0x14a000, 61 0x101074 62 }; 63 64 static void enable_paging (void) 65 { 66 __asm__ ("movl $0x80000001, %eax ; mov %eax, %cr0"); 67 } 68 69 void bootstrap(boot_dir *bd, uint32 memsize, uint32 entry_ebp, char *p) 70 { 71 uint32 *flat; 72 uint32 _cr3; 73 int i; 74 75 kinfo->memsize = memsize; 76 kinfo->entry_ebp = entry_ebp; 77 kinfo->bd = bd; 78 kinfo->param = p; 79 80 #ifdef DIAG 81 con_init(); 82 cprintf("memsize = %x, bdir @ %x, ebp = %x\n",memsize,(int)bd,entry_ebp); 83 cprintf("name[0] = %s\n",bd->bd_entry[0].be_name); 84 cprintf("name[1] = %s\n",bd->bd_entry[1].be_name); 85 cprintf("name[2] = %s\n",bd->bd_entry[2].be_name); 86 #endif 87 88 flat = (void*) ((4096*(memsize/4096)) - 4096*3); 89 90 for(i=0;i<1024;i++){ 91 flat[i] = 0; 92 flat[1024+i] = 4096*i | 3; 93 flat[2048+i] = i > bd->bd_entry[2].be_size ? 0 : /* XXX! EEK! */ 94 ( (bd->bd_entry[2].be_offset*4096+0x100000) + 4096*i) | 3; 95 96 #ifdef DIAG 97 if(flat[2048+i]){ 98 cprintf("%x -> %x\n", 99 bd->bd_entry[2].be_offset*4096+0x100000 + 4096*i, 100 0x8000000+4096*i); 101 } 102 #endif 103 } 104 105 k_start = (void (*)(void)) 0x80000000 + (bd->bd_entry[2].be_code_ventr); 106 107 /* point the pdir at ptab1 and ptab2 */ 108 flat[0] = (uint32) &flat[1024] | 3; 109 flat[512] = (uint32) &flat[2048] | 3; 110 111 /* map the pdir, ptab1, ptab2 starting at 0x803FD000 */ 112 flat[2048+1023] = ((uint32) flat + 2*4096) | 3; 113 flat[2048+1022] = ((uint32) flat + 1*4096) | 3; 114 flat[2048+1021] = ((uint32) flat) | 3; 115 116 _cr3 = (uint32) flat; 117 __asm__ ("mov %0, %%cr3"::"r" (_cr3)); 118 enable_paging (); 119 120 #ifdef DIAG 121 flat = 0x803fd000; 122 123 for(i=0;i<3000000;i++); 124 for(i=0;i<3000000;i++); 125 if(flat[0] & 0xffffff00 != 0x007fe000) cprintf("danger will robinson! (a)\n"); 126 if(flat[512] & 0xffffff00 != 0x007ff000) cprintf("danger will robinson! (b)\n"); 127 cprintf("a = %x b = %x\n",flat[0],flat[512]); 128 for(i=0;i<3000000;i++); 129 cprintf("go! go! go!\n\n"); 130 for(i=0;i<3000000;i++); 131 132 133 /* for(i=0;i<80*4;i++){ 134 cprintf("."); 135 *((char *) 0x100000+i) = 'X'; 136 } 137 asm("hlt"); */ 138 #endif 139 140 k_start(); 141 } 142 143 void grub_bootstrap (multiboot_info *minfo) 144 { 145 const static unsigned int temp_gdt[] = { 0x00000000, 0x00000000, 146 0x0000ffff, 0x00cf9a00, 0x0000ffff, 0x00cf9200 }; 147 unsigned int i[2]; 148 149 i[0] = 24 << 16; 150 i[1] = (unsigned int) temp_gdt; 151 asm ("lgdt (%0)" : : "p" (((char *) i) + 2)); 152 adjust_seg_regs (); 153 bootstrap ((boot_dir *) 0x100000, (minfo->mem_lower + minfo->mem_upper + 154 384) * 1024, 0, minfo->cmdline); 155 } 156