// Helper function to find, malloc_tmphigh, and copy a romfile. This // function adds a trailing zero to the malloc'd copy. void * romfile_loadfile(const char *name, int *psize) { struct romfile_s *file = romfile_find(name); if (!file) return NULL; int filesize = file->size; if (!filesize) return NULL; char *data = malloc_tmphigh(filesize+1); if (!data) { warn_noalloc(); return NULL; } dprintf(5, "Copying romfile '%s' (len %d)\n", name, filesize); int ret = file->copy(file, data, filesize); if (ret < 0) { free(data); return NULL; } if (psize) *psize = filesize; data[filesize] = '\0'; return data; }
// Main setup code. static void maininit(void) { // Initialize internal interfaces. interface_init(); // Setup platform devices. platform_hardware_setup(); // call a payload if (CONFIG_RUN_PAYLOAD) { dprintf(1, "Looking for payload %s\n", CONFIG_RUN_PAYLOAD_FILE); struct romfile_s *file = NULL; file = romfile_find( CONFIG_RUN_PAYLOAD_FILE ); if (!file) printf("Could not find payload\n"); else { struct cbfs_romfile_s *cfile; cfile = container_of(file, struct cbfs_romfile_s, file); cbfs_run_payload(cfile->fhdr); } } // Start hardware initialization (if optionrom threading) if (CONFIG_THREAD_OPTIONROMS) device_hardware_setup(); // Run vga option rom vgarom_setup(); // Do hardware initialization (if running synchronously) if (!CONFIG_THREAD_OPTIONROMS) { device_hardware_setup(); wait_threads(); } // Run option roms optionrom_setup(); // show system info before the F12 menu if (CONFIG_DISPLAY_SYSTEM_INFO) dprintf(1, "\nBuild date: %s\n", __DATE__); // Allow user to modify overall boot order. interactive_bootmenu(); wait_threads(); // Prepare for boot. prepareboot(); // Write protect bios memory. make_bios_readonly(); // Invoke int 19 to start boot process. startBoot(); }
static void romfile_loader_allocate(struct romfile_loader_entry_s *entry, struct romfile_loader_files *files) { struct zone_s *zone; struct romfile_loader_file *file = &files->files[files->nfiles]; void *data; int ret; unsigned alloc_align = le32_to_cpu(entry->alloc_align); if (alloc_align & (alloc_align - 1)) goto err; switch (entry->alloc_zone) { case ROMFILE_LOADER_ALLOC_ZONE_HIGH: zone = &ZoneHigh; break; case ROMFILE_LOADER_ALLOC_ZONE_FSEG: zone = &ZoneFSeg; break; default: goto err; } if (alloc_align < MALLOC_MIN_ALIGN) alloc_align = MALLOC_MIN_ALIGN; if (entry->alloc_file[ROMFILE_LOADER_FILESZ - 1]) goto err; file->file = romfile_find(entry->alloc_file); if (!file->file || !file->file->size) return; data = _malloc(zone, MALLOC_DEFAULT_HANDLE, file->file->size, alloc_align); if (!data) { warn_noalloc(); return; } ret = file->file->copy(file->file, data, file->file->size); if (ret != file->file->size) goto file_err; file->data = data; files->nfiles++; return; file_err: free(data); err: warn_internalerror(); }
// Attempt to load an integer from the given file - return 'defval' // if unsuccessful. u64 romfile_loadint(const char *name, u64 defval) { struct romfile_s *file = romfile_find(name); if (!file) return defval; int filesize = file->size; if (!filesize || filesize > sizeof(u64) || (filesize & (filesize-1))) // Doesn't look like a valid integer. return defval; u64 val = 0; int ret = file->copy(file, &val, sizeof(val)); if (ret < 0) return defval; return val; }
void enable_bootsplash(void) { if (!CONFIG_BOOTSPLASH) return; dprintf(3, "Checking for bootsplash\n"); u32 file = romfile_find("bootsplash.jpg"); if (!file) return; int filesize = romfile_size(file); u8 *picture = NULL; u8 *filedata = malloc_tmphigh(filesize); struct vesa_info *vesa_info = malloc_tmplow(sizeof(*vesa_info)); struct vesa_mode_info *mode_info = malloc_tmplow(sizeof(*mode_info)); struct jpeg_decdata *jpeg = jpeg_alloc(); if (!filedata || !jpeg || !vesa_info || !mode_info) { warn_noalloc(); goto done; } /* Check whether we have a VESA 2.0 compliant BIOS */ memset(vesa_info, 0, sizeof(struct vesa_info)); vesa_info->vesa_signature = VBE2_SIGNATURE; struct bregs br; memset(&br, 0, sizeof(br)); br.ax = 0x4f00; br.di = FLATPTR_TO_OFFSET(vesa_info); br.es = FLATPTR_TO_SEG(vesa_info); call16_int10(&br); if (vesa_info->vesa_signature != VESA_SIGNATURE) { dprintf(1,"No VBE2 found.\n"); goto done; } /* Print some debugging information about our card. */ char *vendor = SEGOFF_TO_FLATPTR(vesa_info->oem_vendor_name_ptr); char *product = SEGOFF_TO_FLATPTR(vesa_info->oem_product_name_ptr); dprintf(3, "VESA %d.%d\nVENDOR: %s\nPRODUCT: %s\n", vesa_info->vesa_version>>8, vesa_info->vesa_version&0xff, vendor, product); // Parse jpeg and get image size. dprintf(5, "Copying bootsplash.jpg\n"); romfile_copy(file, filedata, filesize); dprintf(5, "Decoding bootsplash.jpg\n"); int ret = jpeg_decode(jpeg, filedata); if (ret) { dprintf(1, "jpeg_decode failed with return code %d...\n", ret); goto done; } int width, height; jpeg_get_size(jpeg, &width, &height); // Try to find a graphics mode with the corresponding dimensions. int videomode = find_videomode(vesa_info, mode_info, width, height); if (videomode < 0) goto done; void *framebuffer = mode_info->phys_base_ptr; int depth = mode_info->bits_per_pixel; dprintf(3, "mode: %04x\n", videomode); dprintf(3, "framebuffer: %p\n", framebuffer); dprintf(3, "bytes per scanline: %d\n", mode_info->bytes_per_scanline); dprintf(3, "bits per pixel: %d\n", depth); // Allocate space for image and decompress it. int imagesize = width * height * (depth / 8); picture = malloc_tmphigh(imagesize); if (!picture) { warn_noalloc(); goto done; } dprintf(5, "Decompressing bootsplash.jpg\n"); ret = jpeg_show(jpeg, picture, width, height, depth); if (ret) { dprintf(1, "jpeg_show failed with return code %d...\n", ret); goto done; } /* Switch to graphics mode */ dprintf(5, "Switching to graphics mode\n"); memset(&br, 0, sizeof(br)); br.ax = 0x4f02; br.bx = (1 << 14) | videomode; call16_int10(&br); if (br.ax != 0x4f) { dprintf(1, "set_mode failed.\n"); goto done; } /* Show the picture */ dprintf(5, "Showing bootsplash.jpg\n"); iomemcpy(framebuffer, picture, imagesize); dprintf(5, "Bootsplash copy complete\n"); BootsplashActive = 1; done: free(filedata); free(picture); free(vesa_info); free(mode_info); free(jpeg); return; }
static int smbios_romfile_setup(void) { struct romfile_s *f_anchor = romfile_find("etc/smbios/smbios-anchor"); struct romfile_s *f_tables = romfile_find("etc/smbios/smbios-tables"); struct smbios_entry_point ep; struct smbios_type_0 *t0; u16 qtables_len, need_t0 = 1; u8 *qtables, *tables; if (!f_anchor || !f_tables || f_anchor->size != sizeof(ep)) return 0; f_anchor->copy(f_anchor, &ep, f_anchor->size); if (f_tables->size != ep.structure_table_length) return 0; qtables = malloc_tmphigh(f_tables->size); if (!qtables) { warn_noalloc(); return 0; } f_tables->copy(f_tables, qtables, f_tables->size); ep.structure_table_address = (u32)qtables; /* for smbios_next(), below */ /* did we get a type 0 structure ? */ for (t0 = smbios_next(&ep, NULL); t0; t0 = smbios_next(&ep, t0)) if (t0->header.type == 0) { need_t0 = 0; break; } qtables_len = ep.structure_table_length; if (need_t0) { /* common case: add our own type 0, with 3 strings and 4 '\0's */ u16 t0_len = sizeof(struct smbios_type_0) + strlen(BIOS_NAME) + strlen(VERSION) + strlen(BIOS_DATE) + 4; ep.structure_table_length += t0_len; if (t0_len > ep.max_structure_size) ep.max_structure_size = t0_len; ep.number_of_structures++; } /* allocate final blob and record its address in the entry point */ if (ep.structure_table_length > BUILD_MAX_SMBIOS_FSEG) tables = malloc_high(ep.structure_table_length); else tables = malloc_fseg(ep.structure_table_length); if (!tables) { warn_noalloc(); free(qtables); return 0; } ep.structure_table_address = (u32)tables; /* populate final blob */ if (need_t0) tables = smbios_new_type_0(tables, BIOS_NAME, VERSION, BIOS_DATE); memcpy(tables, qtables, qtables_len); free(qtables); /* finalize entry point */ ep.checksum -= checksum(&ep, 0x10); ep.intermediate_checksum -= checksum((void *)&ep + 0x10, ep.length - 0x10); copy_smbios(&ep); return 1; }