From: Paul Brook Date: Fri, 29 May 2009 23:52:44 +0000 (+0100) Subject: Use relative path for bios X-Git-Tag: 0.10.0-0sb10~1116 X-Git-Url: https://vcs.maemo.org/git/?p=qemu;a=commitdiff_plain;h=5cea8590eaa099be8087f363f80d0e6917382385 Use relative path for bios Look for bios and other support files relative to qemu binary, rather than a hardcoded prefix. Signed-off-by: Paul Brook --- diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c index e496c28..e683421 100644 --- a/hw/mips_jazz.c +++ b/hw/mips_jazz.c @@ -118,7 +118,7 @@ void mips_jazz_init (ram_addr_t ram_size, const char *cpu_model, enum jazz_model_e jazz_model) { - char buf[1024]; + char *filename; int bios_size, n; CPUState *env; qemu_irq *rc4030, *i8259; @@ -161,11 +161,17 @@ void mips_jazz_init (ram_addr_t ram_size, /* load the BIOS image. */ if (bios_name == NULL) bios_name = BIOS_FILENAME; - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); - bios_size = load_image_targphys(buf, 0xfff00000LL, MAGNUM_BIOS_SIZE); + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); + if (filename) { + bios_size = load_image_targphys(filename, 0xfff00000LL, + MAGNUM_BIOS_SIZE); + qemu_free(filename); + } else { + bios_size = -1; + } if (bios_size < 0 || bios_size > MAGNUM_BIOS_SIZE) { fprintf(stderr, "qemu: Could not load MIPS bios '%s'\n", - buf); + bios_name); exit(1); } diff --git a/hw/mips_malta.c b/hw/mips_malta.c index a300808..970da4e 100644 --- a/hw/mips_malta.c +++ b/hw/mips_malta.c @@ -758,7 +758,7 @@ void mips_malta_init (ram_addr_t ram_size, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { - char buf[1024]; + char *filename; ram_addr_t ram_offset; ram_addr_t bios_offset; target_long bios_size; @@ -846,12 +846,18 @@ void mips_malta_init (ram_addr_t ram_size, /* Load a BIOS image. */ if (bios_name == NULL) bios_name = BIOS_FILENAME; - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); - bios_size = load_image_targphys(buf, 0x1fc00000LL, BIOS_SIZE); + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); + if (filename) { + bios_size = load_image_targphys(filename, 0x1fc00000LL, + BIOS_SIZE); + qemu_free(filename); + } else { + bios_size = -1; + } if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename) { fprintf(stderr, "qemu: Could not load MIPS bios '%s', and no -kernel argument was specified\n", - buf); + bios_name); exit(1); } } diff --git a/hw/mips_mipssim.c b/hw/mips_mipssim.c index 1117db2..448dc02 100644 --- a/hw/mips_mipssim.c +++ b/hw/mips_mipssim.c @@ -107,7 +107,7 @@ mips_mipssim_init (ram_addr_t ram_size, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { - char buf[1024]; + char *filename; ram_addr_t ram_offset; ram_addr_t bios_offset; CPUState *env; @@ -140,13 +140,18 @@ mips_mipssim_init (ram_addr_t ram_size, /* Load a BIOS / boot exception handler image. */ if (bios_name == NULL) bios_name = BIOS_FILENAME; - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); - bios_size = load_image_targphys(buf, 0x1fc00000LL, BIOS_SIZE); + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); + if (filename) { + bios_size = load_image_targphys(filename, 0x1fc00000LL, BIOS_SIZE); + qemu_free(filename); + } else { + bios_size = -1; + } if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename) { /* Bail out if we have neither a kernel image nor boot vector code. */ fprintf(stderr, "qemu: Could not load MIPS bios '%s', and no -kernel argument was specified\n", - buf); + filename); exit(1); } else { /* We have a boot vector start address. */ diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c index ba8c7f6..71832d5 100644 --- a/hw/mips_r4k.c +++ b/hw/mips_r4k.c @@ -147,7 +147,7 @@ void mips_r4k_init (ram_addr_t ram_size, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { - char buf[1024]; + char *filename; ram_addr_t ram_offset; ram_addr_t bios_offset; int bios_size; @@ -196,14 +196,18 @@ void mips_r4k_init (ram_addr_t ram_size, run. */ if (bios_name == NULL) bios_name = BIOS_FILENAME; - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); - bios_size = get_image_size(buf); + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); + if (filename) { + bios_size = get_image_size(filename); + } else { + bios_size = -1; + } if ((bios_size > 0) && (bios_size <= BIOS_SIZE)) { bios_offset = qemu_ram_alloc(BIOS_SIZE); cpu_register_physical_memory(0x1fc00000, BIOS_SIZE, bios_offset | IO_MEM_ROM); - load_image_targphys(buf, 0x1fc00000, BIOS_SIZE); + load_image_targphys(filename, 0x1fc00000, BIOS_SIZE); } else if ((index = drive_get_index(IF_PFLASH, 0, 0)) > -1) { uint32_t mips_rom = 0x00400000; bios_offset = qemu_ram_alloc(mips_rom); @@ -216,7 +220,10 @@ void mips_r4k_init (ram_addr_t ram_size, else { /* not fatal */ fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n", - buf); + bios_name); + } + if (filename) { + qemu_free(filename); } if (kernel_filename) { diff --git a/hw/pc.c b/hw/pc.c index 66cc780..0934778 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -603,10 +603,10 @@ static void load_linux(target_phys_addr_t option_rom, uint32_t gpr[8]; uint16_t seg[6]; uint16_t real_seg; - int setup_size, kernel_size, initrd_size, cmdline_size; + int setup_size, kernel_size, initrd_size = 0, cmdline_size; uint32_t initrd_max; uint8_t header[1024]; - target_phys_addr_t real_addr, prot_addr, cmdline_addr, initrd_addr; + target_phys_addr_t real_addr, prot_addr, cmdline_addr, initrd_addr = 0; FILE *f, *fi; /* Align to 16 bytes as a paranoia measure */ @@ -805,14 +805,21 @@ static int load_option_rom(const char *oprom, target_phys_addr_t start, target_phys_addr_t end) { int size; - - size = get_image_size(oprom); - if (size > 0 && start + size > end) { - fprintf(stderr, "Not enough space to load option rom '%s'\n", - oprom); - exit(1); + char *filename; + + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, oprom); + if (filename) { + size = get_image_size(filename); + if (size > 0 && start + size > end) { + fprintf(stderr, "Not enough space to load option rom '%s'\n", + oprom); + exit(1); + } + size = load_image_targphys(filename, start, end - start); + qemu_free(filename); + } else { + size = -1; } - size = load_image_targphys(oprom, start, end - start); if (size < 0) { fprintf(stderr, "Could not load option rom '%s'\n", oprom); exit(1); @@ -830,7 +837,7 @@ static void pc_init1(ram_addr_t ram_size, const char *initrd_filename, int pci_enabled, const char *cpu_model) { - char buf[1024]; + char *filename; int ret, linux_boot, i; ram_addr_t ram_addr, bios_offset, option_rom_offset; ram_addr_t below_4g_mem_size, above_4g_mem_size = 0; @@ -913,19 +920,26 @@ static void pc_init1(ram_addr_t ram_size, /* BIOS load */ if (bios_name == NULL) bios_name = BIOS_FILENAME; - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); - bios_size = get_image_size(buf); + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); + if (filename) { + bios_size = get_image_size(filename); + } else { + bios_size = -1; + } if (bios_size <= 0 || (bios_size % 65536) != 0) { goto bios_error; } bios_offset = qemu_ram_alloc(bios_size); - ret = load_image(buf, qemu_get_ram_ptr(bios_offset)); + ret = load_image(filename, qemu_get_ram_ptr(bios_offset)); if (ret != bios_size) { bios_error: - fprintf(stderr, "qemu: could not load PC BIOS '%s'\n", buf); + fprintf(stderr, "qemu: could not load PC BIOS '%s'\n", bios_name); exit(1); } + if (filename) { + qemu_free(filename); + } /* map the last 128KB of the BIOS in ISA space */ isa_bios_size = bios_size; if (isa_bios_size > (128 * 1024)) @@ -941,14 +955,14 @@ static void pc_init1(ram_addr_t ram_size, cpu_register_physical_memory(0xc0000, 0x20000, option_rom_offset); if (using_vga) { + const char *vgabios_filename; /* VGA BIOS load */ if (cirrus_vga_enabled) { - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, - VGABIOS_CIRRUS_FILENAME); + vgabios_filename = VGABIOS_CIRRUS_FILENAME; } else { - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME); + vgabios_filename = VGABIOS_FILENAME; } - oprom_area_size = load_option_rom(buf, 0xc0000, 0xe0000); + oprom_area_size = load_option_rom(vgabios_filename, 0xc0000, 0xe0000); } /* Although video roms can grow larger than 0x8000, the area between * 0xc0000 - 0xc8000 is reserved for them. It means we won't be looking diff --git a/hw/ppc405_boards.c b/hw/ppc405_boards.c index a8f9a28..0dec131 100644 --- a/hw/ppc405_boards.c +++ b/hw/ppc405_boards.c @@ -175,7 +175,7 @@ static void ref405ep_init (ram_addr_t ram_size, const char *initrd_filename, const char *cpu_model) { - char buf[1024]; + char *filename; ppc4xx_bd_info_t bd; CPUPPCState *env; qemu_irq *pic; @@ -236,13 +236,19 @@ static void ref405ep_init (ram_addr_t ram_size, #ifdef DEBUG_BOARD_INIT printf("Load BIOS from file\n"); #endif + bios_offset = qemu_ram_alloc(BIOS_SIZE); if (bios_name == NULL) bios_name = BIOS_FILENAME; - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); - bios_offset = qemu_ram_alloc(BIOS_SIZE); - bios_size = load_image(buf, qemu_get_ram_ptr(bios_offset)); + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); + if (filename) { + bios_size = load_image(filename, qemu_get_ram_ptr(bios_offset)); + qemu_free(filename); + } else { + bios_size = -1; + } if (bios_size < 0 || bios_size > BIOS_SIZE) { - fprintf(stderr, "qemu: could not load PowerPC bios '%s'\n", buf); + fprintf(stderr, "qemu: could not load PowerPC bios '%s'\n", + bios_name); exit(1); } bios_size = (bios_size + 0xfff) & ~0xfff; @@ -493,7 +499,7 @@ static void taihu_405ep_init(ram_addr_t ram_size, const char *initrd_filename, const char *cpu_model) { - char buf[1024]; + char *filename; CPUPPCState *env; qemu_irq *pic; ram_addr_t bios_offset; @@ -548,10 +554,15 @@ static void taihu_405ep_init(ram_addr_t ram_size, if (bios_name == NULL) bios_name = BIOS_FILENAME; bios_offset = qemu_ram_alloc(BIOS_SIZE); - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); - bios_size = load_image(buf, qemu_get_ram_ptr(bios_offset)); + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); + if (filename) { + bios_size = load_image(filename, qemu_get_ram_ptr(bios_offset)); + } else { + bios_size = -1; + } if (bios_size < 0 || bios_size > BIOS_SIZE) { - fprintf(stderr, "qemu: could not load PowerPC bios '%s'\n", buf); + fprintf(stderr, "qemu: could not load PowerPC bios '%s'\n", + bios_name); exit(1); } bios_size = (bios_size + 0xfff) & ~0xfff; diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c index cbe7236..00aa2c7 100644 --- a/hw/ppc440_bamboo.c +++ b/hw/ppc440_bamboo.c @@ -34,20 +34,19 @@ static void *bamboo_load_device_tree(target_phys_addr_t addr, void *fdt = NULL; #ifdef HAVE_FDT uint32_t mem_reg_property[] = { 0, 0, ramsize }; - char *path; + char *filename; int fdt_size; - int pathlen; int ret; - pathlen = snprintf(NULL, 0, "%s/%s", bios_dir, BINARY_DEVICE_TREE_FILE) + 1; - path = qemu_malloc(pathlen); - - snprintf(path, pathlen, "%s/%s", bios_dir, BINARY_DEVICE_TREE_FILE); - - fdt = load_device_tree(path, &fdt_size); - free(path); - if (fdt == NULL) + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE); + if (!filename) { goto out; + } + fdt = load_device_tree(filename, &fdt_size); + qemu_free(filename); + if (fdt == NULL) { + goto out; + } /* Manipulate device tree in memory. */ diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c index 88ad99d..f0d167d 100644 --- a/hw/ppc_newworld.c +++ b/hw/ppc_newworld.c @@ -93,7 +93,7 @@ static void ppc_core99_init (ram_addr_t ram_size, const char *cpu_model) { CPUState *env = NULL, *envs[MAX_CPUS]; - char buf[1024]; + char *filename; qemu_irq *pic, **openpic_irqs; int unin_memory; int linux_boot, i; @@ -140,24 +140,35 @@ static void ppc_core99_init (ram_addr_t ram_size, bios_offset = qemu_ram_alloc(BIOS_SIZE); if (bios_name == NULL) bios_name = PROM_FILENAME; - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); cpu_register_physical_memory(PROM_ADDR, BIOS_SIZE, bios_offset | IO_MEM_ROM); /* Load OpenBIOS (ELF) */ - bios_size = load_elf(buf, 0, NULL, NULL, NULL); + if (filename) { + bios_size = load_elf(filename, 0, NULL, NULL, NULL); + qemu_free(filename); + } else { + bios_size = -1; + } if (bios_size < 0 || bios_size > BIOS_SIZE) { - hw_error("qemu: could not load PowerPC bios '%s'\n", buf); + hw_error("qemu: could not load PowerPC bios '%s'\n", bios_name); exit(1); } /* allocate and load VGA BIOS */ vga_bios_offset = qemu_ram_alloc(VGA_BIOS_SIZE); vga_bios_ptr = qemu_get_ram_ptr(vga_bios_offset); - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME); - vga_bios_size = load_image(buf, vga_bios_ptr + 8); + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, VGABIOS_FILENAME); + if (filename) { + vga_bios_size = load_image(filename, vga_bios_ptr + 8); + qemu_free(filename); + } else { + vga_bios_size = -1; + } if (vga_bios_size < 0) { /* if no bios is present, we can still work */ - fprintf(stderr, "qemu: warning: could not load VGA bios '%s'\n", buf); + fprintf(stderr, "qemu: warning: could not load VGA bios '%s'\n", + VGABIOS_FILENAME); vga_bios_size = 0; } else { /* set a specific header (XXX: find real Apple format for NDRV diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c index aeac6ae..b2c329b 100644 --- a/hw/ppc_oldworld.c +++ b/hw/ppc_oldworld.c @@ -122,7 +122,7 @@ static void ppc_heathrow_init (ram_addr_t ram_size, const char *cpu_model) { CPUState *env = NULL, *envs[MAX_CPUS]; - char buf[1024]; + char *filename; qemu_irq *pic, **heathrow_irqs; int linux_boot, i; ram_addr_t ram_offset, bios_offset, vga_bios_offset; @@ -173,24 +173,35 @@ static void ppc_heathrow_init (ram_addr_t ram_size, bios_offset = qemu_ram_alloc(BIOS_SIZE); if (bios_name == NULL) bios_name = PROM_FILENAME; - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); cpu_register_physical_memory(PROM_ADDR, BIOS_SIZE, bios_offset | IO_MEM_ROM); /* Load OpenBIOS (ELF) */ - bios_size = load_elf(buf, 0, NULL, NULL, NULL); + if (filename) { + bios_size = load_elf(filename, 0, NULL, NULL, NULL); + qemu_free(filename); + } else { + bios_size = -1; + } if (bios_size < 0 || bios_size > BIOS_SIZE) { - hw_error("qemu: could not load PowerPC bios '%s'\n", buf); + hw_error("qemu: could not load PowerPC bios '%s'\n", bios_name); exit(1); } /* allocate and load VGA BIOS */ vga_bios_offset = qemu_ram_alloc(VGA_BIOS_SIZE); vga_bios_ptr = qemu_get_ram_ptr(vga_bios_offset); - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME); - vga_bios_size = load_image(buf, vga_bios_ptr + 8); + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, VGABIOS_FILENAME); + if (filename) { + vga_bios_size = load_image(filename, vga_bios_ptr + 8); + qemu_free(filename); + } else { + vga_bios_size = -1; + } if (vga_bios_size < 0) { /* if no bios is present, we can still work */ - fprintf(stderr, "qemu: warning: could not load VGA bios '%s'\n", buf); + fprintf(stderr, "qemu: warning: could not load VGA bios '%s'\n", + VGABIOS_FILENAME); vga_bios_size = 0; } else { /* set a specific header (XXX: find real Apple format for NDRV diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c index 4832107..2d308f3 100644 --- a/hw/ppc_prep.c +++ b/hw/ppc_prep.c @@ -539,7 +539,7 @@ static void ppc_prep_init (ram_addr_t ram_size, const char *cpu_model) { CPUState *env = NULL, *envs[MAX_CPUS]; - char buf[1024]; + char *filename; nvram_t nvram; m48t59_t *m48t59; int PPC_io_memory; @@ -585,18 +585,25 @@ static void ppc_prep_init (ram_addr_t ram_size, bios_offset = qemu_ram_alloc(BIOS_SIZE); if (bios_name == NULL) bios_name = BIOS_FILENAME; - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); - bios_size = get_image_size(buf); + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); + if (filename) { + bios_size = get_image_size(filename); + } else { + bios_size = -1; + } if (bios_size > 0 && bios_size <= BIOS_SIZE) { target_phys_addr_t bios_addr; bios_size = (bios_size + 0xfff) & ~0xfff; bios_addr = (uint32_t)(-bios_size); cpu_register_physical_memory(bios_addr, bios_size, bios_offset | IO_MEM_ROM); - bios_size = load_image_targphys(buf, bios_addr, bios_size); + bios_size = load_image_targphys(filename, bios_addr, bios_size); } if (bios_size < 0 || bios_size > BIOS_SIZE) { - hw_error("qemu: could not load PPC PREP bios '%s'\n", buf); + hw_error("qemu: could not load PPC PREP bios '%s'\n", bios_name); + } + if (filename) { + qemu_free(filename); } if (env->nip < 0xFFF80000 && bios_size < 0x00100000) { hw_error("PowerPC 601 / 620 / 970 need a 1MB BIOS\n"); diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c index 632fb05..d9ed36c 100644 --- a/hw/ppce500_mpc8544ds.c +++ b/hw/ppce500_mpc8544ds.c @@ -79,20 +79,19 @@ static void *mpc8544_load_device_tree(target_phys_addr_t addr, void *fdt = NULL; #ifdef HAVE_FDT uint32_t mem_reg_property[] = {0, ramsize}; - char *path; + char *filename; int fdt_size; - int pathlen; int ret; - pathlen = snprintf(NULL, 0, "%s/%s", bios_dir, BINARY_DEVICE_TREE_FILE) + 1; - path = qemu_malloc(pathlen); - - snprintf(path, pathlen, "%s/%s", bios_dir, BINARY_DEVICE_TREE_FILE); - - fdt = load_device_tree(path, &fdt_size); - qemu_free(path); - if (fdt == NULL) + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE); + if (!filename) { goto out; + } + fdt = load_device_tree(filename, &fdt_size); + qemu_free(filename); + if (fdt == NULL) { + goto out; + } /* Manipulate device tree in memory. */ ret = qemu_devtree_setprop(fdt, "/memory", "reg", mem_reg_property, diff --git a/hw/sun4m.c b/hw/sun4m.c index 4ba9e89..ef9fa5e 100644 --- a/hw/sun4m.c +++ b/hw/sun4m.c @@ -400,7 +400,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size, ram_addr_t ram_offset, prom_offset, idreg_offset; unsigned long kernel_size; int ret; - char buf[1024]; + char *filename; BlockDriverState *fd[MAX_FD]; int drive_index; void *fw_cfg; @@ -451,13 +451,20 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size, if (bios_name == NULL) bios_name = PROM_FILENAME; - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); - ret = load_elf(buf, hwdef->slavio_base - PROM_VADDR, NULL, NULL, NULL); - if (ret < 0 || ret > PROM_SIZE_MAX) - ret = load_image_targphys(buf, hwdef->slavio_base, PROM_SIZE_MAX); + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); + if (filename) { + ret = load_elf(filename, hwdef->slavio_base - PROM_VADDR, + NULL, NULL, NULL); + if (ret < 0 || ret > PROM_SIZE_MAX) + ret = load_image_targphys(filename, hwdef->slavio_base, + PROM_SIZE_MAX); + qemu_free(filename); + } else { + ret = -1; + } if (ret < 0 || ret > PROM_SIZE_MAX) { fprintf(stderr, "qemu: could not load prom '%s'\n", - buf); + bios_name); exit(1); } @@ -1185,7 +1192,7 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size, ram_addr_t ram_offset, prom_offset; unsigned long kernel_size; int ret; - char buf[1024]; + char *filename; void *fw_cfg; /* init CPUs */ @@ -1233,13 +1240,20 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size, if (bios_name == NULL) bios_name = PROM_FILENAME; - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); - ret = load_elf(buf, hwdef->slavio_base - PROM_VADDR, NULL, NULL, NULL); - if (ret < 0 || ret > PROM_SIZE_MAX) - ret = load_image_targphys(buf, hwdef->slavio_base, PROM_SIZE_MAX); + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); + if (filename) { + ret = load_elf(filename, hwdef->slavio_base - PROM_VADDR, + NULL, NULL, NULL); + if (ret < 0 || ret > PROM_SIZE_MAX) + ret = load_image_targphys(filename, hwdef->slavio_base, + PROM_SIZE_MAX); + qemu_free(filename); + } else { + ret = -1; + } if (ret < 0 || ret > PROM_SIZE_MAX) { fprintf(stderr, "qemu: could not load prom '%s'\n", - buf); + bios_name); exit(1); } @@ -1399,7 +1413,7 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size, ram_addr_t ram_offset, prom_offset; unsigned long kernel_size; int ret; - char buf[1024]; + char *filename; BlockDriverState *fd[MAX_FD]; int drive_index; void *fw_cfg; @@ -1440,13 +1454,20 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size, if (bios_name == NULL) bios_name = PROM_FILENAME; - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); - ret = load_elf(buf, hwdef->slavio_base - PROM_VADDR, NULL, NULL, NULL); - if (ret < 0 || ret > PROM_SIZE_MAX) - ret = load_image_targphys(buf, hwdef->slavio_base, PROM_SIZE_MAX); + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); + if (filename) { + ret = load_elf(filename, hwdef->slavio_base - PROM_VADDR, + NULL, NULL, NULL); + if (ret < 0 || ret > PROM_SIZE_MAX) + ret = load_image_targphys(filename, hwdef->slavio_base, + PROM_SIZE_MAX); + qemu_free(filename); + } else { + ret = -1; + } if (ret < 0 || ret > PROM_SIZE_MAX) { fprintf(stderr, "qemu: could not load prom '%s'\n", - buf); + filename); exit(1); } diff --git a/hw/sun4u.c b/hw/sun4u.c index f5bb732..7d02018 100644 --- a/hw/sun4u.c +++ b/hw/sun4u.c @@ -333,7 +333,7 @@ static void sun4uv_init(ram_addr_t RAM_size, const struct hwdef *hwdef) { CPUState *env; - char buf[1024]; + char *filename; m48t59_t *nvram; int ret, linux_boot; unsigned int i; @@ -392,17 +392,23 @@ static void sun4uv_init(ram_addr_t RAM_size, if (bios_name == NULL) bios_name = PROM_FILENAME; - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); - ret = load_elf(buf, hwdef->prom_addr - PROM_VADDR, NULL, NULL, NULL); - if (ret < 0) { - ret = load_image_targphys(buf, hwdef->prom_addr, - (PROM_SIZE_MAX + TARGET_PAGE_SIZE) & - TARGET_PAGE_MASK); + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); + if (filename) { + ret = load_elf(filename, hwdef->prom_addr - PROM_VADDR, + NULL, NULL, NULL); if (ret < 0) { - fprintf(stderr, "qemu: could not load prom '%s'\n", - buf); - exit(1); + ret = load_image_targphys(filename, hwdef->prom_addr, + (PROM_SIZE_MAX + TARGET_PAGE_SIZE) & + TARGET_PAGE_MASK); } + qemu_free(filename); + } else { + ret = -1; + } + if (ret < 0) { + fprintf(stderr, "qemu: could not load prom '%s'\n", + bios_name); + exit(1); } kernel_size = 0; diff --git a/keymaps.c b/keymaps.c index 3b86dc1..23db4a0 100644 --- a/keymaps.c +++ b/keymaps.c @@ -64,20 +64,20 @@ static kbd_layout_t *parse_keyboard_layout(const name2keysym_t *table, kbd_layout_t * k) { FILE *f; - char file_name[1024]; + char * filename; char line[1024]; int len; - snprintf(file_name, sizeof(file_name), - "%s/keymaps/%s", bios_dir, language); + filename = qemu_find_file(QEMU_FILE_TYPE_KEYMAP, language); if (!k) k = qemu_mallocz(sizeof(kbd_layout_t)); - if (!(f = fopen(file_name, "r"))) { + if (!(filename && (f = fopen(filename, "r")))) { fprintf(stderr, - "Could not read keymap file: '%s'\n", file_name); + "Could not read keymap file: '%s'\n", language); return 0; } + qemu_free(filename); for(;;) { if (fgets(line, 1024, f) == NULL) break; diff --git a/sysemu.h b/sysemu.h index 92501ed..658aeec 100644 --- a/sysemu.h +++ b/sysemu.h @@ -10,7 +10,10 @@ /* vl.c */ extern const char *bios_name; -extern const char *bios_dir; + +#define QEMU_FILE_TYPE_BIOS 0 +#define QEMU_FILE_TYPE_KEYMAP 1 +char *qemu_find_file(int type, const char *name); extern int vm_running; extern const char *qemu_name; diff --git a/vl.c b/vl.c index f8c0d00..fcf8532 100644 --- a/vl.c +++ b/vl.c @@ -33,6 +33,7 @@ #include "config-host.h" #ifndef _WIN32 +#include #include #include #include @@ -191,7 +192,7 @@ int main(int argc, char **argv) /* XXX: use a two level table to limit memory usage */ #define MAX_IOPORTS 65536 -const char *bios_dir = CONFIG_QEMU_SHAREDIR; +static const char *data_dir; const char *bios_name = NULL; static void *ioport_opaque[MAX_IOPORTS]; static IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS]; @@ -4795,6 +4796,128 @@ static void termsig_setup(void) #endif +#ifdef _WIN32 +/* Look for support files in the same directory as the executable. */ +static char *find_datadir(const char *argv0) +{ + char *p; + char buf[MAX_PATH]; + DWORD len; + + len = GetModuleFileName(NULL, buf, sizeof(buf) - 1); + if (len == 0) { + return len; + } + + buf[len] = 0; + p = buf + len - 1; + while (p != buf && *p != '\\') + p--; + *p = 0; + if (access(buf, R_OK) == 0) { + return qemu_strdup(buf); + } + return NULL; +} +#else /* !_WIN32 */ + +/* Find a likely location for support files using the location of the binary. + For installed binaries this will be "$bindir/../share/qemu". When + running from the build tree this will be "$bindir/../pc-bios". */ +#define SHARE_SUFFIX "/share/qemu" +#define BUILD_SUFFIX "/pc-bios" +static char *find_datadir(const char *argv0) +{ + char *dir; + char *p = NULL; + char *res; +#ifdef PATH_MAX + char buf[PATH_MAX]; +#endif + +#if defined(__linux__) + { + int len; + len = readlink("/proc/self/exe", buf, sizeof(buf) - 1); + if (len > 0) { + buf[len] = 0; + p = buf; + } + } +#elif defined(__FreeBSD__) + { + int len; + len = readlink("/proc/curproc/file", buf, sizeof(buf) - 1); + if (len > 0) { + buf[len] = 0; + p = buf; + } + } +#endif + /* If we don't have any way of figuring out the actual executable + location then try argv[0]. */ + if (!p) { +#ifdef PATH_MAX + p = buf; +#endif + p = realpath(argv0, p); + if (!p) { + return NULL; + } + } + dir = dirname(p); + dir = dirname(dir); + + res = qemu_mallocz(strlen(dir) + + MAX(strlen(SHARE_SUFFIX), strlen(BUILD_SUFFIX)) + 1); + sprintf(res, "%s%s", dir, SHARE_SUFFIX); + if (access(res, R_OK)) { + sprintf(res, "%s%s", dir, BUILD_SUFFIX); + if (access(res, R_OK)) { + qemu_free(res); + res = NULL; + } + } +#ifndef PATH_MAX + free(p); +#endif + return res; +} +#undef SHARE_SUFFIX +#undef BUILD_SUFFIX +#endif + +char *qemu_find_file(int type, const char *name) +{ + int len; + const char *subdir; + char *buf; + + /* If name contains path separators then try it as a straight path. */ + if ((strchr(name, '/') || strchr(name, '\\')) + && access(name, R_OK) == 0) { + return strdup(name); + } + switch (type) { + case QEMU_FILE_TYPE_BIOS: + subdir = ""; + break; + case QEMU_FILE_TYPE_KEYMAP: + subdir = "keymaps/"; + break; + default: + abort(); + } + len = strlen(data_dir) + strlen(name) + strlen(subdir) + 2; + buf = qemu_mallocz(len); + sprintf(buf, "%s/%s%s", data_dir, subdir, name); + if (access(buf, R_OK)) { + qemu_free(buf); + return NULL; + } + return buf; +} + int main(int argc, char **argv, char **envp) { const char *gdbstub_dev = NULL; @@ -5234,7 +5357,7 @@ int main(int argc, char **argv, char **envp) gdbstub_dev = optarg; break; case QEMU_OPTION_L: - bios_dir = optarg; + data_dir = optarg; break; case QEMU_OPTION_bios: bios_name = optarg; @@ -5560,6 +5683,16 @@ int main(int argc, char **argv, char **envp) } } + /* If no data_dir is specified then try to find it relative to the + executable path. */ + if (!data_dir) { + data_dir = find_datadir(argv[0]); + } + /* If all else fails use the install patch specified when building. */ + if (!data_dir) { + data_dir = CONFIG_QEMU_SHAREDIR; + } + #if defined(CONFIG_KVM) && defined(CONFIG_KQEMU) if (kvm_allowed && kqemu_allowed) { fprintf(stderr, @@ -5705,19 +5838,24 @@ int main(int argc, char **argv, char **envp) for (i = 0; i < nb_nics && i < 4; i++) { const char *model = nd_table[i].model; char buf[1024]; + char *filename; if (net_boot & (1 << i)) { if (model == NULL) model = "ne2k_pci"; - snprintf(buf, sizeof(buf), "%s/pxe-%s.bin", bios_dir, model); - if (get_image_size(buf) > 0) { + snprintf(buf, sizeof(buf), "pxe-%s.bin", model); + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, buf); + if (filename && get_image_size(filename) > 0) { if (nb_option_roms >= MAX_OPTION_ROMS) { fprintf(stderr, "Too many option ROMs\n"); exit(1); } - option_rom[nb_option_roms] = strdup(buf); + option_rom[nb_option_roms] = qemu_strdup(buf); nb_option_roms++; netroms++; } + if (filename) { + qemu_free(filename); + } } } if (netroms == 0) {