Commit 77fef8c148e4bec1d1089b3729bd32efdbd3a6c0

Authored by bellard
1 parent 59817ccb

experimental code copy support - added new Linux kernel loader


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@620 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 2 changed files with 122 additions and 232 deletions
@@ -78,7 +78,6 @@ @@ -78,7 +78,6 @@
78 78
79 //#define DEBUG_SERIAL 79 //#define DEBUG_SERIAL
80 80
81 -#define PHYS_RAM_BASE 0xac000000  
82 #if !defined(CONFIG_SOFTMMU) 81 #if !defined(CONFIG_SOFTMMU)
83 #define PHYS_RAM_MAX_SIZE (256 * 1024 * 1024) 82 #define PHYS_RAM_MAX_SIZE (256 * 1024 * 1024)
84 #else 83 #else
@@ -97,126 +96,12 @@ @@ -97,126 +96,12 @@
97 #define KERNEL_STACK_ADDR 0x00400000 96 #define KERNEL_STACK_ADDR 0x00400000
98 #endif 97 #endif
99 #endif 98 #endif
100 -#define INITRD_LOAD_ADDR 0x00400000  
101 -#define KERNEL_PARAMS_ADDR 0x00090000 99 +#define INITRD_LOAD_ADDR 0x00400000
  100 +#define KERNEL_PARAMS_ADDR 0x00090000
  101 +#define KERNEL_CMDLINE_ADDR 0x00099000
102 102
103 #define GUI_REFRESH_INTERVAL 30 103 #define GUI_REFRESH_INTERVAL 30
104 104
105 -/* from plex86 (BSD license) */  
106 -struct __attribute__ ((packed)) linux_params {  
107 - // For 0x00..0x3f, see 'struct screen_info' in linux/include/linux/tty.h.  
108 - // I just padded out the VESA parts, rather than define them.  
109 -  
110 - /* 0x000 */ uint8_t orig_x;  
111 - /* 0x001 */ uint8_t orig_y;  
112 - /* 0x002 */ uint16_t ext_mem_k;  
113 - /* 0x004 */ uint16_t orig_video_page;  
114 - /* 0x006 */ uint8_t orig_video_mode;  
115 - /* 0x007 */ uint8_t orig_video_cols;  
116 - /* 0x008 */ uint16_t unused1;  
117 - /* 0x00a */ uint16_t orig_video_ega_bx;  
118 - /* 0x00c */ uint16_t unused2;  
119 - /* 0x00e */ uint8_t orig_video_lines;  
120 - /* 0x00f */ uint8_t orig_video_isVGA;  
121 - /* 0x010 */ uint16_t orig_video_points;  
122 - /* 0x012 */ uint8_t pad0[0x20 - 0x12]; // VESA info.  
123 - /* 0x020 */ uint16_t cl_magic; // Commandline magic number (0xA33F)  
124 - /* 0x022 */ uint16_t cl_offset; // Commandline offset. Address of commandline  
125 - // is calculated as 0x90000 + cl_offset, bu  
126 - // only if cl_magic == 0xA33F.  
127 - /* 0x024 */ uint8_t pad1[0x40 - 0x24]; // VESA info.  
128 -  
129 - /* 0x040 */ uint8_t apm_bios_info[20]; // struct apm_bios_info  
130 - /* 0x054 */ uint8_t pad2[0x80 - 0x54];  
131 -  
132 - // Following 2 from 'struct drive_info_struct' in drivers/block/cciss.h.  
133 - // Might be truncated?  
134 - /* 0x080 */ uint8_t hd0_info[16]; // hd0-disk-parameter from intvector 0x41  
135 - /* 0x090 */ uint8_t hd1_info[16]; // hd1-disk-parameter from intvector 0x46  
136 -  
137 - // System description table truncated to 16 bytes  
138 - // From 'struct sys_desc_table_struct' in linux/arch/i386/kernel/setup.c.  
139 - /* 0x0a0 */ uint16_t sys_description_len;  
140 - /* 0x0a2 */ uint8_t sys_description_table[14];  
141 - // [0] machine id  
142 - // [1] machine submodel id  
143 - // [2] BIOS revision  
144 - // [3] bit1: MCA bus  
145 -  
146 - /* 0x0b0 */ uint8_t pad3[0x1e0 - 0xb0];  
147 - /* 0x1e0 */ uint32_t alt_mem_k;  
148 - /* 0x1e4 */ uint8_t pad4[4];  
149 - /* 0x1e8 */ uint8_t e820map_entries;  
150 - /* 0x1e9 */ uint8_t eddbuf_entries; // EDD_NR  
151 - /* 0x1ea */ uint8_t pad5[0x1f1 - 0x1ea];  
152 - /* 0x1f1 */ uint8_t setup_sects; // size of setup.S, number of sectors  
153 - /* 0x1f2 */ uint16_t mount_root_rdonly; // MOUNT_ROOT_RDONLY (if !=0)  
154 - /* 0x1f4 */ uint16_t sys_size; // size of compressed kernel-part in the  
155 - // (b)zImage-file (in 16 byte units, rounded up)  
156 - /* 0x1f6 */ uint16_t swap_dev; // (unused AFAIK)  
157 - /* 0x1f8 */ uint16_t ramdisk_flags;  
158 - /* 0x1fa */ uint16_t vga_mode; // (old one)  
159 - /* 0x1fc */ uint16_t orig_root_dev; // (high=Major, low=minor)  
160 - /* 0x1fe */ uint8_t pad6[1];  
161 - /* 0x1ff */ uint8_t aux_device_info;  
162 - /* 0x200 */ uint16_t jump_setup; // Jump to start of setup code,  
163 - // aka "reserved" field.  
164 - /* 0x202 */ uint8_t setup_signature[4]; // Signature for SETUP-header, ="HdrS"  
165 - /* 0x206 */ uint16_t header_format_version; // Version number of header format;  
166 - /* 0x208 */ uint8_t setup_S_temp0[8]; // Used by setup.S for communication with  
167 - // boot loaders, look there.  
168 - /* 0x210 */ uint8_t loader_type;  
169 - // 0 for old one.  
170 - // else 0xTV:  
171 - // T=0: LILO  
172 - // T=1: Loadlin  
173 - // T=2: bootsect-loader  
174 - // T=3: SYSLINUX  
175 - // T=4: ETHERBOOT  
176 - // V=version  
177 - /* 0x211 */ uint8_t loadflags;  
178 - // bit0 = 1: kernel is loaded high (bzImage)  
179 - // bit7 = 1: Heap and pointer (see below) set by boot  
180 - // loader.  
181 - /* 0x212 */ uint16_t setup_S_temp1;  
182 - /* 0x214 */ uint32_t kernel_start;  
183 - /* 0x218 */ uint32_t initrd_start;  
184 - /* 0x21c */ uint32_t initrd_size;  
185 - /* 0x220 */ uint8_t setup_S_temp2[4];  
186 - /* 0x224 */ uint16_t setup_S_heap_end_pointer;  
187 - /* 0x226 */ uint8_t pad7[0x2d0 - 0x226];  
188 -  
189 - /* 0x2d0 : Int 15, ax=e820 memory map. */  
190 - // (linux/include/asm-i386/e820.h, 'struct e820entry')  
191 -#define E820MAX 32  
192 -#define E820_RAM 1  
193 -#define E820_RESERVED 2  
194 -#define E820_ACPI 3 /* usable as RAM once ACPI tables have been read */  
195 -#define E820_NVS 4  
196 - struct {  
197 - uint64_t addr;  
198 - uint64_t size;  
199 - uint32_t type;  
200 - } e820map[E820MAX];  
201 -  
202 - /* 0x550 */ uint8_t pad8[0x600 - 0x550];  
203 -  
204 - // BIOS Enhanced Disk Drive Services.  
205 - // (From linux/include/asm-i386/edd.h, 'struct edd_info')  
206 - // Each 'struct edd_info is 78 bytes, times a max of 6 structs in array.  
207 - /* 0x600 */ uint8_t eddbuf[0x7d4 - 0x600];  
208 -  
209 - /* 0x7d4 */ uint8_t pad9[0x800 - 0x7d4];  
210 - /* 0x800 */ uint8_t commandline[0x800];  
211 -  
212 - /* 0x1000 */  
213 - uint64_t gdt_table[256];  
214 - uint64_t idt_table[48];  
215 -};  
216 -  
217 -#define KERNEL_CS 0x10  
218 -#define KERNEL_DS 0x18  
219 -  
220 /* XXX: use a two level table to limit memory usage */ 105 /* XXX: use a two level table to limit memory usage */
221 #define MAX_IOPORTS 65536 106 #define MAX_IOPORTS 65536
222 107
@@ -360,28 +245,28 @@ char *pstrcat(char *buf, int buf_size, const char *s) @@ -360,28 +245,28 @@ char *pstrcat(char *buf, int buf_size, const char *s)
360 return buf; 245 return buf;
361 } 246 }
362 247
363 -int load_kernel(const char *filename, uint8_t *addr) 248 +#if defined (TARGET_I386)
  249 +int load_kernel(const char *filename, uint8_t *addr,
  250 + uint8_t *real_addr)
364 { 251 {
365 int fd, size; 252 int fd, size;
366 -#if defined (TARGET_I386)  
367 int setup_sects; 253 int setup_sects;
368 - uint8_t bootsect[512];  
369 -#endif  
370 254
371 - printf("Load kernel at %p (0x%08x)\n", addr,  
372 - (uint32_t)addr - (uint32_t)phys_ram_base);  
373 fd = open(filename, O_RDONLY); 255 fd = open(filename, O_RDONLY);
374 if (fd < 0) 256 if (fd < 0)
375 return -1; 257 return -1;
376 -#if defined (TARGET_I386)  
377 - if (read(fd, bootsect, 512) != 512) 258 +
  259 + /* load 16 bit code */
  260 + if (read(fd, real_addr, 512) != 512)
378 goto fail; 261 goto fail;
379 - setup_sects = bootsect[0x1F1]; 262 + setup_sects = real_addr[0x1F1];
380 if (!setup_sects) 263 if (!setup_sects)
381 setup_sects = 4; 264 setup_sects = 4;
382 - /* skip 16 bit setup code */  
383 - lseek(fd, (setup_sects + 1) * 512, SEEK_SET);  
384 -#endif 265 + if (read(fd, real_addr + 512, setup_sects * 512) !=
  266 + setup_sects * 512)
  267 + goto fail;
  268 +
  269 + /* load 32 bit code */
385 size = read(fd, addr, 16 * 1024 * 1024); 270 size = read(fd, addr, 16 * 1024 * 1024);
386 if (size < 0) 271 if (size < 0)
387 goto fail; 272 goto fail;
@@ -391,6 +276,7 @@ int load_kernel(const char *filename, uint8_t *addr) @@ -391,6 +276,7 @@ int load_kernel(const char *filename, uint8_t *addr)
391 close(fd); 276 close(fd);
392 return -1; 277 return -1;
393 } 278 }
  279 +#endif
394 280
395 /* return the size or -1 if error */ 281 /* return the size or -1 if error */
396 int load_image(const char *filename, uint8_t *addr) 282 int load_image(const char *filename, uint8_t *addr)
@@ -486,6 +372,7 @@ void hw_error(const char *fmt, ...) @@ -486,6 +372,7 @@ void hw_error(const char *fmt, ...)
486 /* PC cmos mappings */ 372 /* PC cmos mappings */
487 #define REG_EQUIPMENT_BYTE 0x14 373 #define REG_EQUIPMENT_BYTE 0x14
488 #define REG_IBM_CENTURY_BYTE 0x32 374 #define REG_IBM_CENTURY_BYTE 0x32
  375 +#define REG_IBM_PS2_CENTURY_BYTE 0x37
489 376
490 uint8_t cmos_data[128]; 377 uint8_t cmos_data[128];
491 uint8_t cmos_index; 378 uint8_t cmos_index;
@@ -550,6 +437,7 @@ static void cmos_update_time(void) @@ -550,6 +437,7 @@ static void cmos_update_time(void)
550 cmos_data[RTC_MONTH] = to_bcd(tm->tm_mon + 1); 437 cmos_data[RTC_MONTH] = to_bcd(tm->tm_mon + 1);
551 cmos_data[RTC_YEAR] = to_bcd(tm->tm_year % 100); 438 cmos_data[RTC_YEAR] = to_bcd(tm->tm_year % 100);
552 cmos_data[REG_IBM_CENTURY_BYTE] = to_bcd((tm->tm_year / 100) + 19); 439 cmos_data[REG_IBM_CENTURY_BYTE] = to_bcd((tm->tm_year / 100) + 19);
  440 + cmos_data[REG_IBM_PS2_CENTURY_BYTE] = cmos_data[REG_IBM_CENTURY_BYTE];
553 } 441 }
554 442
555 uint32_t cmos_ioport_read(CPUState *env, uint32_t addr) 443 uint32_t cmos_ioport_read(CPUState *env, uint32_t addr)
@@ -568,6 +456,7 @@ uint32_t cmos_ioport_read(CPUState *env, uint32_t addr) @@ -568,6 +456,7 @@ uint32_t cmos_ioport_read(CPUState *env, uint32_t addr)
568 case RTC_MONTH: 456 case RTC_MONTH:
569 case RTC_YEAR: 457 case RTC_YEAR:
570 case REG_IBM_CENTURY_BYTE: 458 case REG_IBM_CENTURY_BYTE:
  459 + case REG_IBM_PS2_CENTURY_BYTE:
571 cmos_update_time(); 460 cmos_update_time();
572 ret = cmos_data[cmos_index]; 461 ret = cmos_data[cmos_index];
573 break; 462 break;
@@ -3082,23 +2971,6 @@ static void host_alarm_handler(int host_signum, siginfo_t *info, @@ -3082,23 +2971,6 @@ static void host_alarm_handler(int host_signum, siginfo_t *info,
3082 } 2971 }
3083 } 2972 }
3084 2973
3085 -#ifdef CONFIG_SOFTMMU  
3086 -void *get_mmap_addr(unsigned long size)  
3087 -{  
3088 - return NULL;  
3089 -}  
3090 -#else  
3091 -unsigned long mmap_addr = PHYS_RAM_BASE;  
3092 -  
3093 -void *get_mmap_addr(unsigned long size)  
3094 -{  
3095 - unsigned long addr;  
3096 - addr = mmap_addr;  
3097 - mmap_addr += ((size + 4095) & ~4095) + 4096;  
3098 - return (void *)addr;  
3099 -}  
3100 -#endif  
3101 -  
3102 /* main execution loop */ 2974 /* main execution loop */
3103 2975
3104 CPUState *cpu_gdbstub_get_env(void *opaque) 2976 CPUState *cpu_gdbstub_get_env(void *opaque)
@@ -3259,6 +3131,10 @@ void help(void) @@ -3259,6 +3131,10 @@ void help(void)
3259 "-d output log to %s\n" 3131 "-d output log to %s\n"
3260 "-hdachs c,h,s force hard disk 0 geometry (usually qemu can guess it)\n" 3132 "-hdachs c,h,s force hard disk 0 geometry (usually qemu can guess it)\n"
3261 "-L path set the directory for the BIOS and VGA BIOS\n" 3133 "-L path set the directory for the BIOS and VGA BIOS\n"
  3134 +#ifdef USE_CODE_COPY
  3135 + "-no-code-copy disable code copy acceleration\n"
  3136 +#endif
  3137 +
3262 "\n" 3138 "\n"
3263 "During emulation, use C-a h to get terminal commands:\n", 3139 "During emulation, use C-a h to get terminal commands:\n",
3264 #ifdef CONFIG_SOFTMMU 3140 #ifdef CONFIG_SOFTMMU
@@ -3295,6 +3171,7 @@ struct option long_options[] = { @@ -3295,6 +3171,7 @@ struct option long_options[] = {
3295 { "boot", 1, NULL, 0, }, 3171 { "boot", 1, NULL, 0, },
3296 { "fda", 1, NULL, 0, }, 3172 { "fda", 1, NULL, 0, },
3297 { "fdb", 1, NULL, 0, }, 3173 { "fdb", 1, NULL, 0, },
  3174 + { "no-code-copy", 0, NULL, 0},
3298 { NULL, 0, NULL, 0 }, 3175 { NULL, 0, NULL, 0 },
3299 }; 3176 };
3300 3177
@@ -3310,19 +3187,26 @@ extern void __sigaction(); @@ -3310,19 +3187,26 @@ extern void __sigaction();
3310 #endif 3187 #endif
3311 #endif /* CONFIG_SDL */ 3188 #endif /* CONFIG_SDL */
3312 3189
  3190 +#if defined (TARGET_I386) && defined(USE_CODE_COPY)
  3191 +
  3192 +/* this stack is only used during signal handling */
  3193 +#define SIGNAL_STACK_SIZE 32768
  3194 +
  3195 +static uint8_t *signal_stack;
  3196 +
  3197 +#endif
  3198 +
3313 int main(int argc, char **argv) 3199 int main(int argc, char **argv)
3314 { 3200 {
3315 int c, ret, initrd_size, i, use_gdbstub, gdbstub_port, long_index; 3201 int c, ret, initrd_size, i, use_gdbstub, gdbstub_port, long_index;
3316 int snapshot, linux_boot; 3202 int snapshot, linux_boot;
3317 -#if defined (TARGET_I386)  
3318 - struct linux_params *params;  
3319 -#endif  
3320 struct sigaction act; 3203 struct sigaction act;
3321 struct itimerval itv; 3204 struct itimerval itv;
3322 CPUState *env; 3205 CPUState *env;
3323 const char *initrd_filename; 3206 const char *initrd_filename;
3324 const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD]; 3207 const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
3325 const char *kernel_filename, *kernel_cmdline; 3208 const char *kernel_filename, *kernel_cmdline;
  3209 + char buf[1024];
3326 DisplayState *ds = &display_state; 3210 DisplayState *ds = &display_state;
3327 3211
3328 /* we never want that malloc() uses mmap() */ 3212 /* we never want that malloc() uses mmap() */
@@ -3420,6 +3304,9 @@ int main(int argc, char **argv) @@ -3420,6 +3304,9 @@ int main(int argc, char **argv)
3420 case 14: 3304 case 14:
3421 fd_filename[1] = optarg; 3305 fd_filename[1] = optarg;
3422 break; 3306 break;
  3307 + case 15:
  3308 + code_copy_enabled = 0;
  3309 + break;
3423 } 3310 }
3424 break; 3311 break;
3425 case 'h': 3312 case 'h':
@@ -3554,9 +3441,42 @@ int main(int argc, char **argv) @@ -3554,9 +3441,42 @@ int main(int argc, char **argv)
3554 /* allocate RAM */ 3441 /* allocate RAM */
3555 cpu_register_physical_memory(0, ram_size, 0); 3442 cpu_register_physical_memory(0, ram_size, 0);
3556 3443
  3444 +#if defined(TARGET_I386)
  3445 + /* RAW PC boot */
  3446 +
  3447 + /* BIOS load */
  3448 + snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
  3449 + ret = load_image(buf, phys_ram_base + 0x000f0000);
  3450 + if (ret != 0x10000) {
  3451 + fprintf(stderr, "qemu: could not load PC bios '%s'\n", buf);
  3452 + exit(1);
  3453 + }
  3454 +
  3455 + /* VGA BIOS load */
  3456 + snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME);
  3457 + ret = load_image(buf, phys_ram_base + 0x000c0000);
  3458 +
  3459 + /* setup basic memory access */
  3460 + cpu_register_physical_memory(0xc0000, 0x10000, 0xc0000 | IO_MEM_ROM);
  3461 + cpu_register_physical_memory(0xf0000, 0x10000, 0xf0000 | IO_MEM_ROM);
  3462 +
  3463 + bochs_bios_init();
  3464 +
3557 if (linux_boot) { 3465 if (linux_boot) {
  3466 + extern uint8_t linux_boot_start;
  3467 + extern uint8_t linux_boot_end;
  3468 +
  3469 + if (bs_table[0] == NULL) {
  3470 + fprintf(stderr, "A disk image must be given for 'hda' when booting a Linux kernel\n");
  3471 + exit(1);
  3472 + }
  3473 + bdrv_set_boot_sector(bs_table[0], &linux_boot_start,
  3474 + &linux_boot_end - &linux_boot_start);
  3475 +
3558 /* now we can load the kernel */ 3476 /* now we can load the kernel */
3559 - ret = load_kernel(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR); 3477 + ret = load_kernel(kernel_filename,
  3478 + phys_ram_base + KERNEL_LOAD_ADDR,
  3479 + phys_ram_base + KERNEL_PARAMS_ADDR);
3560 if (ret < 0) { 3480 if (ret < 0) {
3561 fprintf(stderr, "qemu: could not load kernel '%s'\n", 3481 fprintf(stderr, "qemu: could not load kernel '%s'\n",
3562 kernel_filename); 3482 kernel_filename);
@@ -3573,89 +3493,30 @@ int main(int argc, char **argv) @@ -3573,89 +3493,30 @@ int main(int argc, char **argv)
3573 exit(1); 3493 exit(1);
3574 } 3494 }
3575 } 3495 }
3576 -  
3577 - /* init kernel params */  
3578 -#ifdef TARGET_I386  
3579 - params = (void *)(phys_ram_base + KERNEL_PARAMS_ADDR);  
3580 - memset(params, 0, sizeof(struct linux_params));  
3581 - params->mount_root_rdonly = 0;  
3582 - stw_raw(&params->cl_magic, 0xA33F);  
3583 - stw_raw(&params->cl_offset, params->commandline - (uint8_t *)params);  
3584 - stl_raw(&params->alt_mem_k, (ram_size / 1024) - 1024);  
3585 - pstrcat(params->commandline, sizeof(params->commandline), kernel_cmdline);  
3586 - params->loader_type = 0x01;  
3587 if (initrd_size > 0) { 3496 if (initrd_size > 0) {
3588 - stl_raw(&params->initrd_start, INITRD_LOAD_ADDR);  
3589 - stl_raw(&params->initrd_size, initrd_size); 3497 + stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x218, INITRD_LOAD_ADDR);
  3498 + stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x21c, initrd_size);
3590 } 3499 }
3591 - params->orig_video_lines = 25;  
3592 - params->orig_video_cols = 80;  
3593 -  
3594 - /* setup basic memory access */  
3595 - cpu_x86_update_cr0(env, 0x00000033);  
3596 -  
3597 - memset(params->idt_table, 0, sizeof(params->idt_table));  
3598 -  
3599 - stq_raw(&params->gdt_table[2], 0x00cf9a000000ffffLL); /* KERNEL_CS */  
3600 - stq_raw(&params->gdt_table[3], 0x00cf92000000ffffLL); /* KERNEL_DS */  
3601 - /* for newer kernels (2.6.0) CS/DS are at different addresses */  
3602 - stq_raw(&params->gdt_table[12], 0x00cf9a000000ffffLL); /* KERNEL_CS */  
3603 - stq_raw(&params->gdt_table[13], 0x00cf92000000ffffLL); /* KERNEL_DS */  
3604 -  
3605 - env->idt.base = (void *)((uint8_t *)params->idt_table - phys_ram_base);  
3606 - env->idt.limit = sizeof(params->idt_table) - 1;  
3607 - env->gdt.base = (void *)((uint8_t *)params->gdt_table - phys_ram_base);  
3608 - env->gdt.limit = sizeof(params->gdt_table) - 1;  
3609 -  
3610 - cpu_x86_load_seg_cache(env, R_CS, KERNEL_CS, NULL, 0xffffffff, 0x00cf9a00);  
3611 - cpu_x86_load_seg_cache(env, R_DS, KERNEL_DS, NULL, 0xffffffff, 0x00cf9200);  
3612 - cpu_x86_load_seg_cache(env, R_ES, KERNEL_DS, NULL, 0xffffffff, 0x00cf9200);  
3613 - cpu_x86_load_seg_cache(env, R_SS, KERNEL_DS, NULL, 0xffffffff, 0x00cf9200);  
3614 - cpu_x86_load_seg_cache(env, R_FS, KERNEL_DS, NULL, 0xffffffff, 0x00cf9200);  
3615 - cpu_x86_load_seg_cache(env, R_GS, KERNEL_DS, NULL, 0xffffffff, 0x00cf9200);  
3616 -  
3617 - env->eip = KERNEL_LOAD_ADDR;  
3618 - env->regs[R_ESI] = KERNEL_PARAMS_ADDR;  
3619 - env->eflags = 0x2;  
3620 -#elif defined (TARGET_PPC)  
3621 - PPC_init_hw(env, ram_size, KERNEL_LOAD_ADDR, ret,  
3622 - KERNEL_STACK_ADDR, boot_device);  
3623 -#endif  
3624 - } else {  
3625 - char buf[1024];  
3626 -  
3627 - /* RAW PC boot */  
3628 -#if defined(TARGET_I386)  
3629 - /* BIOS load */  
3630 - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);  
3631 - ret = load_image(buf, phys_ram_base + 0x000f0000);  
3632 - if (ret != 0x10000) {  
3633 - fprintf(stderr, "qemu: could not load PC bios '%s'\n", buf);  
3634 - exit(1);  
3635 - }  
3636 -  
3637 - /* VGA BIOS load */  
3638 - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME);  
3639 - ret = load_image(buf, phys_ram_base + 0x000c0000);  
3640 -  
3641 - /* setup basic memory access */  
3642 - cpu_register_physical_memory(0xc0000, 0x10000, 0xc0000 | IO_MEM_ROM);  
3643 - cpu_register_physical_memory(0xf0000, 0x10000, 0xf0000 | IO_MEM_ROM);  
3644 -  
3645 - bochs_bios_init(); 3500 + pstrcpy(phys_ram_base + KERNEL_CMDLINE_ADDR, 4096,
  3501 + kernel_cmdline);
  3502 + stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x20, 0xA33F);
  3503 + stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x22,
  3504 + KERNEL_CMDLINE_ADDR - KERNEL_PARAMS_ADDR);
  3505 + /* loader type */
  3506 + stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x210, 0x01);
  3507 + }
3646 #elif defined(TARGET_PPC) 3508 #elif defined(TARGET_PPC)
3647 - /* allocate ROM */  
3648 - // snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);  
3649 - snprintf(buf, sizeof(buf), "%s", BIOS_FILENAME);  
3650 - printf("load BIOS at %p\n", phys_ram_base + 0x000f0000);  
3651 - ret = load_image(buf, phys_ram_base + 0x000f0000);  
3652 - if (ret != 0x10000) {  
3653 - fprintf(stderr, "qemu: could not load PPC bios '%s' (%d)\n%m\n",  
3654 - buf, ret);  
3655 - exit(1);  
3656 - }  
3657 -#endif 3509 + /* allocate ROM */
  3510 + // snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
  3511 + snprintf(buf, sizeof(buf), "%s", BIOS_FILENAME);
  3512 + printf("load BIOS at %p\n", phys_ram_base + 0x000f0000);
  3513 + ret = load_image(buf, phys_ram_base + 0x000f0000);
  3514 + if (ret != 0x10000) {
  3515 + fprintf(stderr, "qemu: could not load PPC bios '%s' (%d)\n%m\n",
  3516 + buf, ret);
  3517 + exit(1);
3658 } 3518 }
  3519 +#endif
3659 3520
3660 /* terminal init */ 3521 /* terminal init */
3661 if (nographic) { 3522 if (nographic) {
@@ -3692,15 +3553,44 @@ int main(int argc, char **argv) @@ -3692,15 +3553,44 @@ int main(int argc, char **argv)
3692 PPC_end_init(); 3553 PPC_end_init();
3693 #endif 3554 #endif
3694 fdctrl_register((unsigned char **)fd_filename, snapshot, boot_device); 3555 fdctrl_register((unsigned char **)fd_filename, snapshot, boot_device);
  3556 +
3695 /* setup cpu signal handlers for MMU / self modifying code handling */ 3557 /* setup cpu signal handlers for MMU / self modifying code handling */
  3558 +#if !defined(CONFIG_SOFTMMU)
  3559 +
  3560 +#if defined (TARGET_I386) && defined(USE_CODE_COPY)
  3561 + {
  3562 + stack_t stk;
  3563 + signal_stack = malloc(SIGNAL_STACK_SIZE);
  3564 + stk.ss_sp = signal_stack;
  3565 + stk.ss_size = SIGNAL_STACK_SIZE;
  3566 + stk.ss_flags = 0;
  3567 +
  3568 + if (sigaltstack(&stk, NULL) < 0) {
  3569 + perror("sigaltstack");
  3570 + exit(1);
  3571 + }
  3572 + }
  3573 +#endif
  3574 +
3696 sigfillset(&act.sa_mask); 3575 sigfillset(&act.sa_mask);
3697 act.sa_flags = SA_SIGINFO; 3576 act.sa_flags = SA_SIGINFO;
3698 -#if !defined(CONFIG_SOFTMMU) 3577 +#if defined (TARGET_I386) && defined(USE_CODE_COPY)
  3578 + act.sa_flags |= SA_ONSTACK;
  3579 +#endif
3699 act.sa_sigaction = host_segv_handler; 3580 act.sa_sigaction = host_segv_handler;
3700 sigaction(SIGSEGV, &act, NULL); 3581 sigaction(SIGSEGV, &act, NULL);
3701 sigaction(SIGBUS, &act, NULL); 3582 sigaction(SIGBUS, &act, NULL);
  3583 +#if defined (TARGET_I386) && defined(USE_CODE_COPY)
  3584 + sigaction(SIGFPE, &act, NULL);
  3585 +#endif
3702 #endif 3586 #endif
3703 3587
  3588 + /* timer signal */
  3589 + sigfillset(&act.sa_mask);
  3590 + act.sa_flags = SA_SIGINFO;
  3591 +#if defined (TARGET_I386) && defined(USE_CODE_COPY)
  3592 + act.sa_flags |= SA_ONSTACK;
  3593 +#endif
3704 act.sa_sigaction = host_alarm_handler; 3594 act.sa_sigaction = host_alarm_handler;
3705 sigaction(SIGALRM, &act, NULL); 3595 sigaction(SIGALRM, &act, NULL);
3706 3596
@@ -32,7 +32,6 @@ extern int64_t ticks_per_sec; @@ -32,7 +32,6 @@ extern int64_t ticks_per_sec;
32 typedef void (IOPortWriteFunc)(struct CPUState *env, uint32_t address, uint32_t data); 32 typedef void (IOPortWriteFunc)(struct CPUState *env, uint32_t address, uint32_t data);
33 typedef uint32_t (IOPortReadFunc)(struct CPUState *env, uint32_t address); 33 typedef uint32_t (IOPortReadFunc)(struct CPUState *env, uint32_t address);
34 34
35 -void *get_mmap_addr(unsigned long size);  
36 int register_ioport_read(int start, int length, IOPortReadFunc *func, int size); 35 int register_ioport_read(int start, int length, IOPortReadFunc *func, int size);
37 int register_ioport_write(int start, int length, IOPortWriteFunc *func, int size); 36 int register_ioport_write(int start, int length, IOPortWriteFunc *func, int size);
38 void pic_set_irq(int irq, int level); 37 void pic_set_irq(int irq, int level);
@@ -56,6 +55,7 @@ int bdrv_write(BlockDriverState *bs, int64_t sector_num, @@ -56,6 +55,7 @@ int bdrv_write(BlockDriverState *bs, int64_t sector_num,
56 const uint8_t *buf, int nb_sectors); 55 const uint8_t *buf, int nb_sectors);
57 void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr); 56 void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr);
58 int bdrv_commit(BlockDriverState *bs); 57 int bdrv_commit(BlockDriverState *bs);
  58 +void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size);
59 59
60 /* user mode linux compatible COW file */ 60 /* user mode linux compatible COW file */
61 #define COW_MAGIC 0x4f4f4f4d /* MOOO */ 61 #define COW_MAGIC 0x4f4f4f4d /* MOOO */