~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Bochs x86 Emulator
bochs/load32bitOShack.cc

Version: ~ [ 2.3.5 ] ~ [ 2.3 ] ~

** Warning: Cannot open xref database.

1 ///////////////////////////////////////////////////////////////////////// 2 // $Id: load32bitOShack.cc,v 1.22 2007/07/09 15:16:09 sshwarts Exp $ 3 ///////////////////////////////////////////////////////////////////////// 4 // 5 // Copyright (C) 2001 MandrakeSoft S.A. 6 // 7 // MandrakeSoft S.A. 8 // 43, rue d'Aboukir 9 // 75002 Paris - France 10 // http://www.linux-mandrake.com/ 11 // http://www.mandrakesoft.com/ 12 // 13 // This library is free software; you can redistribute it and/or 14 // modify it under the terms of the GNU Lesser General Public 15 // License as published by the Free Software Foundation; either 16 // version 2 of the License, or (at your option) any later version. 17 // 18 // This library is distributed in the hope that it will be useful, 19 // but WITHOUT ANY WARRANTY; without even the implied warranty of 20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 // Lesser General Public License for more details. 22 // 23 // You should have received a copy of the GNU Lesser General Public 24 // License along with this library; if not, write to the Free Software 25 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 26 27 28 #include "bochs.h" 29 #include "cpu/cpu.h" 30 #include "iodev/iodev.h" 31 #define LOG_THIS genlog-> 32 33 34 static void bx_load_linux_hack(void); 35 static void bx_load_null_kernel_hack(void); 36 static Bit32u bx_load_kernel_image(char *path, Bit32u paddr); 37 38 void bx_load32bitOSimagehack(void) 39 { 40 if (SIM->get_param_string(BXPN_LOAD32BITOS_IOLOG) && 41 (SIM->get_param_string(BXPN_LOAD32BITOS_IOLOG)->getptr()[0] != '\0')) 42 { 43 44 // Replay IO from log to initialize IO devices to 45 // a reasonable state needed for the OS. This is done 46 // in lieu of running the 16-bit BIOS to init things, 47 // since we want to test straight 32bit stuff for 48 // freemware. 49 50 FILE *fp = fopen(SIM->get_param_string(BXPN_LOAD32BITOS_IOLOG)->getptr(), "r"); 51 if (fp == NULL) { 52 BX_PANIC(("could not open IO init file.")); 53 } 54 55 while (1) { 56 unsigned len, op, port, val; 57 int ret; 58 ret = fscanf(fp, "%u %u %x %x\n", &len, &op, &port, &val); 59 if (ret != 4) { 60 BX_PANIC(("could not open IO init file.")); 61 } 62 if (op == 0) { 63 // read 64 bx_devices.inp(port, len); 65 } 66 else if (op == 1) { 67 // write 68 bx_devices.outp(port, val, len); 69 } 70 else { 71 BX_PANIC(("bad IO op in init filen")); 72 } 73 if (feof(fp)) break; 74 } 75 } //if iolog file to load 76 77 // Invoke proper hack depending on which OS image we're loading 78 switch (SIM->get_param_enum(BXPN_LOAD32BITOS_WHICH)->get()) { 79 case Load32bitOSLinux: 80 bx_load_linux_hack(); 81 break; 82 case Load32bitOSNullKernel: 83 bx_load_null_kernel_hack(); 84 break; 85 default: 86 BX_PANIC(("load32bitOSImage: OS not recognized")); 87 } 88 } 89 90 struct gdt_entry 91 { 92 Bit32u low; 93 Bit32u high; 94 }; 95 96 struct linux_setup_params 97 { 98 /* 0x000 */ Bit8u orig_x; 99 /* 0x001 */ Bit8u orig_y; 100 /* 0x002 */ Bit16u memory_size_std; 101 /* 0x004 */ Bit16u orig_video_page; 102 /* 0x006 */ Bit8u orig_video_mode; 103 /* 0x007 */ Bit8u orig_video_cols; 104 /* 0x008 */ Bit16u unused1; 105 /* 0x00a */ Bit16u orig_video_ega_bx; 106 /* 0x00c */ Bit16u unused2; 107 /* 0x00e */ Bit8u orig_video_lines; 108 /* 0x00f */ Bit8u orig_video_isVGA; 109 /* 0x010 */ Bit16u orig_video_points; 110 /* 0x012 */ Bit8u pad1[0x40 - 0x12]; 111 /* 0x040 */ Bit8u apm_info[0x80 - 0x40]; 112 /* 0x080 */ Bit8u hd0_info[16]; 113 /* 0x090 */ Bit8u hd1_info[16]; 114 /* 0x0a0 */ Bit8u pad2[0x1e0 - 0xa0]; 115 /* 0x1e0 */ Bit32u memory_size_ext; 116 /* 0x1e4 */ Bit8u pad3[0x1f1 - 0x1e4]; 117 /* 0x1f1 */ Bit8u setup_sects; 118 /* 0x1f2 */ Bit16u mount_root_rdonly; 119 /* 0x1f4 */ Bit16u sys_size; 120 /* 0x1f6 */ Bit16u swap_dev; 121 /* 0x1f8 */ Bit16u ramdisk_flags; 122 /* 0x1fa */ Bit16u vga_mode; 123 /* 0x1fc */ Bit16u orig_root_dev; 124 /* 0x1fe */ Bit16u bootsect_magic; 125 /* 0x200 */ Bit8u pad4[0x210 - 0x200]; 126 /* 0x210 */ Bit32u loader_type; 127 /* 0x214 */ Bit32u kernel_start; 128 /* 0x218 */ Bit32u initrd_start; 129 /* 0x21c */ Bit32u initrd_size; 130 /* 0x220 */ Bit8u pad5[0x400 - 0x220]; 131 /* 0x400 */ struct gdt_entry gdt[128]; 132 /* 0x800 */ Bit8u commandline[2048]; 133 }; 134 135 static void bx_load_linux_setup_params(Bit32u initrd_start, Bit32u initrd_size) 136 { 137 BX_MEM_C *mem = BX_MEM(0); 138 struct linux_setup_params *params = 139 (struct linux_setup_params *) &mem->vector[0x00090000]; 140 141 memset( params, '\0', sizeof(*params) ); 142 143 /* Video settings (standard VGA) */ 144 params->orig_x = 0; 145 params->orig_y = 0; 146 params->orig_video_page = 0; 147 params->orig_video_mode = 3; 148 params->orig_video_cols = 80; 149 params->orig_video_lines = 25; 150 params->orig_video_points = 16; 151 params->orig_video_isVGA = 1; 152 params->orig_video_ega_bx = 3; 153 154 /* Memory size (total mem - 1MB, in KB) */ 155 params->memory_size_ext = (mem->megabytes - 1) * 1024; 156 157 /* Boot parameters */ 158 params->loader_type = 1; 159 params->bootsect_magic = 0xaa55; 160 params->mount_root_rdonly = 0; 161 params->orig_root_dev = 0x0100; 162 params->initrd_start = initrd_start; 163 params->initrd_size = initrd_size; 164 165 /* Initial GDT */ 166 params->gdt[2].high = 0x00cf9a00; 167 params->gdt[2].low = 0x0000ffff; 168 params->gdt[3].high = 0x00cf9200; 169 params->gdt[3].low = 0x0000ffff; 170 } 171 172 void bx_load_linux_hack(void) 173 { 174 Bit32u initrd_start = 0, initrd_size = 0; 175 176 // The RESET function will have been called first. 177 // Set CPU and memory features which are assumed at this point. 178 179 // Load Linux kernel image 180 bx_load_kernel_image(SIM->get_param_string(BXPN_LOAD32BITOS_PATH)->getptr(), 0x100000); 181 182 // Load initial ramdisk image if requested 183 char * tmpPtr = SIM->get_param_string(BXPN_LOAD32BITOS_INITRD)->getptr(); 184 if ( tmpPtr && tmpPtr[0] ) /* The initial value is "" and not NULL */ 185 { 186 initrd_start = 0x00800000; /* FIXME: load at top of memory */ 187 initrd_size = bx_load_kernel_image( tmpPtr, initrd_start ); 188 } 189 190 // Setup Linux startup parameters buffer 191 bx_load_linux_setup_params( initrd_start, initrd_size ); 192 193 // Enable A20 line 194 BX_SET_ENABLE_A20( 1 ); 195 196 // Setup PICs the way Linux likes it 197 BX_OUTP( 0x20, 0x11, 1 ); 198 BX_OUTP( 0xA0, 0x11, 1 ); 199 BX_OUTP( 0x21, 0x20, 1 ); 200 BX_OUTP( 0xA1, 0x28, 1 ); 201 BX_OUTP( 0x21, 0x04, 1 ); 202 BX_OUTP( 0xA1, 0x02, 1 ); 203 BX_OUTP( 0x21, 0x01, 1 ); 204 BX_OUTP( 0xA1, 0x01, 1 ); 205 BX_OUTP( 0x21, 0xFF, 1 ); 206 BX_OUTP( 0xA1, 0xFB, 1 ); 207 208 // Disable interrupts and NMIs 209 BX_CPU(0)->clear_IF (); 210 BX_OUTP( 0x70, 0x80, 1 ); 211 212 // Enter protected mode 213 // Fixed by george (kyriazis at nvidia.com) 214 // BX_CPU(0)->cr0.pe = 1; 215 // BX_CPU(0)->cr0.val32 |= 0x01; 216 217 BX_CPU(0)->SetCR0(BX_CPU(0)->cr0.val32 | 0x01); 218 219 // load esi with real_mode 220 BX_CPU(0)->gen_reg[BX_32BIT_REG_ESI].dword.erx = 0x90000; 221 222 // Set up initial GDT 223 BX_CPU(0)->gdtr.limit = 0x400; 224 BX_CPU(0)->gdtr.base = 0x00090400; 225 226 // Jump to protected mode entry point 227 BX_CPU(0)->jump_protected( NULL, 0x10, 0x00100000 ); 228 } 229 230 void bx_load_null_kernel_hack(void) 231 { 232 // The RESET function will have been called first. 233 // Set CPU and memory features which are assumed at this point. 234 235 bx_load_kernel_image(SIM->get_param_string(BXPN_LOAD32BITOS_PATH)->getptr(), 0x100000); 236 237 // EIP deltas 238 BX_CPU(0)->prev_eip = 239 BX_CPU(0)->dword.eip = 0x00100000; 240 241 // CS deltas 242 BX_CPU(0)->sregs[BX_SEG_REG_CS].cache.u.segment.base = 0x00000000; 243 BX_CPU(0)->sregs[BX_SEG_REG_CS].cache.u.segment.limit = 0xFFFFF; 244 BX_CPU(0)->sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled = 0xFFFFFFFF; 245 BX_CPU(0)->sregs[BX_SEG_REG_CS].cache.u.segment.g = 1; // page gran 246 BX_CPU(0)->sregs[BX_SEG_REG_CS].cache.u.segment.d_b = 1; // 32bit 247 248 #if BX_SUPPORT_ICACHE 249 BX_CPU(0)->updateFetchModeMask(); 250 #endif 251 252 // DS deltas 253 BX_CPU(0)->sregs[BX_SEG_REG_DS].cache.u.segment.base = 0x00000000; 254 BX_CPU(0)->sregs[BX_SEG_REG_DS].cache.u.segment.limit = 0xFFFFF; 255 BX_CPU(0)->sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled = 0xFFFFFFFF; 256 BX_CPU(0)->sregs[BX_SEG_REG_DS].cache.u.segment.g = 1; // page gran 257 BX_CPU(0)->sregs[BX_SEG_REG_DS].cache.u.segment.d_b = 1; // 32bit 258 259 // CR0 deltas 260 BX_CPU(0)->cr0.set_PE(1); // protected mode 261 } 262 263 Bit32u 264 bx_load_kernel_image(char *path, Bit32u paddr) 265 { 266 struct stat stat_buf; 267 int fd, ret; 268 unsigned long size, offset; 269 Bit32u page_size; 270 271 // read in ROM BIOS image file 272 fd = open(path, O_RDONLY 273 #ifdef O_BINARY 274 | O_BINARY 275 #endif 276 ); 277 if (fd < 0) { 278 BX_INFO(( "load_kernel_image: couldn't open image file '%s'.", path )); 279 BX_EXIT(1); 280 } 281 ret = fstat(fd, &stat_buf); 282 if (ret) { 283 BX_INFO(( "load_kernel_image: couldn't stat image file '%s'.", path )); 284 BX_EXIT(1); 285 } 286 287 size = (unsigned long)stat_buf.st_size; 288 page_size = ((Bit32u)size + 0xfff) & ~0xfff; 289 290 BX_MEM_C *mem = BX_MEM(0); 291 if ( (paddr + size) > mem->len ) { 292 BX_INFO(( "load_kernel_image: address range > physical memsize!" )); 293 BX_EXIT(1); 294 } 295 296 offset = 0; 297 while (size > 0) { 298 ret = read(fd, (bx_ptr_t) &mem->vector[paddr + offset], size); 299 if (ret <= 0) { 300 BX_INFO(( "load_kernel_image: read failed on image" )); 301 BX_EXIT(1); 302 } 303 size -= ret; 304 offset += ret; 305 } 306 close(fd); 307 BX_INFO(("load_kernel_image: '%s', size=%u read into memory at %08x", 308 path, (unsigned) stat_buf.st_size, (unsigned) paddr)); 309 310 return page_size; 311 } 312

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.