Port-bebox archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: booting with floppy



heinz%netbsd.org@localhost wrote:

 >   Boot: Loading in()
 >   1580436+1528 [94+85072+71240]=0x1a88e8
 >   start=0x3100
 > 
 >   panic: uvm_setpagesize: page size not a power of two
 >   Stopped in iaslotcf_locnames at   0x12ade8:     lwz r0, r1, 0x14,
 >   db> 
 >
 > But why would the page size not be a power of two? I hope, this
 > is not a bug of the cross compiler...

-current kernel of bebox may be bad...

Please try to use the following filter to fix length of bss section.
I think "1528" is too short.

sakamoto
--
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/exec_elf.h>
#include <machine/endian.h>

#if BYTE_ORDER == LITTLE_ENDIAN
unsigned long
_BE_long(val)
        unsigned long val;
{
        unsigned char *p = (unsigned char *)&val;
        return ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0));
}

unsigned short
_BE_short(val)
        unsigned short val;
{
        unsigned char *p = (unsigned char *)&val;
        return ((p[0] << 8) | (p[1] << 0));
}
#else
#define _BE_long(x) (x)
#define _BE_short(x) (x)
#endif

int
main(argc, argv)
        int argc;
        char *argv[];
{
        int i;
        int in_fd, out_fd;
        int bss_end = 0, sbss_end = 0;
        int p_memsz, p_memsz_offset;
        char *in_data;
        char *symtab;
        struct stat buf;
        Elf32_Ehdr *hdr;
        Elf32_Phdr *phdr;
        Elf32_Shdr *shdr;

        switch (argc) {
        case 3:
                if (stat(argv[1], &buf)) {
                        perror("stat");
                        exit(1);
                }
                if ((in_fd = open(argv[1], O_RDONLY)) < 0) {
                        fprintf(stderr, "Can't open '%s': %s\n",
                                argv[1], strerror(errno));
                        exit(2);
                }
                if ((in_data = (char *)mmap(NULL, buf.st_size, PROT_READ,
                    MAP_PRIVATE, in_fd, 0)) == MAP_FAILED) {
                        perror("mmap");
                        exit(1); 
                }

                if ((out_fd = open(argv[2], O_WRONLY|O_CREAT, 0644)) < 0) {
                        fprintf(stderr, "Can't open '%s': %s\n",
                                argv[2], strerror(errno));
                        exit(2);
                }
                break;

        default:
                fprintf(stderr, "usage: %s IN OUT\n", argv[0]);
                exit(1);
        }

        /*
         * ELF file operation
         */
        hdr = (Elf32_Ehdr *)in_data;
        if (bcmp(hdr->e_ident, ELFMAG, SELFMAG)) {
                fprintf(stderr, "input '%s' is not ELF32 format\n", argv[1]);
                exit(3);
        }
        if (_BE_short(hdr->e_machine) != EM_PPC) {
                fprintf(stderr, "input '%s' is not PowerPC exec binary\n",
                        argv[1]);
                exit(3);
        }

#ifdef DEBUG
        printf("e_entry= 0x%lx\n", _BE_long(hdr->e_entry));
        printf("e_phoff= 0x%lx\n", _BE_long(hdr->e_phoff));
        printf("e_shoff= 0x%lx\n", _BE_long(hdr->e_shoff));
        printf("e_flags= 0x%x\n", _BE_short(hdr->e_flags));
        printf("e_ehsize= 0x%x\n", _BE_short(hdr->e_ehsize));
        printf("e_phentsize= 0x%x\n", _BE_short(hdr->e_phentsize));
        printf("e_phnum= 0x%x\n", _BE_short(hdr->e_phnum));
        printf("e_shentsize= 0x%x\n", _BE_short(hdr->e_shentsize));
        printf("e_shnum= 0x%x\n", _BE_short(hdr->e_shnum));
        printf("e_shstrndx= 0x%x\n", _BE_short(hdr->e_shstrndx));
        printf("\n");
#endif

        shdr = (Elf32_Shdr *)(in_data + _BE_long(hdr->e_shoff) +
                sizeof (*shdr) * _BE_short(hdr->e_shstrndx));
        symtab = (char *)(in_data + _BE_long(shdr->sh_offset));

        for (i = 0; i < _BE_short(hdr->e_shnum); i++) {
                shdr = (Elf32_Shdr *)(in_data + _BE_long(hdr->e_shoff) +
                        sizeof (*shdr) * i);

#ifdef DEBUG
                printf("sh_name= 0x%lx(%s)\n", _BE_long(shdr->sh_name),
                        &symtab[_BE_long(shdr->sh_name)]);
                printf("sh_type= 0x%lx\n", _BE_long(shdr->sh_type));
                printf("sh_flags= 0x%lx\n", _BE_long(shdr->sh_flags));
                printf("sh_addr= 0x%lx\n", _BE_long(shdr->sh_addr));
                printf("sh_offset= 0x%lx\n", _BE_long(shdr->sh_offset));
                printf("sh_size= 0x%lx\n", _BE_long(shdr->sh_size));
                printf("sh_link= 0x%lx\n", _BE_long(shdr->sh_link));
                printf("sh_info= 0x%lx\n", _BE_long(shdr->sh_info));
                printf("sh_addralign= 0x%lx\n", _BE_long(shdr->sh_addralign));
                printf("sh_entsize= 0x%lx\n", _BE_long(shdr->sh_entsize));
                printf("\n");
#endif

                if (!strcmp(&symtab[_BE_long(shdr->sh_name)], ".sbss")) {
                        sbss_end = _BE_long(shdr->sh_addr) +
                                _BE_long(shdr->sh_size);
                }
                if (!strcmp(&symtab[_BE_long(shdr->sh_name)], ".bss")) {
                        bss_end = _BE_long(shdr->sh_addr) +
                                _BE_long(shdr->sh_size);
                }
        }

        for (i = 0; i < _BE_short(hdr->e_phnum); i++) {
                phdr = (Elf32_Phdr *)(in_data + _BE_long(hdr->e_phoff) +
                        sizeof (*phdr) * i);

#ifdef DEBUG
                printf("p_type= 0x%lx\n", _BE_long(phdr->p_type));
                printf("p_offset= 0x%lx\n", _BE_long(phdr->p_offset));
                printf("p_vaddr= 0x%lx\n", _BE_long(phdr->p_vaddr));
                printf("p_paddr= 0x%lx\n", _BE_long(phdr->p_paddr));
                printf("p_filesz= 0x%lx\n", _BE_long(phdr->p_filesz));
                printf("p_memsz= 0x%lx\n", _BE_long(phdr->p_memsz));
                printf("p_flags= 0x%lx\n", _BE_long(phdr->p_flags));
                printf("p_align= 0x%lx\n", _BE_long(phdr->p_align));
                printf("\n");
#endif

                if (_BE_long(phdr->p_filesz) < _BE_long(phdr->p_memsz)) {
                        p_memsz = _BE_long(_BE_long(phdr->p_memsz) +
                                bss_end - sbss_end);
                        p_memsz_offset = (int)&phdr->p_memsz - (int)in_data;
                }
        }

        if (write(out_fd, in_data, p_memsz_offset) < 0) {
                perror("write");
                exit(1);
        }
        if (write(out_fd, &p_memsz, sizeof (p_memsz)) < 0) {
                perror("write");
                exit(1);
        }
        if (write(out_fd, in_data + p_memsz_offset + sizeof (p_memsz),
            buf.st_size - p_memsz_offset - sizeof (p_memsz)) < 0) {
                perror("write");
                exit(1);
        }

        close(in_fd);
        close(out_fd);
        return 0;
}



Home | Main Index | Thread Index | Old Index