diff --git a/stand/i386/gptboot/gptboot.c b/stand/i386/gptboot/gptboot.c index a9d54f46196d..07a5e71c7e69 100644 --- a/stand/i386/gptboot/gptboot.c +++ b/stand/i386/gptboot/gptboot.c @@ -132,87 +132,93 @@ xfsread(ufs_ino_t inode, void *buf, size_t nbyte) static void bios_getmem(void) { - uint64_t size; + uint64_t size; - /* Parse system memory map */ - v86.ebx = 0; - do { - v86.ctl = V86_FLAGS; - v86.addr = MEM_EXT; /* int 0x15 function 0xe820*/ - v86.eax = 0xe820; - v86.ecx = sizeof(struct bios_smap); - v86.edx = SMAP_SIG; - v86.es = VTOPSEG(&smap); - v86.edi = VTOPOFF(&smap); - v86int(); - if ((v86.efl & 1) || (v86.eax != SMAP_SIG)) - break; - /* look for a low-memory segment that's large enough */ - if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0) && - (smap.length >= (512 * 1024))) - bios_basemem = smap.length; - /* look for the first segment in 'extended' memory */ - if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0x100000)) { - bios_extmem = smap.length; + /* Parse system memory map */ + v86.ebx = 0; + do { + v86.ctl = V86_FLAGS; + v86.addr = MEM_EXT; /* int 0x15 function 0xe820*/ + v86.eax = 0xe820; + v86.ecx = sizeof(struct bios_smap); + v86.edx = SMAP_SIG; + v86.es = VTOPSEG(&smap); + v86.edi = VTOPOFF(&smap); + v86int(); + if ((v86.efl & 1) || (v86.eax != SMAP_SIG)) + break; + /* look for a low-memory segment that's large enough */ + if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0) && + (smap.length >= (512 * 1024))) + bios_basemem = smap.length; + /* look for the first segment in 'extended' memory */ + if ((smap.type == SMAP_TYPE_MEMORY) && + (smap.base == 0x100000)) { + bios_extmem = smap.length; + } + + /* + * Look for the largest segment in 'extended' memory beyond + * 1MB but below 4GB. + */ + if ((smap.type == SMAP_TYPE_MEMORY) && + (smap.base > 0x100000) && (smap.base < 0x100000000ull)) { + size = smap.length; + + /* + * If this segment crosses the 4GB boundary, + * truncate it. + */ + if (smap.base + size > 0x100000000ull) + size = 0x100000000ull - smap.base; + + if (size > high_heap_size) { + high_heap_size = size; + high_heap_base = smap.base; + } + } + } while (v86.ebx != 0); + + /* Fall back to the old compatibility function for base memory */ + if (bios_basemem == 0) { + v86.ctl = 0; + v86.addr = 0x12; /* int 0x12 */ + v86int(); + + bios_basemem = (v86.eax & 0xffff) * 1024; } /* - * Look for the largest segment in 'extended' memory beyond - * 1MB but below 4GB. + * Fall back through several compatibility functions for extended + * memory */ - if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base > 0x100000) && - (smap.base < 0x100000000ull)) { - size = smap.length; - - /* - * If this segment crosses the 4GB boundary, truncate it. - */ - if (smap.base + size > 0x100000000ull) - size = 0x100000000ull - smap.base; - - if (size > high_heap_size) { - high_heap_size = size; - high_heap_base = smap.base; - } + if (bios_extmem == 0) { + v86.ctl = V86_FLAGS; + v86.addr = 0x15; /* int 0x15 function 0xe801*/ + v86.eax = 0xe801; + v86int(); + if (!(v86.efl & 1)) { + bios_extmem = ((v86.ecx & 0xffff) + + ((v86.edx & 0xffff) * 64)) * 1024; + } } - } while (v86.ebx != 0); - - /* Fall back to the old compatibility function for base memory */ - if (bios_basemem == 0) { - v86.ctl = 0; - v86.addr = 0x12; /* int 0x12 */ - v86int(); - - bios_basemem = (v86.eax & 0xffff) * 1024; - } - - /* Fall back through several compatibility functions for extended memory */ - if (bios_extmem == 0) { - v86.ctl = V86_FLAGS; - v86.addr = 0x15; /* int 0x15 function 0xe801*/ - v86.eax = 0xe801; - v86int(); - if (!(v86.efl & 1)) { - bios_extmem = ((v86.ecx & 0xffff) + ((v86.edx & 0xffff) * 64)) * 1024; + if (bios_extmem == 0) { + v86.ctl = 0; + v86.addr = 0x15; /* int 0x15 function 0x88*/ + v86.eax = 0x8800; + v86int(); + bios_extmem = (v86.eax & 0xffff) * 1024; } - } - if (bios_extmem == 0) { - v86.ctl = 0; - v86.addr = 0x15; /* int 0x15 function 0x88*/ - v86.eax = 0x8800; - v86int(); - bios_extmem = (v86.eax & 0xffff) * 1024; - } - /* - * If we have extended memory and did not find a suitable heap - * region in the SMAP, use the last 3MB of 'extended' memory as a - * high heap candidate. - */ - if (bios_extmem >= HEAP_MIN && high_heap_size < HEAP_MIN) { - high_heap_size = HEAP_MIN; - high_heap_base = bios_extmem + 0x100000 - HEAP_MIN; - } + /* + * If we have extended memory and did not find a suitable heap + * region in the SMAP, use the last 3MB of 'extended' memory as a + * high heap candidate. + */ + if (bios_extmem >= HEAP_MIN && high_heap_size < HEAP_MIN) { + high_heap_size = HEAP_MIN; + high_heap_base = bios_extmem + 0x100000 - HEAP_MIN; + } } static int @@ -371,207 +377,215 @@ exit(int x) static void load(void) { - union { - struct exec ex; - Elf32_Ehdr eh; - } hdr; - static Elf32_Phdr ep[2]; - static Elf32_Shdr es[2]; - caddr_t p; - ufs_ino_t ino; - uint32_t addr, x; - int fmt, i, j; + union { + struct exec ex; + Elf32_Ehdr eh; + } hdr; + static Elf32_Phdr ep[2]; + static Elf32_Shdr es[2]; + caddr_t p; + ufs_ino_t ino; + uint32_t addr, x; + int fmt, i, j; - if (!(ino = lookup(kname))) { - if (!ls) { - printf("%s: No %s on %u:%s(%up%u)\n", BOOTPROG, - kname, dsk.drive & DRV_MASK, dev_nm[dsk.type], dsk.unit, - dsk.part); - } - return; - } - if (xfsread(ino, &hdr, sizeof(hdr))) - return; - if (N_GETMAGIC(hdr.ex) == ZMAGIC) - fmt = 0; - else if (IS_ELF(hdr.eh)) - fmt = 1; - else { - printf("Invalid %s\n", "format"); - return; - } - if (fmt == 0) { - addr = hdr.ex.a_entry & 0xffffff; - p = PTOV(addr); - fs_off = PAGE_SIZE; - if (xfsread(ino, p, hdr.ex.a_text)) - return; - p += roundup2(hdr.ex.a_text, PAGE_SIZE); - if (xfsread(ino, p, hdr.ex.a_data)) - return; - p += hdr.ex.a_data + roundup2(hdr.ex.a_bss, PAGE_SIZE); - bootinfo.bi_symtab = VTOP(p); - memcpy(p, &hdr.ex.a_syms, sizeof(hdr.ex.a_syms)); - p += sizeof(hdr.ex.a_syms); - if (hdr.ex.a_syms) { - if (xfsread(ino, p, hdr.ex.a_syms)) - return; - p += hdr.ex.a_syms; - if (xfsread(ino, p, sizeof(int))) - return; - x = *(uint32_t *)p; - p += sizeof(int); - x -= sizeof(int); - if (xfsread(ino, p, x)) - return; - p += x; - } - } else { - fs_off = hdr.eh.e_phoff; - for (j = i = 0; i < hdr.eh.e_phnum && j < 2; i++) { - if (xfsread(ino, ep + j, sizeof(ep[0]))) - return; - if (ep[j].p_type == PT_LOAD) - j++; - } - for (i = 0; i < 2; i++) { - p = PTOV(ep[i].p_paddr & 0xffffff); - fs_off = ep[i].p_offset; - if (xfsread(ino, p, ep[i].p_filesz)) + if (!(ino = lookup(kname))) { + if (!ls) { + printf("%s: No %s on %u:%s(%up%u)\n", BOOTPROG, + kname, dsk.drive & DRV_MASK, dev_nm[dsk.type], + dsk.unit, + dsk.part); + } return; } - p += roundup2(ep[1].p_memsz, PAGE_SIZE); - bootinfo.bi_symtab = VTOP(p); - if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) { - fs_off = hdr.eh.e_shoff + sizeof(es[0]) * - (hdr.eh.e_shstrndx + 1); - if (xfsread(ino, &es, sizeof(es))) + if (xfsread(ino, &hdr, sizeof(hdr))) + return; + if (N_GETMAGIC(hdr.ex) == ZMAGIC) + fmt = 0; + else if (IS_ELF(hdr.eh)) + fmt = 1; + else { + printf("Invalid %s\n", "format"); return; - for (i = 0; i < 2; i++) { - memcpy(p, &es[i].sh_size, sizeof(es[i].sh_size)); - p += sizeof(es[i].sh_size); - fs_off = es[i].sh_offset; - if (xfsread(ino, p, es[i].sh_size)) - return; - p += es[i].sh_size; - } } - addr = hdr.eh.e_entry & 0xffffff; - } - bootinfo.bi_esymtab = VTOP(p); - bootinfo.bi_kernelname = VTOP(kname); - bootinfo.bi_bios_dev = dsk.drive; + if (fmt == 0) { + addr = hdr.ex.a_entry & 0xffffff; + p = PTOV(addr); + fs_off = PAGE_SIZE; + if (xfsread(ino, p, hdr.ex.a_text)) + return; + p += roundup2(hdr.ex.a_text, PAGE_SIZE); + if (xfsread(ino, p, hdr.ex.a_data)) + return; + p += hdr.ex.a_data + roundup2(hdr.ex.a_bss, PAGE_SIZE); + bootinfo.bi_symtab = VTOP(p); + memcpy(p, &hdr.ex.a_syms, sizeof(hdr.ex.a_syms)); + p += sizeof(hdr.ex.a_syms); + if (hdr.ex.a_syms) { + if (xfsread(ino, p, hdr.ex.a_syms)) + return; + p += hdr.ex.a_syms; + if (xfsread(ino, p, sizeof(int))) + return; + x = *(uint32_t *)p; + p += sizeof(int); + x -= sizeof(int); + if (xfsread(ino, p, x)) + return; + p += x; + } + } else { + fs_off = hdr.eh.e_phoff; + for (j = i = 0; i < hdr.eh.e_phnum && j < 2; i++) { + if (xfsread(ino, ep + j, sizeof(ep[0]))) + return; + if (ep[j].p_type == PT_LOAD) + j++; + } + for (i = 0; i < 2; i++) { + p = PTOV(ep[i].p_paddr & 0xffffff); + fs_off = ep[i].p_offset; + if (xfsread(ino, p, ep[i].p_filesz)) + return; + } + p += roundup2(ep[1].p_memsz, PAGE_SIZE); + bootinfo.bi_symtab = VTOP(p); + if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) { + fs_off = hdr.eh.e_shoff + sizeof(es[0]) * + (hdr.eh.e_shstrndx + 1); + if (xfsread(ino, &es, sizeof(es))) + return; + for (i = 0; i < 2; i++) { + memcpy(p, &es[i].sh_size, + sizeof(es[i].sh_size)); + p += sizeof(es[i].sh_size); + fs_off = es[i].sh_offset; + if (xfsread(ino, p, es[i].sh_size)) + return; + p += es[i].sh_size; + } + } + addr = hdr.eh.e_entry & 0xffffff; + } + bootinfo.bi_esymtab = VTOP(p); + bootinfo.bi_kernelname = VTOP(kname); + bootinfo.bi_bios_dev = dsk.drive; #ifdef LOADER_GELI_SUPPORT - geliargs.size = sizeof(geliargs); - explicit_bzero(gelipw, sizeof(gelipw)); - gelibuf = malloc(sizeof(struct keybuf) + (GELI_MAX_KEYS * sizeof(struct keybuf_ent))); - geli_fill_keybuf(gelibuf); - geliargs.notapw = '\0'; - geliargs.keybuf_sentinel = KEYBUF_SENTINEL; - geliargs.keybuf = gelibuf; + geliargs.size = sizeof(geliargs); + explicit_bzero(gelipw, sizeof(gelipw)); + gelibuf = malloc(sizeof(struct keybuf) + + (GELI_MAX_KEYS * sizeof(struct keybuf_ent))); + geli_fill_keybuf(gelibuf); + geliargs.notapw = '\0'; + geliargs.keybuf_sentinel = KEYBUF_SENTINEL; + geliargs.keybuf = gelibuf; #endif - __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK), - MAKEBOOTDEV(dev_maj[dsk.type], dsk.part + 1, dsk.unit, 0xff), - KARGS_FLAGS_EXTARG, 0, 0, VTOP(&bootinfo) + __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK), + MAKEBOOTDEV(dev_maj[dsk.type], dsk.part + 1, dsk.unit, 0xff), + KARGS_FLAGS_EXTARG, 0, 0, VTOP(&bootinfo) #ifdef LOADER_GELI_SUPPORT - , geliargs + , geliargs #endif - ); + ); } static int parse_cmds(char *cmdstr, int *dskupdated) { - char *arg = cmdstr; - char *ep, *p, *q; - const char *cp; - unsigned int drv; - int c, i, j; + char *arg = cmdstr; + char *ep, *p, *q; + const char *cp; + unsigned int drv; + int c, i, j; - *dskupdated = 0; - while ((c = *arg++)) { - if (c == ' ' || c == '\t' || c == '\n') - continue; - for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++); - ep = p; - if (*p) - *p++ = 0; - if (c == '-') { - while ((c = *arg++)) { - if (c == 'P') { - if (*(uint8_t *)PTOV(0x496) & 0x10) { - cp = "yes"; - } else { - opts |= OPT_SET(RBX_DUAL) | OPT_SET(RBX_SERIAL); - cp = "no"; - } - printf("Keyboard: %s\n", cp); - continue; - } else if (c == 'S') { - j = 0; - while ((unsigned int)(i = *arg++ - '0') <= 9) - j = j * 10 + i; - if (j > 0 && i == -'0') { - comspeed = j; - break; - } - /* Fall through to error below ('S' not in optstr[]). */ + *dskupdated = 0; + while ((c = *arg++)) { + if (c == ' ' || c == '\t' || c == '\n') + continue; + for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++); + ep = p; + if (*p) + *p++ = 0; + if (c == '-') { + while ((c = *arg++)) { + if (c == 'P') { + if (*(uint8_t *)PTOV(0x496) & 0x10) { + cp = "yes"; + } else { + opts |= OPT_SET(RBX_DUAL) | + OPT_SET(RBX_SERIAL); + cp = "no"; + } + printf("Keyboard: %s\n", cp); + continue; + } else if (c == 'S') { + j = 0; + while ((unsigned int)(i = *arg++ - '0') + <= 9) + j = j * 10 + i; + if (j > 0 && i == -'0') { + comspeed = j; + break; + } + /* + * Fall through to error below + * ('S' not in optstr[]). + */ + } + for (i = 0; c != optstr[i]; i++) + if (i == NOPT - 1) + return -1; + opts ^= OPT_SET(flags[i]); + } + ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) : + OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD; + if (ioctrl & IO_SERIAL) { + if (sio_init(115200 / comspeed) != 0) + ioctrl &= ~IO_SERIAL; + } + } else { + for (q = arg--; *q && *q != '('; q++); + if (*q) { + drv = -1; + if (arg[1] == ':') { + drv = *arg - '0'; + if (drv > 9) + return (-1); + arg += 2; + } + if (q - arg != 2) + return -1; + for (i = 0; arg[0] != dev_nm[i][0] || + arg[1] != dev_nm[i][1]; i++) + if (i == NDEV - 1) + return -1; + dsk.type = i; + arg += 3; + dsk.unit = *arg - '0'; + if (arg[1] != 'p' || dsk.unit > 9) + return -1; + arg += 2; + dsk.part = *arg - '0'; + if (dsk.part < 1 || dsk.part > 9) + return -1; + arg++; + if (arg[0] != ')') + return -1; + arg++; + if (drv == -1) + drv = dsk.unit; + dsk.drive = (dsk.type <= TYPE_MAXHARD + ? DRV_HARD : 0) + drv; + *dskupdated = 1; + } + if ((i = ep - arg)) { + if ((size_t)i >= sizeof(kname)) + return -1; + memcpy(kname, arg, i + 1); + } } - for (i = 0; c != optstr[i]; i++) - if (i == NOPT - 1) - return -1; - opts ^= OPT_SET(flags[i]); - } - ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) : - OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD; - if (ioctrl & IO_SERIAL) { - if (sio_init(115200 / comspeed) != 0) - ioctrl &= ~IO_SERIAL; - } - } else { - for (q = arg--; *q && *q != '('; q++); - if (*q) { - drv = -1; - if (arg[1] == ':') { - drv = *arg - '0'; - if (drv > 9) - return (-1); - arg += 2; - } - if (q - arg != 2) - return -1; - for (i = 0; arg[0] != dev_nm[i][0] || - arg[1] != dev_nm[i][1]; i++) - if (i == NDEV - 1) - return -1; - dsk.type = i; - arg += 3; - dsk.unit = *arg - '0'; - if (arg[1] != 'p' || dsk.unit > 9) - return -1; - arg += 2; - dsk.part = *arg - '0'; - if (dsk.part < 1 || dsk.part > 9) - return -1; - arg++; - if (arg[0] != ')') - return -1; - arg++; - if (drv == -1) - drv = dsk.unit; - dsk.drive = (dsk.type <= TYPE_MAXHARD - ? DRV_HARD : 0) + drv; - *dskupdated = 1; - } - if ((i = ep - arg)) { - if ((size_t)i >= sizeof(kname)) - return -1; - memcpy(kname, arg, i + 1); - } + arg = p; } - arg = p; - } - return 0; + return 0; } static int