addr_t map_string(const char *string) { if (!string) return 0; else return map_data(string, strlen(string) + 1, 1, 0); }
void mboot_make_memmap(void) { int i, nmap; struct AddrRangeDesc *ard; uint32_t lowmem, highmem; uint32_t highrsvd; /* Always report DOS memory as "lowmem", this may be overly conservative (e.g. if we're dropping PXE), but it should be *safe*... */ nmap = mboot_scan_memory(&ard, &lowmem); highmem = 0x100000; highrsvd = 0xfff00000; again: for (i = 0; i < nmap; i++) { uint64_t start, end; start = ard[i].BaseAddr; end = start + ard[i].Length; if (end < start) end = ~0ULL; if (start & 0xffffffff00000000ULL) continue; /* Not interested in 64-bit memory */ if (start < highmem) start = highmem; if (end <= start) continue; if (ard[i].Type == 1 && start == highmem) { highmem = end; goto again; } else if (ard[i].Type != 1 && start < highrsvd) highrsvd = start; } if (highmem > highrsvd) highmem = highrsvd; mbinfo.mem_lower = lowmem >> 10; mbinfo.mem_upper = (highmem - 0x100000) >> 10; mbinfo.flags |= MB_INFO_MEMORY; /* The spec says this address should be +4, but Grub disagrees */ mbinfo.mmap_addr = map_data(ard, nmap * sizeof *ard, 4, false); if (mbinfo.mmap_addr) { mbinfo.mmap_length = nmap * sizeof *ard; mbinfo.flags |= MB_INFO_MEM_MAP; } }
void mboot_solaris_dhcp_hack(void) { void *dhcpdata; size_t dhcplen; if (syslinux_derivative_info()->c.filesystem != SYSLINUX_FS_PXELINUX) return; if (!pxe_get_cached_info(PXENV_PACKET_TYPE_DHCP_ACK, &dhcpdata, &dhcplen)) { mbinfo.drives_addr = map_data(dhcpdata, dhcplen, 4, 0); if (mbinfo.drives_addr) { mbinfo.drives_length = dhcplen; mbinfo.boot_device = 0x20ffffff; mbinfo.flags = (mbinfo.flags & ~MB_INFO_DRIVE_INFO) | MB_INFO_BOOTDEV; } } }
int main(int argc, char** argv) { if (argc < 5) { printf("Usage: %s <image> <database> <x> <y>\n", argv[0]); return 1; } int bounds[4]; unsigned int x, y; x = atoi(argv[3]); y = atoi(argv[4]); img_t* img = img_new(argv[1]); map_t* map = map_data(argv[2]); img_t* edge = img_edge(img, 3*6*6); img_fill_gaps(edge, 3); img_find_bounds(edge, x, y, 50, 50, bounds); img_t* sub = img_sub(img, bounds); //img_flood_fill(edge, x, y); img_to_bmp(edge, "/tmp/edge"); img_to_bmp(sub, "/tmp/sub"); return 0; }
OSErr AddToMasterFile(INTEGER from_file_rn, INTEGER master_file_rn) { OSErr err; mapping_t mapping; INTEGER type_num, type_num_max; ResType type; Handle h; Str255 name; BOOLEAN save_resload; err = setup_map (from_file_rn, master_file_rn, &mapping); if (err == noEErr) { type_num_max = CountTypesRN (from_file_rn); save_resload = ResLoad; SetResLoad (false); for (type_num = 1; type_num <= type_num_max; ++type_num) { GetIndTypeRN (from_file_rn, &type, type_num); res_num_max = CountResourcesRN (from_file_rn, type); for (res_num = 1; res_num <= res_num_max; ++res_num) { h = GetIndResourceRN (from_file_rn, type, res_num); GetResInfo (h, &id, &t, name); if (map_id (&id, from_file_rn, master_file_rn, &mapping)) { LoadResource(h); DetachResource(h); map_data (h, &mapping); AddResourceRN (master_file_rn, h, type, id, name); } } } SetResLoad (save_resload); } }
int main(int argc, char *argv[]) { char fn_src[500+1], fn_dst[500+1], *opt_src, *opt_dst; int fd, ft_src, ft_dst, i, stride, bytes, flag, m; GBM_ERR rc; GBMFT gbmft; GBM gbm; GBMRGB gbmrgb[0x100]; byte *data; char *map = "none"; byte remap[0x100]; double gam = 2.1, shelf = 0.0; /*...scommand line arguments:8:*/ for ( i = 1; i < argc; i++ ) { if ( argv[i][0] != '-' ) break; switch ( argv[i][1] ) { case 'm': if ( ++i == argc ) fatal("expected map argument"); map = argv[i]; break; case 'g': if ( ++i == argc ) usage(); gam = get_opt_double(argv[i], "gam"); if ( gam < 0.1 || gam > 10.0 ) fatal("only gammas in the range 0.1 to 10.0 are sensible"); break; case 's': if ( ++i == argc ) usage(); shelf = get_opt_double(argv[i], "shelf"); break; default: usage(); break; } } /*...e*/ /*...sdeduce mapping and bits per pixel etc\46\:8:*/ { int j; for ( j = 0; j < N_MAPINFOS; j++ ) if ( same(map, mapinfos[j].name, strlen(map) + 1) ) break; if ( j == N_MAPINFOS ) fatal("unrecognised mapping %s", map); m = mapinfos[j].m; } /*...e*/ if ( i == argc ) usage(); strcpy(fn_src, argv[i++]); strcpy(fn_dst, ( i == argc ) ? fn_src : argv[i++]); if ( i < argc ) usage(); if ( (opt_src = strchr(fn_src, ',')) != NULL ) *opt_src++ = '\0'; else opt_src = ""; if ( (opt_dst = strchr(fn_dst, ',')) != NULL ) *opt_dst++ = '\0'; else opt_dst = ""; gbm_init(); if ( gbm_guess_filetype(fn_src, &ft_src) != GBM_ERR_OK ) fatal("can't guess bitmap file format for %s", fn_src); if ( gbm_guess_filetype(fn_dst, &ft_dst) != GBM_ERR_OK ) fatal("can't guess bitmap file format for %s", fn_dst); if ( (fd = open(fn_src, O_RDONLY | O_BINARY)) == -1 ) fatal("can't open %s", fn_src); if ( (rc = gbm_read_header(fn_src, fd, ft_src, &gbm, opt_src)) != GBM_ERR_OK ) { close(fd); fatal("can't read header of %s: %s", fn_src, gbm_err(rc)); } gbm_query_filetype(ft_dst, &gbmft); switch ( gbm.bpp ) { case 24: flag = GBM_FT_W24; break; case 8: flag = GBM_FT_W8; break; case 4: flag = GBM_FT_W4; break; case 1: flag = GBM_FT_W1; break; } if ( (gbmft.flags & flag) == 0 ) { close(fd); fatal("output bitmap format %s does not support writing %d bpp data", gbmft.short_name, gbm.bpp); } if ( (rc = gbm_read_palette(fd, ft_src, &gbm, gbmrgb)) != GBM_ERR_OK ) { close(fd); fatal("can't read palette of %s: %s", fn_src, gbm_err(rc)); } stride = ( ((gbm.w * gbm.bpp + 31)/32) * 4 ); bytes = stride * gbm.h; if ( (data = malloc(bytes)) == NULL ) { close(fd); fatal("out of memory allocating %d bytes for bitmap", bytes); } if ( (rc = gbm_read_data(fd, ft_src, &gbm, data)) != GBM_ERR_OK ) { close(fd); fatal("can't read bitmap data of %s: %s", fn_src, gbm_err(rc)); } close(fd); map_compute(m, remap, gam, shelf); if ( gbm.bpp == 24 ) map_data(data, gbm.w, gbm.h, remap); else map_palette(gbmrgb, 1 << gbm.bpp, remap); if ( (fd = open(fn_dst, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, S_IREAD | S_IWRITE)) == -1 ) fatal("can't create %s", fn_dst); if ( (rc = gbm_write(fn_dst, fd, ft_dst, &gbm, gbmrgb, data, opt_dst)) != GBM_ERR_OK ) { close(fd); remove(fn_dst); fatal("can't write %s: %s", fn_dst, gbm_err(rc)); } close(fd); free(data); gbm_deinit(); return 0; }
struct multiboot_header *map_image(void *ptr, size_t len) { struct multiboot_header *mbh; int mbh_len; char *cptr = ptr; Elf32_Ehdr *eh = ptr; Elf32_Phdr *ph; Elf32_Shdr *sh; unsigned int i, mbh_offset; uint32_t bad_flags; /* * Search for the multiboot header... */ mbh_len = 0; for (mbh_offset = 0; mbh_offset < MULTIBOOT_SEARCH; mbh_offset += 4) { mbh = (struct multiboot_header *)((char *)ptr + mbh_offset); if (mbh->magic != MULTIBOOT_MAGIC) continue; if (mbh->magic + mbh->flags + mbh->checksum) continue; if (mbh->flags & MULTIBOOT_VIDEO_MODE) mbh_len = 48; else if (mbh->flags & MULTIBOOT_AOUT_KLUDGE) mbh_len = 32; else mbh_len = 12; if (mbh_offset + mbh_len > len) mbh_len = 0; /* Invalid... */ else break; /* Found something... */ } if (mbh_len) { bad_flags = mbh->flags & MULTIBOOT_UNSUPPORTED; if (bad_flags) { printf("Unsupported Multiboot flags set: %#x\n", bad_flags); return NULL; } } if (len < sizeof(Elf32_Ehdr) || memcmp(eh->e_ident, "\x7f" "ELF\1\1\1", 6) || (eh->e_machine != EM_386 && eh->e_machine != EM_486 && eh->e_machine != EM_X86_64) || eh->e_version != EV_CURRENT || eh->e_ehsize < sizeof(Elf32_Ehdr) || eh->e_ehsize >= len || eh->e_phentsize < sizeof(Elf32_Phdr) || !eh->e_phnum || eh->e_phoff + eh->e_phentsize * eh->e_phnum > len) eh = NULL; /* No valid ELF header found */ /* Is this a Solaris kernel? */ if (!set.solaris && eh && kernel_is_solaris(eh)) opt.solaris = true; /* * Note: the Multiboot Specification implies that AOUT_KLUDGE should * have precedence over the ELF header. However, Grub disagrees, and * Grub is "the reference bootloader" for the Multiboot Specification. * This is insane, since it makes the AOUT_KLUDGE bit functionally * useless, but at least Solaris apparently depends on this behavior. */ if (eh && !(opt.aout && mbh_len && (mbh->flags & MULTIBOOT_AOUT_KLUDGE))) { regs.eip = eh->e_entry; /* Can be overridden further down... */ ph = (Elf32_Phdr *) (cptr + eh->e_phoff); for (i = 0; i < eh->e_phnum; i++) { if (ph->p_type == PT_LOAD || ph->p_type == PT_PHDR) { /* * This loads at p_paddr, which matches Grub. However, if * e_entry falls within the p_vaddr range of this PHDR, then * adjust it to match the p_paddr range... this is how Grub * behaves, so it's by definition correct (it doesn't have to * make sense...) */ addr_t addr = ph->p_paddr; addr_t msize = ph->p_memsz; addr_t dsize = min(msize, ph->p_filesz); if (eh->e_entry >= ph->p_vaddr && eh->e_entry < ph->p_vaddr + msize) regs.eip = eh->e_entry + (ph->p_paddr - ph->p_vaddr); dprintf("Segment at 0x%08x data 0x%08x len 0x%08x\n", addr, dsize, msize); if (syslinux_memmap_type(amap, addr, msize) != SMT_FREE) { printf ("Memory segment at 0x%08x (len 0x%08x) is unavailable\n", addr, msize); return NULL; /* Memory region unavailable */ } /* Mark this region as allocated in the available map */ if (syslinux_add_memmap(&amap, addr, msize, SMT_ALLOC)) { error("Overlapping segments found in ELF header\n"); return NULL; } if (ph->p_filesz) { /* Data present region. Create a move entry for it. */ if (syslinux_add_movelist (&ml, addr, (addr_t) cptr + ph->p_offset, dsize)) { error("Failed to map PHDR data\n"); return NULL; } } if (msize > dsize) { /* Zero-filled region. Mark as a zero region in the memory map. */ if (syslinux_add_memmap (&mmap, addr + dsize, msize - dsize, SMT_ZERO)) { error("Failed to map PHDR zero region\n"); return NULL; } } if (addr + msize > mboot_high_water_mark) mboot_high_water_mark = addr + msize; } else { /* Ignore this program header */ } ph = (Elf32_Phdr *) ((char *)ph + eh->e_phentsize); } /* Load the ELF symbol table */ if (eh->e_shoff) { addr_t addr, len; sh = (Elf32_Shdr *) ((char *)eh + eh->e_shoff); len = eh->e_shentsize * eh->e_shnum; /* * Align this, but don't pad -- in general this means a bunch of * smaller sections gets packed into a single page. */ addr = map_data(sh, len, 4096, MAP_HIGH | MAP_NOPAD); if (!addr) { error("Failed to map symbol table\n"); return NULL; } mbinfo.flags |= MB_INFO_ELF_SHDR; mbinfo.syms.e.addr = addr; mbinfo.syms.e.num = eh->e_shnum; mbinfo.syms.e.size = eh->e_shentsize; mbinfo.syms.e.shndx = eh->e_shstrndx; for (i = 0; i < eh->e_shnum; i++) { addr_t align; if (!sh[i].sh_size) continue; /* Empty section */ if (sh[i].sh_flags & SHF_ALLOC) continue; /* SHF_ALLOC sections should have PHDRs */ align = sh[i].sh_addralign ? sh[i].sh_addralign : 0; addr = map_data((char *)ptr + sh[i].sh_offset, sh[i].sh_size, align, MAP_HIGH); if (!addr) { error("Failed to map symbol section\n"); return NULL; } sh[i].sh_addr = addr; } } } else if (mbh_len && (mbh->flags & MULTIBOOT_AOUT_KLUDGE)) { /* * a.out kludge thing... */ char *data_ptr; addr_t data_len, bss_len; addr_t bss_addr; regs.eip = mbh->entry_addr; data_ptr = (char *)mbh - (mbh->header_addr - mbh->load_addr); if (mbh->load_end_addr) data_len = mbh->load_end_addr - mbh->load_addr; else data_len = len - mbh_offset + (mbh->header_addr - mbh->load_addr); bss_addr = mbh->load_addr + data_len; if (mbh->bss_end_addr) bss_len = mbh->bss_end_addr - mbh->load_end_addr; else bss_len = 0; if (syslinux_memmap_type(amap, mbh->load_addr, data_len + bss_len) != SMT_FREE) { printf("Memory segment at 0x%08x (len 0x%08x) is unavailable\n", mbh->load_addr, data_len + bss_len); return NULL; /* Memory region unavailable */ } if (syslinux_add_memmap(&amap, mbh->load_addr, data_len + bss_len, SMT_ALLOC)) { error("Failed to claim a.out address space!\n"); return NULL; } if (data_len) if (syslinux_add_movelist(&ml, mbh->load_addr, (addr_t) data_ptr, data_len)) { error("Failed to map a.out data\n"); return NULL; } if (bss_len) if (syslinux_add_memmap (&mmap, bss_addr, bss_len, SMT_ZERO)) { error("Failed to map a.out bss\n"); return NULL; } if (bss_addr + bss_len > mboot_high_water_mark) mboot_high_water_mark = bss_addr + bss_len; } else { error ("Invalid Multiboot image: neither ELF header nor a.out kludge found\n"); return NULL; } return mbh; }
void set_graphics_mode(const struct multiboot_header *mbh, struct multiboot_info *mbi) { com32sys_t rm; uint16_t mode, bestmode, *mode_ptr; struct vesa_general_info *gi; struct vesa_mode_info *mi; int pxf, bestpxf; int wantx, wanty; int err, besterr; bool better; addr_t viaddr; /* Only do this if requested by the OS image */ if (!(mbh->flags & MULTIBOOT_VIDEO_MODE) || mbh->mode_type != 0) return; gi = lmalloc(sizeof *gi); if (!gi) return; mi = lmalloc(sizeof *mi); if (!mi) goto out; memset(&rm, 0, sizeof rm); memset(gi, 0, sizeof *gi); gi->signature = VBE2_MAGIC; /* Get VBE2 extended data */ rm.eax.w[0] = 0x4F00; /* Get SVGA general information */ rm.edi.w[0] = OFFS(gi); rm.es = SEG(gi); __intcall(0x10, &rm, &rm); if (rm.eax.w[0] != 0x004F) goto out; /* Function call failed */ if (gi->signature != VESA_MAGIC) goto out; /* No magic */ if (gi->version < 0x0102) goto out; /* VESA 1.2+ required */ memcpy(&vesa_info.gi, gi, sizeof *gi); /* Search for a suitable mode with a suitable color and memory model... */ mode_ptr = GET_PTR(gi->video_mode_ptr); bestmode = 0; bestpxf = 0; wantx = mbh->width ? mbh->width : 0xffff; wanty = mbh->height ? mbh->height : 0xffff; besterr = wantx + wanty; while ((mode = *mode_ptr++) != 0xFFFF) { mode &= 0x1FF; /* The rest are attributes of sorts */ memset(&rm, 0, sizeof rm); memset(mi, 0, sizeof *mi); rm.eax.w[0] = 0x4F01; /* Get SVGA mode information */ rm.ecx.w[0] = mode; rm.edi.w[0] = OFFS(mi); rm.es = SEG(mi); __intcall(0x10, &rm, &rm); /* Must be a supported mode */ if (rm.eax.w[0] != 0x004f) continue; /* Must be an LFB color graphics mode supported by the hardware. The bits tested are: 7 - linear frame buffer 4 - graphics mode 3 - color mode 1 - mode information available (mandatory in VBE 1.2+) 0 - mode supported by hardware */ if ((mi->mode_attr & 0x009b) != 0x009b) continue; /* We don't support multibank (interlaced memory) modes */ /* * Note: The Bochs VESA BIOS (vbe.c 1.58 2006/08/19) violates the * specification which states that banks == 1 for unbanked modes; * fortunately it does report bank_size == 0 for those. */ if (mi->banks > 1 && mi->bank_size) continue; /* Must either be a packed-pixel mode or a direct color mode (depending on VESA version ); must be a supported pixel format */ if (mi->bpp == 32 && (mi->memory_layout == 4 || (mi->memory_layout == 6 && mi->rpos == 16 && mi->gpos == 8 && mi->bpos == 0))) pxf = 32; else if (mi->bpp == 24 && (mi->memory_layout == 4 || (mi->memory_layout == 6 && mi->rpos == 16 && mi->gpos == 8 && mi->bpos == 0))) pxf = 24; else if (mi->bpp == 16 && (mi->memory_layout == 4 || (mi->memory_layout == 6 && mi->rpos == 11 && mi->gpos == 5 && mi->bpos == 0))) pxf = 16; else if (mi->bpp == 15 && (mi->memory_layout == 4 || (mi->memory_layout == 6 && mi->rpos == 10 && mi->gpos == 5 && mi->bpos == 0))) pxf = 15; else continue; better = false; err = abs(mi->h_res - wantx) + abs(mi->v_res - wanty); #define IS_GOOD(mi, bestx, besty) \ ((mi)->h_res >= (bestx) && (mi)->v_res >= (besty)) if (!bestpxf) better = true; else if (!IS_GOOD(&vesa_info.mi, wantx, wanty) && IS_GOOD(mi, wantx, wanty)) /* This matches criteria, which the previous one didn't */ better = true; else if (IS_GOOD(&vesa_info.mi, wantx, wanty) && !IS_GOOD(mi, wantx, wanty)) /* This doesn't match criteria, and the previous one did */ better = false; else if (err < besterr) better = true; else if (err == besterr && (pxf == (int)mbh->depth || pxf > bestpxf)) better = true; if (better) { bestmode = mode; bestpxf = pxf; memcpy(&vesa_info.mi, mi, sizeof *mi); } } if (!bestpxf) goto out; /* No mode found */ mi = &vesa_info.mi; mode = bestmode; /* Now set video mode */ memset(&rm, 0, sizeof rm); rm.eax.w[0] = 0x4F02; /* Set SVGA video mode */ mode |= 0x4000; /* Request linear framebuffer */ rm.ebx.w[0] = mode; __intcall(0x10, &rm, &rm); if (rm.eax.w[0] != 0x004F) goto out; /* Failed to set mode */ mbi->flags |= MB_INFO_VIDEO_INFO; mbi->vbe_mode = mode; viaddr = map_data(&vesa_info, sizeof vesa_info, 4, 0); mbi->vbe_control_info = viaddr + offsetof(struct vesa_info, gi); mbi->vbe_mode_info = viaddr + offsetof(struct vesa_info, mi); /* Get the VBE 2.x PM entry point if supported */ rm.eax.w[0] = 0x4F0A; rm.ebx.w[0] = 0; __intcall(0x10, &rm, &rm); if (rm.eax.w[0] == 0x004F) { mbi->vbe_interface_seg = rm.es; mbi->vbe_interface_off = rm.edi.w[0]; mbi->vbe_interface_len = rm.ecx.w[0]; } /* In theory this should be: * * UsingVga = (mi->mode_attr & 4) ? 0x0007 : 0x000f; * * However, that would assume all systems that claim to handle text * output in VESA modes actually do that... */ graphics_using_vga(0x0F, vesa_info.mi.h_res, vesa_info.mi.v_res); out: lfree(mi); lfree(gi); }