示例#1
0
文件: linux_load.c 项目: 3a9LL/panda
/* Load the first part the file and check if it's Linux */
static uint32_t load_linux_header(struct linux_header *hdr)
{
    int load_high;
    uint32_t kern_addr;

    if (lfile_read(hdr, sizeof *hdr) != sizeof *hdr) {
	debug("Can't read Linux header\n");
	return 0;
    }
    if (hdr->boot_sector_magic != 0xaa55) {
	debug("Not a Linux kernel image\n");
	return 0;
    }

    /* Linux is found. Print some information */
    if (memcmp(hdr->header_magic, "HdrS", 4) != 0) {
	/* This may be floppy disk image or something.
	 * Perform a simple (incomplete) sanity check. */
	if (hdr->setup_sects >= 16
		|| file_size() - (hdr->setup_sects<<9) >= 512<<10) {
	    debug("This looks like a bootdisk image but not like Linux...\n");
	    return 0;
	}

	printf("Possible very old Linux");
	/* This kernel does not even have a protocol version.
	 * Force the value. */
	hdr->protocol_version = 0; /* pre-2.00 */
    } else
	printf("Found Linux");
    if (hdr->protocol_version >= 0x200 && hdr->kver_addr) {
	char kver[256];
	file_seek(hdr->kver_addr + 0x200);
	if (lfile_read(kver, sizeof kver) != 0) {
	    kver[255] = 0;
	    printf(" version %s", kver);
	}
    }
    debug(" (protocol %#x)", hdr->protocol_version);
    load_high = 0;
    if (hdr->protocol_version >= 0x200) {
	debug(" (loadflags %#x)", hdr->loadflags);
	load_high = hdr->loadflags & 1;
    }
    if (load_high) {
	printf(" bzImage");
	kern_addr = 0x100000;
    } else {
	printf(" zImage or Image");
	kern_addr = 0x1000;
    }
    printf(".\n");

    return kern_addr;
}
示例#2
0
文件: linux_load.c 项目: 3a9LL/panda
/* Load 32-bit part of kernel */
static int load_linux_kernel(struct linux_header *hdr, uint32_t kern_addr)
{
    uint32_t kern_offset, kern_size;

    if (hdr->setup_sects == 0)
	hdr->setup_sects = 4;
    kern_offset = (hdr->setup_sects + 1) * 512;
    file_seek(kern_offset);
    kern_size = file_size() - kern_offset;
    debug("offset=%#x addr=%#x size=%#x\n", kern_offset, kern_addr, kern_size);

#if 0
    if (using_devsize) {
	printf("Attempt to load up to end of device as kernel; "
		"specify the image size\n");
	return 0;
    }
#endif

    printf("Loading kernel... ");
    if (lfile_read(phys_to_virt(kern_addr), kern_size) != kern_size) {
	printf("Can't read kernel\n");
	return 0;
    }
    printf("ok\n");

    return kern_size;
}
示例#3
0
文件: elfload.c 项目: tycho/openbios
static unsigned long process_image_notes(Elf_phdr *phdr, int phnum,
                                         unsigned short *sum_ptr,
                                         unsigned int offset)
{
    int i;
    char *buf = NULL;
    int retval = 0;
    unsigned long addr, end;
    Elf_Nhdr *nhdr;
    const char *name;
    void *desc;

    for (i = 0; i < phnum; i++) {
	if (phdr[i].p_type != PT_NOTE)
	    continue;
	buf = malloc(phdr[i].p_filesz);
	file_seek(offset + phdr[i].p_offset);
	if ((uint64_t)lfile_read(buf, phdr[i].p_filesz) != phdr[i].p_filesz) {
	    printf("Can't read note segment\n");
	    goto out;
	}
	addr = (unsigned long) buf;
	end = addr + phdr[i].p_filesz;
	while (addr < end) {
	    nhdr = (Elf_Nhdr *) addr;
	    addr += sizeof(Elf_Nhdr);
	    name = (const char *) addr;
	    addr += (nhdr->n_namesz+3) & ~3;
	    desc = (void *) addr;
	    addr += (nhdr->n_descsz+3) & ~3;

	    if (nhdr->n_namesz==sizeof(ELF_NOTE_BOOT)
		    && memcmp(name, ELF_NOTE_BOOT, sizeof(ELF_NOTE_BOOT))==0) {
		if (nhdr->n_type == EIN_PROGRAM_NAME) {
		    image_name = calloc(1, nhdr->n_descsz + 1);
		    memcpy(image_name, desc, nhdr->n_descsz);
		}
		if (nhdr->n_type == EIN_PROGRAM_VERSION) {
		    image_version = calloc(1, nhdr->n_descsz + 1);
		    memcpy(image_version, desc, nhdr->n_descsz);
		}
		if (nhdr->n_type == EIN_PROGRAM_CHECKSUM) {
		    *sum_ptr = *(unsigned short *) desc;
		    debug("Image checksum: %#04x\n", *sum_ptr);
		    /* Where in the file */
		    retval = phdr[i].p_offset
			+ (unsigned long) desc - (unsigned long) buf;
		}
	    }
	}
    }
out:
    file_close();
    if (buf)
	free(buf);
    return retval;
}
示例#4
0
int forth_load(const char *filename)
{
    char magic[2];
    unsigned long forthsize;
    int retval = -1;

    if (!file_open(filename))
	goto out;

    if (lfile_read(magic, 2) != 2) {
	debug("Can't read magic header\n");
	retval = LOADER_NOT_SUPPORT;
	goto out;
    }

    if (magic[0] != '\\' || magic[1] != ' ') {
	debug("No forth source image\n");
	retval = LOADER_NOT_SUPPORT;
	goto out;
    }

    forthsize = file_size();

    forthtext = malloc(forthsize+1);
    file_seek(0);

    printk("Loading forth source ...");
    if ((unsigned long)lfile_read(forthtext, forthsize) != forthsize) {
	printk("Can't read forth text\n");
	goto out;
    }
    forthtext[forthsize]=0;
    printk("ok\n");

    PUSH ( (ucell)forthtext );
    PUSH ( (ucell)forthsize );
    fword("eval2");
    retval=0;

out:
    //if (forthtext)
    //	free(forthtext);
    return retval;
}
示例#5
0
文件: elfload.c 项目: tycho/openbios
static int load_segments(Elf_phdr *phdr, int phnum,
                         unsigned long checksum_offset,
                         unsigned int offset)
{
    unsigned long bytes;
    //unsigned int start_time, time;
    int i;

    bytes = 0;
    // start_time = currticks();
    for (i = 0; i < phnum; i++) {
	if (phdr[i].p_type != PT_LOAD)
	    continue;
	debug("segment %d addr:%#llx file:%#llx mem:%#llx ",
              i, addr_fixup(phdr[i].p_paddr), phdr[i].p_filesz, phdr[i].p_memsz);
	file_seek(offset + phdr[i].p_offset);
	debug("loading... ");
	if ((uint64_t)lfile_read(phys_to_virt(addr_fixup(phdr[i].p_paddr)), phdr[i].p_filesz)
		!= phdr[i].p_filesz) {
	    printf("Can't read program segment %d\n", i);
	    return 0;
	}
	bytes += phdr[i].p_filesz;
	debug("clearing... ");
	memset(phys_to_virt(addr_fixup(phdr[i].p_paddr) + phdr[i].p_filesz), 0,
		phdr[i].p_memsz - phdr[i].p_filesz);
	if (phdr[i].p_offset <= checksum_offset
		&& phdr[i].p_offset + phdr[i].p_filesz >= checksum_offset+2) {
	    debug("clearing checksum... ");
	    memset(phys_to_virt(addr_fixup(phdr[i].p_paddr) + checksum_offset
			- phdr[i].p_offset), 0, 2);
	}
	debug("ok\n");

    }
    // time = currticks() - start_time;
    //debug("Loaded %lu bytes in %ums (%luKB/s)\n", bytes, time,
    //	    time? bytes/time : 0);
    debug("Loaded %lu bytes \n", bytes);

    return 1;
}
示例#6
0
文件: elfload.c 项目: tycho/openbios
int elf_load(struct sys_info *info, const char *filename, const char *cmdline)
{
    Elf_ehdr ehdr;
    Elf_phdr *phdr = NULL;
    unsigned long phdr_size;
    unsigned long checksum_offset;
    unsigned short checksum = 0;
    Elf_Bhdr *boot_notes = NULL;
    int retval = -1;
    int image_retval;

    image_name = image_version = NULL;

    if (!file_open(filename))
	goto out;

    if (lfile_read(&ehdr, sizeof ehdr) != sizeof ehdr) {
	debug("Can't read ELF header\n");
	retval = LOADER_NOT_SUPPORT;
	goto out;
    }

    if (ehdr.e_ident[EI_MAG0] != ELFMAG0
	    || ehdr.e_ident[EI_MAG1] != ELFMAG1
	    || ehdr.e_ident[EI_MAG2] != ELFMAG2
	    || ehdr.e_ident[EI_MAG3] != ELFMAG3
	    || ehdr.e_ident[EI_CLASS] != ARCH_ELF_CLASS
	    || ehdr.e_ident[EI_DATA] != ARCH_ELF_DATA
	    || ehdr.e_ident[EI_VERSION] != EV_CURRENT
	    || ehdr.e_type != ET_EXEC
	    || !ARCH_ELF_MACHINE_OK(ehdr.e_machine)
	    || ehdr.e_version != EV_CURRENT
	    || ehdr.e_phentsize != sizeof(Elf_phdr)) {
	debug("Not a bootable ELF image\n");
	retval = LOADER_NOT_SUPPORT;
	goto out;
    }

    phdr_size = ehdr.e_phnum * sizeof *phdr;
    phdr = malloc(phdr_size);
    file_seek(ehdr.e_phoff);
    if (lfile_read(phdr, phdr_size) != phdr_size) {
	printk("Can't read program header\n");
	goto out;
    }

    if (!check_mem_ranges(info, phdr, ehdr.e_phnum))
	goto out;

    checksum_offset = process_image_notes(phdr, ehdr.e_phnum, &checksum);

    printk("Loading %s", image_name ? image_name : "image");
    if (image_version)
	printk(" version %s", image_version);
    printk("...\n");

    if (!load_segments(phdr, ehdr.e_phnum, checksum_offset))
	goto out;

    if (checksum_offset) {
	if (!verify_image(&ehdr, phdr, ehdr.e_phnum, checksum))
	    goto out;
    }

    boot_notes = build_boot_notes(info, cmdline);

    //debug("current time: %lu\n", currticks());

    debug("entry point is %#x\n", ehdr.e_entry);
    printk("Jumping to entry point...\n");
    image_retval = start_elf(ehdr.e_entry & ADDRMASK, virt_to_phys(boot_notes));

    // console_init(); FIXME
    printk("Image returned with return value %#x\n", image_retval);
    retval = 0;

out:
    if (phdr)
	free(phdr);
    if (boot_notes)
	free(boot_notes);
    if (image_name)
	free(image_name);
    if (image_version)
	free(image_version);
    return retval;
}
示例#7
0
文件: linux_load.c 项目: 3a9LL/panda
static int load_initrd(struct linux_header *hdr, struct sys_info *info,
	uint32_t kern_end, struct linux_params *params, const char *initrd_file)
{
    uint32_t max;
    uint32_t start, end, size;
    uint64_t forced;
    extern char _start[], _end[];

    if (!file_open(initrd_file)) {
	printf("Can't open initrd: %s\n", initrd_file);
	return -1;
    }

#if 0
    if (using_devsize) {
	printf("Attempt to load up to end of device as initrd; "
		"specify the image size\n");
	return -1;
    }
#endif

    size = file_size();


    /* Find out the kernel's restriction on how high the initrd can be
     * placed */
    if (hdr->protocol_version >= 0x203)
	max = hdr->initrd_addr_max;
    else
	max = 0x38000000; /* Hardcoded value for older kernels */

    /* FILO itself is at the top of RAM. (relocated)
     * So, try putting initrd just below us. */
    end = virt_to_phys(_start);
    if (end > max)
	end = max;

    /* If "mem=" option is given, we have to put the initrd within
     * the specified range. */
    if (forced_memsize) {
	forced = forced_memsize;
	if (forced > max)
	    forced = max;
	/* If the "mem=" is lower, it's easy */
	if (forced <= end)
	    end = forced;
	else {
	    /* Otherwise, see if we can put it above us */
	    if (virt_to_phys(_end) + size <= forced)
		end = forced; /* Ok */
	}
    }

    start = end - size;
    start &= ~0xfff; /* page align */
    end = start + size;

    debug("start=%#x end=%#x\n", start, end);

    if (start < kern_end) {
	printf("Initrd is too big to fit in memory\n");
	return -1;
    }

    printf("Loading initrd... ");
    if (lfile_read(phys_to_virt(start), size) != size) {
	printf("Can't read initrd\n");
	return -1;
    }
    printf("ok\n");

    params->initrd_start = start;
    params->initrd_size = size;

    return 0;
}
示例#8
0
文件: elfload.c 项目: tycho/openbios
int elf_load(struct sys_info *info, const char *filename, const char *cmdline)
{
    Elf_ehdr ehdr;
    Elf_phdr *phdr = NULL;
    unsigned long phdr_size;
    unsigned long checksum_offset;
    unsigned short checksum = 0;
    Elf_Bhdr *boot_notes = NULL;
    int retval = -1;
    int image_retval;
    unsigned int offset;

    image_name = image_version = NULL;

    if (!file_open(filename))
	goto out;

    for (offset = 0; offset < 16 * 512; offset += 512) {
        if ((size_t)lfile_read(&ehdr, sizeof ehdr) != sizeof ehdr) {
            debug("Can't read ELF header\n");
            retval = LOADER_NOT_SUPPORT;
            goto out;
        }

        if (ehdr.e_ident[EI_MAG0] == ELFMAG0)
            break;

        file_seek(offset);
    }

    if (ehdr.e_ident[EI_MAG0] != ELFMAG0
	    || ehdr.e_ident[EI_MAG1] != ELFMAG1
	    || ehdr.e_ident[EI_MAG2] != ELFMAG2
	    || ehdr.e_ident[EI_MAG3] != ELFMAG3
	    || ehdr.e_ident[EI_CLASS] != ARCH_ELF_CLASS
	    || ehdr.e_ident[EI_DATA] != ARCH_ELF_DATA
	    || ehdr.e_ident[EI_VERSION] != EV_CURRENT
	    || ehdr.e_type != ET_EXEC
	    || !ARCH_ELF_MACHINE_OK(ehdr.e_machine)
	    || ehdr.e_version != EV_CURRENT
	    || ehdr.e_phentsize != sizeof(Elf_phdr)) {
	debug("Not a bootable ELF image\n");
	retval = LOADER_NOT_SUPPORT;
	goto out;
    }

    phdr_size = ehdr.e_phnum * sizeof *phdr;
    phdr = malloc(phdr_size);
    file_seek(offset + ehdr.e_phoff);
    if ((unsigned long)lfile_read(phdr, phdr_size) != phdr_size) {
	printf("Can't read program header\n");
	goto out;
    }

    if (!check_mem_ranges(info, phdr, ehdr.e_phnum))
	goto out;

    checksum_offset = process_image_notes(phdr, ehdr.e_phnum, &checksum, offset);

    printf("Loading %s", image_name ? image_name : "image");
    if (image_version)
	printf(" version %s", image_version);
    printf("...\n");

    if (!load_segments(phdr, ehdr.e_phnum, checksum_offset, offset))
	goto out;

    if (checksum_offset) {
	if (!verify_image(&ehdr, phdr, ehdr.e_phnum, checksum))
	    goto out;
    }

    boot_notes = build_boot_notes(info, cmdline);

    //debug("current time: %lu\n", currticks());

    debug("entry point is %#llx\n", addr_fixup(ehdr.e_entry));
    printf("Jumping to entry point...\n");

#if 0
    {
        extern unsigned int qemu_mem_size;
        extern char boot_device;
        void *init_openprom(unsigned long memsize, const char *cmdline, char boot_device);

        int (*entry)(const void *romvec, int p2, int p3, int p4, int p5);
        const void *romvec;

        romvec = init_openprom(qemu_mem_size, cmdline, boot_device);
        entry = (void *) addr_fixup(ehdr.e_entry);
        image_retval = entry(romvec, 0, 0, 0, 0);
    }
#else
    image_retval = start_elf(addr_fixup(ehdr.e_entry), virt_to_phys(boot_notes));
#endif

    // console_init(); FIXME
    printf("Image returned with return value %#x\n", image_retval);
    retval = 0;

out:
    file_close();
    if (phdr)
	free(phdr);
    if (boot_notes)
	free(boot_notes);
    if (image_name)
	free(image_name);
    if (image_version)
	free(image_version);
    return retval;
}