Subject: Re: booting with floppy
To: None <heinz@netbsd.org>
From: Kazuki Sakamoto <sakamoto@splhack.org>
List: port-bebox
Date: 01/23/2001 10:25:12
heinz@netbsd.org 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;
}