int monte_load_linux_initrd(struct monte_boot_t *boot, const void *buffer, long size) { long initrd_addr; void *ramdisk_data; struct monte_region_t *region; /*--- XXX Disgusting hack --------------------------------------------- * We can't tell how big memory is very easily from user space. * /proc/meminfo is close but a pain to read. In stead we just * stat /proc/kcore. This seems easiest and comes closest to the * correct answer. What a mess. *-------------------------------------------------------------------*/ struct stat buf; if (stat("/proc/kcore", &buf) == -1) { buf.st_size = 32*1024*1024; /* a random guess if /proc isn't mounted.*/ } initrd_addr = ((buf.st_size/4)*3) & PAGE_MASK; /* Next problem: We don't know how big this ram disk image is a * head of time so just start loading a page at a time :P */ region = region_new(boot, (void *) initrd_addr); ramdisk_data = region_size(region, size); memcpy(ramdisk_data, buffer, size); printf("monte: initial ramdisk: %8ld bytes at %p\n", size, (void *)initrd_addr); /* Put the right bits in RAM so the kernel will find the initrd */ #if defined(__i386__) boot->setup->ramdisk = initrd_addr; boot->setup->ramdisk_size = size; #elif defined(__alpha__) region = region_new(boot, (void *) __pa(boot->param.entrypoint - 0x6000)); ramdisk_data = region_size(region, PAGE_SIZE); ramdisk_data += 0x100; ((long*)ramdisk_data)[0] = __va(initrd_addr); ((long*)ramdisk_data)[1] = size; #else #error No initrd argument placement code for this architecture. #endif return 0; }
int monte_load_linux_command_line(struct monte_boot_t *boot, char *cmdline) { struct monte_region_t *region; char *cmd_line; /* Setup the kernel command line */ region = region_new(boot, (void *) MONTE_CMDLINE_BEGIN); cmd_line = region_size(region, PAGE_SIZE); boot->setup->cmd_line_ptr = MONTE_CMDLINE_BEGIN; boot->setup->cmd_magic = CMDLINE_MAGIC; boot->setup->cmd_offset = MONTE_CMDLINE_BEGIN - MONTE_SETUP_BEGIN; strcpy(cmd_line, cmdline); printf("monte: command line : \"%s\"\n", cmdline); return 0; }
int monte_load_linux_command_line(struct monte_boot_t *boot, char *cmdline) { struct monte_region_t *region; char *cmd_line; /* Setup the kernel command line */ /* On alpha, the command line sits in the zero page at address * ?0a000 which is in the region before the kernel entry * point... Also, one page should be enough for it.*/ region = region_new(boot, (void *) __pa(boot->param.entrypoint - 0x6000)); cmd_line = region_size(region, PAGE_SIZE); strcpy(cmd_line, cmdline); printf("monte: command line : \"%s\"\n", cmdline); return 0; }
static int load_elf_image(struct monte_boot_t *boot, const void *buffer, long size) { int i; Elf64_Ehdr *ehdr; Elf64_Phdr *phdr; struct monte_region_t *region; void *kernimage; /* Super simple ELF loader that makes gobs of assumptions that * won't be valid anywhere except Linux ELF kernel images */ ehdr = (Elf64_Ehdr *) buffer; if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0) { fprintf(stderr, "not an ELF file.\n"); return -1; } if (ehdr->e_ident[EI_CLASS] != ELFCLASS64) { fprintf(stderr, "ELF object is not an ELF64 object.\n"); return -1; } phdr = (Elf64_Phdr *)(buffer + ehdr->e_phoff); for (i=0; i < ehdr->e_phnum; i++) { /* Load a program section */ /* Setup a region for this thing */ region = region_new(boot, (void*)__pa(phdr[i].p_vaddr)); kernimage = region_size(region, phdr[i].p_memsz+(1024*PAGE_SIZE)); /* Load data and zero the rest (BSS) */ printf("monte: kernel code : %8ld bytes at %p\n", phdr[i].p_filesz, (void*) __pa(phdr[i].p_vaddr)); memcpy(kernimage, buffer + phdr[i].p_offset, phdr[i].p_filesz); memset(kernimage + phdr[i].p_filesz, 0, phdr[i].p_memsz - phdr[i].p_filesz); } boot->param.entrypoint = ehdr->e_entry; printf("monte: entry point : %p\n", (void*)boot->param.entrypoint); return 0; }
inline HeapWord* ParMarkBitMap::region_end() const { return region_start() + region_size(); }
int monte_load_linux_kernel(struct monte_boot_t *boot, const void *buffer, long size){ void *setup_data, *kernel_data; struct monte_region_t *region; struct kernel_setup_t *stmp; stmp = (struct kernel_setup_t *)buffer; /* Sanity check */ /* Check for the kernel setup signature */ if (stmp->boot_flag != BS_SIG_VAL) { fprintf(stderr, "monte: Boot signature not found.\n"); return -1; } /* Sanity check number of sectors */ if (stmp->setup_sects > MAX_SETUP_SECTS) { fprintf(stderr, "monte: number of setup sectors too large: %d" " (max %d)\n",(int) stmp->setup_sects, MAX_SETUP_SECTS); return -1; } /* Check for that setup signature. */ if (strncmp(stmp->signature, SETUP_SIG_VAL, strlen(SETUP_SIG_VAL)) != 0) { fprintf(stderr, "monte: Kernel image setup signature not found.\n"); return -1; } /* Setup the region for the setup code */ region = region_new(boot, (void *)MONTE_SETUP_BEGIN); setup_data = region_size(region, (stmp->setup_sects+1)*512); boot->setup = setup_data; memcpy(setup_data, buffer, (stmp->setup_sects+1)*512); printf("monte: kernel setup : %8d bytes at %p\n", ((int) stmp->setup_sects)*512, (void*)MONTE_SETUP_BEGIN); buffer += (stmp->setup_sects+1)*512; /* update buffer pointers */ size -= (stmp->setup_sects+1)*512; /* The number of kernel "paragraphs" is getting overflowed by * todays kernels. Ignore it and just load the rest of the data * we have. */ region = region_new(boot, (void*)boot->setup->start); kernel_data = region_size(region, size); memcpy(kernel_data, buffer, size); printf("monte: kernel code : %8d bytes at %p\n", (int) size, (void *) boot->setup->start); if (boot->param.flags & MONTE_PROTECTED) { if (save_old_setup(boot)) return -1; boot->param.entrypoint = boot->setup->start; } else boot->param.entrypoint = 0x90200000; /* Real mode 9020:0000 */ /* XXXXX FIX ME XXXXXX THIS IS A HACK!!! XXXXXX */ if (boot->param.entrypoint == 0) { printf("monte: Forcing entry point to 0x100000\n"); boot->param.entrypoint = 0x100000; } /* XXXXX FIX ME XXXXXX THIS IS A HACK!!! XXXXXX */ boot->setup->loader = 0x50; /* Set the loader type. */ boot->setup->ramdisk = 0; boot->setup->ramdisk_size = 0; boot->setup->cmd_magic = 0; boot->setup->cmd_offset = 0; return 0; }