Exemple #1
0
int
main(int ac, char **av)
{
    int fd;
    int i, nsect;
    int aoutsz;
    struct external_filehdr fhdr;
    AOUTHDR aout;
    struct external_scnhdr shdr;

    if (ac != 2) {
    fprintf(stderr, "Usage: hack-coff coff-file\n");
    exit(1);
    }
    if ((fd = open(av[1], 2)) == -1) {
    perror(av[2]);
    exit(1);
    }
    if (read(fd, &fhdr, sizeof(fhdr)) != sizeof(fhdr))
    goto readerr;
    i = get_16be(fhdr.f_magic);
    if (i != U802TOCMAGIC && i != U802WRMAGIC && i != U802ROMAGIC) {
    fprintf(stderr, "%s: not an xcoff file\n", av[1]);
    exit(1);
    }
    aoutsz = get_16be(fhdr.f_opthdr);
    if (read(fd, &aout, aoutsz) != aoutsz)
    goto readerr;
    nsect = get_16be(fhdr.f_nscns);
    for (i = 0; i < nsect; ++i) {
    if (read(fd, &shdr, sizeof(shdr)) != sizeof(shdr))
        goto readerr;
    if (strcmp(shdr.s_name, ".text") == 0) {
        put_16be(aout.o_snentry, i+1);
        put_16be(aout.o_sntext, i+1);
    } else if (strcmp(shdr.s_name, ".data") == 0) {
        put_16be(aout.o_sndata, i+1);
    } else if (strcmp(shdr.s_name, ".bss") == 0) {
        put_16be(aout.o_snbss, i+1);
    }
    }
    put_16be(aout.magic, AOUT_MAGIC);
    if (lseek(fd, (long) sizeof(struct external_filehdr), 0) == -1
    || write(fd, &aout, aoutsz) != aoutsz) {
    fprintf(stderr, "%s: write error\n", av[1]);
    exit(1);
    }
    close(fd);
    exit(0);

readerr:
    fprintf(stderr, "%s: read error or file too short\n", av[1]);
    exit(1);
}
Exemple #2
0
coffboot(int a1, int a2, void *prom)
{
    void *options;
    unsigned loadbase;
    struct external_filehdr *eh;
    struct external_scnhdr *sp;
    struct external_scnhdr *isect, *rsect;
    int ns, oh, i;
    unsigned sa, len;
    void *dst;
    unsigned char *im;
    unsigned initrd_start, initrd_size;

    printf("coffboot starting\n");
    options = finddevice("/options");
    if (options == (void *) -1)
	exit();
    if (getprop(options, "load-base", &loadbase, sizeof(loadbase))
	!= sizeof(loadbase)) {
	printf("error getting load-base\n");
	exit();
    }
    setup_bats(RAM_START);

    loadbase += RAM_START;
    eh = (struct external_filehdr *) loadbase;
    ns = get_16be(eh->f_nscns);
    oh = get_16be(eh->f_opthdr);

    sp = (struct external_scnhdr *) (loadbase + sizeof(struct external_filehdr) + oh);
    isect = rsect = NULL;
    for (i = 0; i < ns; ++i, ++sp) {
	if (strcmp(sp->s_name, "image") == 0)
	    isect = sp;
	else if (strcmp(sp->s_name, "initrd") == 0)
	    rsect = sp;
    }
    if (isect == NULL) {
	printf("image section not found\n");
	exit();
    }

    if (rsect != NULL && (initrd_size = get_32be(rsect->s_size)) != 0) {
	initrd_start = (RAM_END - initrd_size) & ~0xFFF;
	a1 = initrd_start;
	a2 = initrd_size;
	printf("initial ramdisk at %x (%u bytes)\n",
	       initrd_start, initrd_size);
	memcpy((char *) initrd_start,
	       (char *) (loadbase + get_32be(rsect->s_scnptr)),
	       initrd_size);
	end_avail = (char *) initrd_start;
    } else {
	end_avail = (char *) RAM_END;
    }
	
    im = (unsigned char *)(loadbase + get_32be(isect->s_scnptr));
    len = get_32be(isect->s_size);
    dst = (void *) PROG_START;

    if (im[0] == 0x1f && im[1] == 0x8b) {
	void *cp = (void *) RAM_FREE;
	avail_ram = (void *) (RAM_FREE + ((len + 7) & -8));
	memcpy(cp, im, len);
	printf("gunzipping... ");
	gunzip(dst, 0x400000, cp, &len);
	printf("done\n");

    } else {
	memmove(dst, im, len);
    }

    flush_cache(dst, len);

    sa = (unsigned long)dst;
    printf("start address = 0x%x\n", sa);

#if 0
    pause();
#endif
    {
	    struct bi_record *rec;
	    
	    rec = (struct bi_record *)_ALIGN((unsigned long)dst+len+(1<<20)-1,(1<<20));
	    
	    rec->tag = BI_FIRST;
	    rec->size = sizeof(struct bi_record);
	    rec = (struct bi_record *)((unsigned long)rec + rec->size);

	    rec->tag = BI_BOOTLOADER_ID;
	    sprintf( (char *)rec->data, "coffboot");
	    rec->size = sizeof(struct bi_record) + strlen("coffboot") + 1;
	    rec = (struct bi_record *)((unsigned long)rec + rec->size);
	    
	    rec->tag = BI_MACHTYPE;
	    rec->data[0] = _MACH_Pmac;
	    rec->data[1] = 1;
	    rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
	    rec = (struct bi_record *)((unsigned long)rec + rec->size);
	    
	    rec->tag = BI_LAST;
	    rec->size = sizeof(struct bi_record);
	    rec = (struct bi_record *)((unsigned long)rec + rec->size);
    }
    
    (*(void (*)())sa)(a1, a2, prom);

    printf("returned?\n");

    pause();
}