| 2341 | #define KERNEL_PARAMS_ADDR 0x00090000 |
| 2342 | |
| 2343 | static void copy_kernel(PCMachine *s, const uint8_t *buf, int buf_len, |
| 2344 | const char *cmd_line) |
| 2345 | { |
| 2346 | uint8_t *ram_ptr; |
| 2347 | int setup_sects, header_len, copy_len, setup_hdr_start, setup_hdr_end; |
| 2348 | uint32_t load_address; |
| 2349 | struct linux_params *params; |
| 2350 | FBDevice *fb_dev; |
| 2351 | |
| 2352 | if (buf_len < 1024) { |
| 2353 | too_small: |
| 2354 | fprintf(stderr, "Kernel too small\n"); |
| 2355 | exit(1); |
| 2356 | } |
| 2357 | if (buf[0x1fe] != 0x55 || buf[0x1ff] != 0xaa) { |
| 2358 | fprintf(stderr, "Invalid kernel magic\n"); |
| 2359 | exit(1); |
| 2360 | } |
| 2361 | setup_sects = buf[0x1f1]; |
| 2362 | if (setup_sects == 0) |
| 2363 | setup_sects = 4; |
| 2364 | header_len = (setup_sects + 1) * 512; |
| 2365 | if (buf_len < header_len) |
| 2366 | goto too_small; |
| 2367 | if (memcmp(buf + 0x202, "HdrS", 4) != 0) { |
| 2368 | fprintf(stderr, "Kernel too old\n"); |
| 2369 | exit(1); |
| 2370 | } |
| 2371 | load_address = 0x100000; /* we don't support older protocols */ |
| 2372 | |
| 2373 | ram_ptr = get_ram_ptr(s, load_address); |
| 2374 | copy_len = buf_len - header_len; |
| 2375 | if (copy_len > (s->ram_size - load_address)) { |
| 2376 | fprintf(stderr, "Not enough RAM\n"); |
| 2377 | exit(1); |
| 2378 | } |
| 2379 | memcpy(ram_ptr, buf + header_len, copy_len); |
| 2380 | |
| 2381 | params = (void *)get_ram_ptr(s, KERNEL_PARAMS_ADDR); |
| 2382 | |
| 2383 | memset(params, 0, sizeof(struct linux_params)); |
| 2384 | |
| 2385 | /* copy the setup header */ |
| 2386 | setup_hdr_start = 0x1f1; |
| 2387 | setup_hdr_end = 0x202 + buf[0x201]; |
| 2388 | memcpy((uint8_t *)params + setup_hdr_start, buf + setup_hdr_start, |
| 2389 | setup_hdr_end - setup_hdr_start); |
| 2390 | |
| 2391 | strcpy((char *)params->commandline, cmd_line); |
| 2392 | |
| 2393 | params->mount_root_rdonly = 0; |
| 2394 | params->cmd_line_ptr = KERNEL_PARAMS_ADDR + |
| 2395 | offsetof(struct linux_params, commandline); |
| 2396 | params->alt_mem_k = (s->ram_size / 1024) - 1024; |
| 2397 | params->loader_type = 0x01; |
| 2398 | #if 0 |
| 2399 | if (initrd_size > 0) { |
| 2400 | params->initrd_start = INITRD_LOAD_ADDR; |
no test coverage detected