Commit 77fef8c148e4bec1d1089b3729bd32efdbd3a6c0
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
vl.c
@@ -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(¶ms->cl_magic, 0xA33F); | ||
3583 | - stw_raw(¶ms->cl_offset, params->commandline - (uint8_t *)params); | ||
3584 | - stl_raw(¶ms->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(¶ms->initrd_start, INITRD_LOAD_ADDR); | ||
3589 | - stl_raw(¶ms->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(¶ms->gdt_table[2], 0x00cf9a000000ffffLL); /* KERNEL_CS */ | ||
3600 | - stq_raw(¶ms->gdt_table[3], 0x00cf92000000ffffLL); /* KERNEL_DS */ | ||
3601 | - /* for newer kernels (2.6.0) CS/DS are at different addresses */ | ||
3602 | - stq_raw(¶ms->gdt_table[12], 0x00cf9a000000ffffLL); /* KERNEL_CS */ | ||
3603 | - stq_raw(¶ms->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 |
vl.h
@@ -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 */ |