From e7da798e38b08574611096048247c7959fad1adb Mon Sep 17 00:00:00 2001 From: garbled Date: Thu, 20 Dec 2007 22:59:59 +0000 Subject: [PATCH] Add bebox mkbootimage stuff to the unified mkbootimage. It should work in theory, assuming: a) I didn't mess up b) The original code in bebox/stand actually works --- .../powerpc/stand/mkbootimage/bebox_bootrec.h | 173 ++++++++++++ sys/arch/powerpc/stand/mkbootimage/magic.h | 5 +- .../powerpc/stand/mkbootimage/mkbootimage.c | 250 +++++++++++++++++- sys/arch/powerpc/stand/mkbootimage/pef.h | 96 +++++++ 4 files changed, 521 insertions(+), 3 deletions(-) create mode 100644 sys/arch/powerpc/stand/mkbootimage/bebox_bootrec.h create mode 100644 sys/arch/powerpc/stand/mkbootimage/pef.h diff --git a/sys/arch/powerpc/stand/mkbootimage/bebox_bootrec.h b/sys/arch/powerpc/stand/mkbootimage/bebox_bootrec.h new file mode 100644 index 000000000000..3b3aae3e023c --- /dev/null +++ b/sys/arch/powerpc/stand/mkbootimage/bebox_bootrec.h @@ -0,0 +1,173 @@ +/* $NetBSD: bebox_bootrec.h,v 1.1 2007/12/20 22:59:59 garbled Exp $ */ + +#define BEBOX_HEADER_SIZE 0x6400 +#define BEBOX_BLOCK_SIZE 0x100 +#define BEBOX_FILE_SIZE_OFFSET 0x00004494 +#define BEBOX_FILE_SIZE_ALIGN_OFFSET 0x00004498 +#define BEBOX_FILE_BLOCK_MAP_START 0x00000200 +#define BEBOX_FILE_BLOCK_MAP_END 0x00000368 + +u_char bebox_image_data0[] = { + 0x00, 0x03, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef, /* mtime */ + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0b, 0x40, /* avail size */ + 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, 0x40, /* used block */ + 0x01, 0x00, 0x00, 0x00, 0x66, 0x64, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x41, 0xc0, + 0xbe, 0x00, 0xbe, 0x01, 0xbe, 0x02, 0xbe, 0x03, + 0xbe, 0x04, 0xbe, 0x05, 0xbe, 0x06, 0xbe, 0x07, + 0xbe, 0x08, 0xbe, 0x09, 0xbe, 0x0a, 0xbe, 0x0b, + 0xbe, 0x0c, 0xbe, 0x0d, 0xbe, 0x0e, 0xbe, 0x0f, + 0xbe, 0x10, 0xbe, 0x11, 0xbe, 0x12, 0xbe, 0x13, + 0xbe, 0x14, 0xbe, 0x15, 0xbe, 0x16, 0xbe, 0x17, + 0xbe, 0x18, 0xbe, 0x19, 0xbe, 0x1a, 0xbe, 0x1b, + 0xbe, 0x1c, 0xbe, 0x1d, 0xbe, 0x1e, 0xbe, 0x1f, + 0xbe, 0x20, 0xbe, 0x21, 0xbe, 0x22, 0xbe, 0x23, + 0xbe, 0x24, 0xbe, 0x25, 0xbe, 0x26, 0xbe, 0x27, + 0xbe, 0x28, 0xbe, 0x29, 0xbe, 0x2a, 0xbe, 0x2b, + 0xbe, 0x2c, 0xbe, 0x2d, 0xbe, 0x2e, 0xbe, 0x2f, + 0xbe, 0x30, 0xbe, 0x31, 0xbe, 0x32, 0xbe, 0x33, + 0xbe, 0x34, 0xbe, 0x35, 0xbe, 0x36, 0xbe, 0x37, + 0xbe, 0x38, 0xbe, 0x39, 0xbe, 0x3a, 0xbe, 0x3b, + 0xbe, 0x3c, 0xbe, 0x3d, 0xbe, 0x3e, 0xbe, 0x3f, + 0xbe, 0x40, 0xbe, 0x41, 0xbe, 0x42, 0xbe, 0x43, + 0xbe, 0x44, 0xbe, 0x45, 0xbe, 0x46, 0xbe, 0x47, + 0xbe, 0x48, 0xbe, 0x49, 0xbe, 0x4a, 0xbe, 0x4b, + 0xbe, 0x4c, 0xbe, 0x4d, 0xbe, 0x4e, 0xbe, 0x4f, + 0xbe, 0x50, 0xbe, 0x51, 0xbe, 0x52, 0xbe, 0x53, + 0xbe, 0x54, 0xbe, 0x55, 0xbe, 0x56, 0xbe, 0x57, + 0xbe, 0x58, 0xbe, 0x59, 0xbe, 0x5a, 0xbe, 0x5b, + 0xbe, 0x5c, 0xbe, 0x5d, 0xbe, 0x5e, 0xbe, 0x5f, + 0xbe, 0x60, 0xbe, 0x61, 0xbe, 0x62, 0xbe, 0x63, + 0xbe, 0x64, 0xbe, 0x65, 0xbe, 0x66, 0xbe, 0x67, + 0xbe, 0x68, 0xbe, 0x69, 0xbe, 0x6a, 0xbe, 0x6b, + 0xbe, 0x6c, 0xbe, 0x6d, 0xbe, 0x6e, 0xbe, 0x6f, + 0xbe, 0x70, 0xbe, 0x71, 0xbe, 0x72, 0xbe, 0x73, + 0xbe, 0x74, 0xbe, 0x75, 0xbe, 0x76, 0xbe, 0x77, + 0xbe, 0x78, 0xbe, 0x79, 0xbe, 0x7a, 0xbe, 0x7b, + 0xbe, 0x7c, 0xbe, 0x7d, 0xbe, 0x7e, 0xbe, 0x7f, + 0xbe, 0x80, 0xbe, 0x81, 0xbe, 0x82, 0xbe, 0x83, + 0xbe, 0x84, 0xbe, 0x85, 0xbe, 0x86, 0xbe, 0x87, + 0xbe, 0x88, 0xbe, 0x89, 0xbe, 0x8a, 0xbe, 0x8b, + 0xbe, 0x8c, 0xbe, 0x8d, 0xbe, 0x8e, 0xbe, 0x8f, + 0xbe, 0x90, 0xbe, 0x91, 0xbe, 0x92, 0xbe, 0x93, + 0xbe, 0x94, 0xbe, 0x95, 0xbe, 0x96, 0xbe, 0x97, + 0xbe, 0x98, 0xbe, 0x99, 0xbe, 0x9a, 0xbe, 0x9b, + 0xbe, 0x9c, 0xbe, 0x9d, 0xbe, 0x9e, 0xbe, 0x9f, + 0xbe, 0xa0, 0xbe, 0xa1, 0xbe, 0xa2, 0xbe, 0xa3, + 0xbe, 0xa4, 0xbe, 0xa5, 0xbe, 0xa6, 0xbe, 0xa7, + 0xbe, 0xa8, 0xbe, 0xa9, 0xbe, 0xaa, 0xbe, 0xab, + 0xbe, 0xac, 0xbe, 0xad, 0xbe, 0xae, 0xbe, 0xaf, + 0xbe, 0xb0, 0xbe, 0xb1, 0xbe, 0xb2, 0xbe, 0xb3, + 0xbe, 0xb4, 0xbe, 0xb5, 0xbe, 0xb6, 0xbe, 0xb7, + 0xbe, 0xb8, 0xbe, 0xb9, 0xbe, 0xba, 0xbe, 0xbb, + 0xbe, 0xbc, 0xbe, 0xbd, 0xbe, 0xbe, 0xbe, 0xbf, + 0xbe, 0xc0, 0xbe, 0xc1, 0xbe, 0xc2, 0xbe, 0xc3, + 0xbe, 0xc4, 0xbe, 0xc5, 0xbe, 0xc6, 0xbe, 0xc7, + 0xbe, 0xc8, 0xbe, 0xc9, 0xbe, 0xca, 0xbe, 0xcb, + 0xbe, 0xcc, 0xbe, 0xcd, 0xbe, 0xce, 0xbe, 0xcf, + 0xbe, 0xd0, 0xbe, 0xd1, 0xbe, 0xd2, 0xbe, 0xd3, +}; + +u_char bebox_image_data1[] = { + 0x54, 0x72, 0x61, 0x73, 0x68, 0x00, 0x00, 0x00, +}; + +u_char bebox_image_data2[] = { + 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xde, 0xad, 0xbe, 0xef, /* mtime */ + 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, /* mtime */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x41, 0xff, +}; + +u_char bebox_image_data3[] = { + 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x00, 0x00, +}; + +u_char bebox_image_data4[] = { + 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xde, 0xad, 0xbe, 0xef, /* mtime */ + 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, /* mtime */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x41, 0xff, +}; + +u_char bebox_image_data5[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, +}; + +u_char bebox_image_data6[] = { + 0x00, 0x72, 0x61, 0x73, 0x68, 0x00, 0x00, 0x00, +}; + +u_char bebox_image_data7[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xff, +}; + +u_char bebox_image_data8[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, +}; + +u_char bebox_image_data9[] = { + 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x00, 0x00, +}; + +u_char bebox_image_data10[] = { + 0x80, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x65, + 0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef, /* mtime */ + 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, /* mtime/filesize */ + 0xde, 0xea, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, /* filesize(aligned) */ + 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x81, 0xb6, +}; + +u_char bebox_image_data11[] = { + 0x00, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x00, 0x00, +}; + +u_char bebox_image_data12[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xff, +}; + +struct bebox_image_block { + long offset; + u_char *data; + int size; +}; + +#define BEBOX_IMG(x) __CONCAT(bebox_image_data,x) +#define BEBOX_IMG_DATA_SIZE(x) BEBOX_IMG(x), \ + (sizeof (BEBOX_IMG(x)) / sizeof (BEBOX_IMG(x)[0])) + +struct bebox_image_block bebox_image_block[] = { + { 0x00000000, BEBOX_IMG_DATA_SIZE(0) }, + { 0x00000440, BEBOX_IMG_DATA_SIZE(1) }, + { 0x00000480, BEBOX_IMG_DATA_SIZE(2) }, + { 0x000004c0, BEBOX_IMG_DATA_SIZE(3) }, + { 0x00000500, BEBOX_IMG_DATA_SIZE(4) }, + { 0x00002400, BEBOX_IMG_DATA_SIZE(5) }, + { 0x00002440, BEBOX_IMG_DATA_SIZE(6) }, + { 0x000024a0, BEBOX_IMG_DATA_SIZE(7) }, + { 0x00004400, BEBOX_IMG_DATA_SIZE(8) }, + { 0x00004440, BEBOX_IMG_DATA_SIZE(9) }, + { 0x00004480, BEBOX_IMG_DATA_SIZE(10) }, + { 0x000044c0, BEBOX_IMG_DATA_SIZE(11) }, + { 0x00004520, BEBOX_IMG_DATA_SIZE(12) }, + { -1 } +}; + +long bebox_mtime_offset[] = { + 0x00000004, + 0x0000048c, + 0x00000490, + 0x0000050c, + 0x00000510, + 0x0000448c, + 0x00004490, + -1 +}; diff --git a/sys/arch/powerpc/stand/mkbootimage/magic.h b/sys/arch/powerpc/stand/mkbootimage/magic.h index 80718d6c3975..d62c2d668c41 100644 --- a/sys/arch/powerpc/stand/mkbootimage/magic.h +++ b/sys/arch/powerpc/stand/mkbootimage/magic.h @@ -1,8 +1,11 @@ -/* $NetBSD: magic.h,v 1.2 2007/12/19 19:46:31 garbled Exp $ */ +/* $NetBSD: magic.h,v 1.3 2007/12/20 23:00:00 garbled Exp $ */ +char bebox_magic[] = "BSD"; char prep_magic[] = "KMA"; char rs6000_magic[] = "KMZ"; int kern_len; + +#define BEBOX_MAGICSIZE sizeof (bebox_magic) #define PREP_MAGICSIZE sizeof (prep_magic) #define RS6000_MAGICSIZE sizeof (rs6000_magic) #define KERNLENSIZE sizeof (kern_len) diff --git a/sys/arch/powerpc/stand/mkbootimage/mkbootimage.c b/sys/arch/powerpc/stand/mkbootimage/mkbootimage.c index 6f20060668ec..c3d6644652fc 100644 --- a/sys/arch/powerpc/stand/mkbootimage/mkbootimage.c +++ b/sys/arch/powerpc/stand/mkbootimage/mkbootimage.c @@ -1,4 +1,4 @@ -/* $NetBSD: mkbootimage.c,v 1.5 2007/12/20 18:00:18 garbled Exp $ */ +/* $NetBSD: mkbootimage.c,v 1.6 2007/12/20 23:00:00 garbled Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. @@ -64,9 +64,11 @@ #include #include -#include "rs6000_bootrec.h" +#include "bebox_bootrec.h" #include "byteorder.h" #include "magic.h" +#include "pef.h" +#include "rs6000_bootrec.h" /* Globals */ @@ -83,6 +85,7 @@ rs6000_config_record_t confrec; /* supported platforms */ char *sup_plats[] = { + "bebox", "prep", "rs6000", NULL, @@ -97,6 +100,8 @@ char *sup_plats[] = { #define ELFGET32(x) (((x)[0] << 24) | ((x)[1] << 16) | \ ((x)[2] << 8) | (x)[3]) +#define ULALIGN(x) ((x + 0x0f) & 0xfffffff0) + static void usage(int); static int open_file(const char *, char *, Elf32_External_Ehdr *, struct stat *); @@ -106,6 +111,7 @@ static void rs6000_build_records(int); static int rs6000_build_image(char *, char *, char *, char *); int main(int, char **); + static void usage(int extended) { @@ -579,6 +585,244 @@ rs6000_build_image(char *kernel, char *boot, char *rawdev, char *outname) return 0; } +static int +bebox_write_header(int bebox_fd, int elf_image_len, int kern_img_len) +{ + int hsize = BEBOX_HEADER_SIZE; + unsigned long textOffset, dataOffset, ldrOffset; + unsigned long entry_vector[3]; + struct FileHeader fileHdr; + struct SectionHeader textHdr, dataHdr, ldrHdr; + struct LoaderHeader lh; + + if (saloneflag) + hsize = 0; + + ldrOffset = ULALIGN(sizeof (fileHdr) + sizeof (textHdr) + + sizeof (dataHdr) + sizeof (ldrHdr)); + dataOffset = ULALIGN(ldrOffset + sizeof (lh)); + textOffset = ULALIGN(dataOffset + sizeof (entry_vector) + kern_img_len); + + /* Create the File Header */ + memset(&fileHdr, 0, sizeof (fileHdr)); + fileHdr.magic = sa_htobe32(PEF_MAGIC); + fileHdr.fileTypeID = sa_htobe32(PEF_FILE); + fileHdr.archID = sa_htobe32(PEF_PPC); + fileHdr.versionNumber = sa_htobe32(1); + fileHdr.numSections = sa_htobe16(3); + fileHdr.loadableSections = sa_htobe16(2); + write(bebox_fd, &fileHdr, sizeof (fileHdr)); + + /* Create the Section Header for TEXT */ + memset(&textHdr, 0, sizeof (textHdr)); + textHdr.sectionName = sa_htobe32(-1); + textHdr.sectionAddress = sa_htobe32(0); + textHdr.execSize = sa_htobe32(elf_image_len); + textHdr.initSize = sa_htobe32(elf_image_len); + textHdr.rawSize = sa_htobe32(elf_image_len); + textHdr.fileOffset = sa_htobe32(textOffset); + textHdr.regionKind = CodeSection; + textHdr.shareKind = ContextShare; + textHdr.alignment = 4; /* 16 byte alignment */ + write(bebox_fd, &textHdr, sizeof (textHdr)); + + /* Create the Section Header for DATA */ + memset(&dataHdr, 0, sizeof (dataHdr)); + dataHdr.sectionName = sa_htobe32(-1); + dataHdr.sectionAddress = sa_htobe32(0); + dataHdr.execSize = sa_htobe32(sizeof (entry_vector) + kern_img_len); + dataHdr.initSize = sa_htobe32(sizeof (entry_vector) + kern_img_len); + dataHdr.rawSize = sa_htobe32(sizeof (entry_vector) + kern_img_len); + dataHdr.fileOffset = sa_htobe32(dataOffset); + dataHdr.regionKind = DataSection; + dataHdr.shareKind = ContextShare; + dataHdr.alignment = 4; /* 16 byte alignment */ + write(bebox_fd, &dataHdr, sizeof (dataHdr)); + + /* Create the Section Header for loader stuff */ + memset(&ldrHdr, 0, sizeof (ldrHdr)); + ldrHdr.sectionName = sa_htobe32(-1); + ldrHdr.sectionAddress = sa_htobe32(0); + ldrHdr.execSize = sa_htobe32(sizeof (lh)); + ldrHdr.initSize = sa_htobe32(sizeof (lh)); + ldrHdr.rawSize = sa_htobe32(sizeof (lh)); + ldrHdr.fileOffset = sa_htobe32(ldrOffset); + ldrHdr.regionKind = LoaderSection; + ldrHdr.shareKind = GlobalShare; + ldrHdr.alignment = 4; /* 16 byte alignment */ + write(bebox_fd, &ldrHdr, sizeof (ldrHdr)); + + /* Create the Loader Header */ + memset(&lh, 0, sizeof (lh)); + lh.entryPointSection = sa_htobe32(1); /* Data */ + lh.entryPointOffset = sa_htobe32(0); + lh.initPointSection = sa_htobe32(-1); + lh.initPointOffset = sa_htobe32(0); + lh.termPointSection = sa_htobe32(-1); + lh.termPointOffset = sa_htobe32(0); + lseek(bebox_fd, ldrOffset + hsize, SEEK_SET); + write(bebox_fd, &lh, sizeof (lh)); + + /* Copy the pseudo-DATA */ + memset(entry_vector, 0, sizeof (entry_vector)); + entry_vector[0] = sa_htobe32(ENTRY); /* Magic */ + lseek(bebox_fd, dataOffset + hsize, SEEK_SET); + write(bebox_fd, entry_vector, sizeof (entry_vector)); + + return textOffset; +} + +static int +bebox_build_image(char *kernel, char *boot, char *rawdev, char *outname) +{ + unsigned char *elf_img = NULL, *kern_img = NULL, *header_img = NULL; + int i, ch, tmp, kgzlen, err, hsize = BEBOX_HEADER_SIZE; + int elf_fd, bebox_fd, kern_fd, elf_img_len = 0; + uint32_t swapped[128]; + off_t lenpos, kstart, kend, toff, endoff; + unsigned long length; + long flength, *offset; + gzFile gzf; + struct stat kern_stat; + struct bebox_image_block *p; + struct timeval tp; + Elf32_External_Phdr phdr; + + if (saloneflag) + hsize = 0; + + elf_fd = open_file("bootloader", boot, &hdr, &elf_stat); + kern_fd = open_file("kernel", kernel, &khdr, &kern_stat); + kern_len = kern_stat.st_size + BEBOX_MAGICSIZE + KERNLENSIZE; + + for (i = 0; i < ELFGET16(hdr.e_phnum); i++) { + lseek(elf_fd, ELFGET32(hdr.e_phoff) + sizeof(phdr) * i, + SEEK_SET); + if (read(elf_fd, &phdr, sizeof(phdr)) != sizeof(phdr)) + errx(3, "Can't read input '%s' phdr : %s", boot, + strerror(errno)); + + if ((ELFGET32(phdr.p_type) != PT_LOAD) || + !(ELFGET32(phdr.p_flags) & PF_X)) + continue; + + fstat(elf_fd, &elf_stat); + elf_img_len = elf_stat.st_size - ELFGET32(phdr.p_offset); + lseek(elf_fd, ELFGET32(phdr.p_offset), SEEK_SET); + + break; + } + if ((bebox_fd = open(outname, O_RDWR|O_TRUNC, 0)) < 0) { + /* we couldn't open it, it must be new */ + bebox_fd = creat(outname, 0644); + if (bebox_fd < 0) + errx(2, "Can't open output '%s': %s", outname, + strerror(errno)); + } + lseek(bebox_fd, hsize, SEEK_SET); + + /* write the header with the wrong values to get the offset right */ + bebox_write_header(bebox_fd, elf_img_len, kern_len); + + /* Copy kernel */ + kern_img = (unsigned char *)malloc(kern_stat.st_size); + + if (kern_img == NULL) + errx(3, "Can't malloc: %s", strerror(errno)); + + /* we need to jump back after having read the headers */ + lseek(kern_fd, 0, SEEK_SET); + if (read(kern_fd, (void *)kern_img, kern_stat.st_size) != + kern_stat.st_size) + errx(3, "Can't read kernel '%s' : %s", kernel, strerror(errno)); + + gzf = gzdopen(dup(bebox_fd), "a"); + if (gzf == NULL) + errx(3, "Can't init compression: %s", strerror(errno)); + if (gzsetparams(gzf, Z_BEST_COMPRESSION, Z_DEFAULT_STRATEGY) != Z_OK) + errx(3, "%s", gzerror(gzf, &err)); + + /* write a magic number and size before the kernel */ + write(bebox_fd, (void *)bebox_magic, BEBOX_MAGICSIZE); + lenpos = lseek(bebox_fd, 0, SEEK_CUR); + tmp = sa_htobe32(0); + write(bebox_fd, (void *)&tmp, KERNLENSIZE); + + /* write in the compressed kernel */ + kstart = lseek(bebox_fd, 0, SEEK_CUR); + kgzlen = gzwrite(gzf, kern_img, kern_stat.st_size); + gzclose(gzf); + kend = lseek(bebox_fd, 0, SEEK_CUR); + free(kern_img); + + /* jump back to the length position now that we know the length */ + lseek(bebox_fd, lenpos, SEEK_SET); + kgzlen = kend - kstart; + tmp = sa_htobe32(kgzlen); + write(bebox_fd, (void *)&tmp, KERNLENSIZE); + + /* now rewrite the header correctly */ + lseek(bebox_fd, hsize, SEEK_SET); + toff = bebox_write_header(bebox_fd, elf_img_len, kgzlen); + + /* Copy boot image */ + elf_img = (unsigned char *)malloc(elf_img_len); + if (!elf_img) + errx(3, "Can't malloc: %s", strerror(errno)); + if (read(elf_fd, elf_img, elf_img_len) != elf_img_len) + errx(3, "Can't read file '%s' : %s", boot, strerror(errno)); + lseek(bebox_fd, toff + hsize, SEEK_SET); + write(bebox_fd, elf_img, elf_img_len); + free(elf_img); + + close(kern_fd); + close(elf_fd); + + if (saloneflag) { + close(bebox_fd); + return 0; + } + + /* Now go back and write in the block header */ + endoff = lseek(bebox_fd, 0, SEEK_END); + lseek(bebox_fd, 0, SEEK_SET); + header_img = (unsigned char *)malloc(BEBOX_HEADER_SIZE); + if (!header_img) + errx(3, "Can't malloc: %s", strerror(errno)); + memset(header_img, 0, BEBOX_HEADER_SIZE); + + /* copy the boot image into the buffer */ + for (p = bebox_image_block; p->offset != -1; p++) + memcpy(header_img + p->offset, p->data, p->size); + + /* fill used block bitmap */ + memset(header_img + BEBOX_FILE_BLOCK_MAP_START, 0xff, + BEBOX_FILE_BLOCK_MAP_END - BEBOX_FILE_BLOCK_MAP_START); + + /* fix the file size in the header */ + *(long *)(header_img + BEBOX_FILE_SIZE_OFFSET) = + (long)sa_htobe32(endoff); + *(long *)(header_img + BEBOX_FILE_SIZE_ALIGN_OFFSET) = + (long)sa_htobe32(roundup(endoff, BEBOX_BLOCK_SIZE)); + + gettimeofday(&tp, 0); + for (offset = bebox_mtime_offset; *offset != -1; offset++) + *(long *)(header_img + *offset) = (long)sa_htobe32(tp.tv_sec); + + write(bebox_fd, header_img, BEBOX_HEADER_SIZE); + + /* now pad the end */ + flength = roundup(endoff, BEBOX_BLOCK_SIZE); + /* refill the header_img with zeros */ + memset(header_img, 0, BEBOX_BLOCK_SIZE * 2); + lseek(bebox_fd, 0, SEEK_END); + write(bebox_fd, header_img, flength - endoff); + + close(bebox_fd); + + return 0; +} + int main(int argc, char **argv) { @@ -660,6 +904,8 @@ main(int argc, char **argv) return(prep_build_image(kernel, boot, rawdev, outname)); if (strcmp(march, "rs6000") == 0) return(rs6000_build_image(kernel, boot, rawdev, outname)); + if (strcmp(march, "bebox") == 0) + return(bebox_build_image(kernel, boot, rawdev, outname)); usage(1); return(0); diff --git a/sys/arch/powerpc/stand/mkbootimage/pef.h b/sys/arch/powerpc/stand/mkbootimage/pef.h new file mode 100644 index 000000000000..f14ca053c970 --- /dev/null +++ b/sys/arch/powerpc/stand/mkbootimage/pef.h @@ -0,0 +1,96 @@ +/* $NetBSD: pef.h,v 1.1 2007/12/20 23:00:00 garbled Exp $ */ + +/*- + * Copyright (C) 1995-1997 Gary Thomas (gdt@linuxppc.org) + * All rights reserved. + * + * Structure of a PEF format file + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Gary Thomas. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +struct FileHeader +{ + unsigned long magic; + unsigned long fileTypeID; + unsigned long archID; + unsigned long versionNumber; + unsigned long dateTimeStamp; + unsigned long definVersion; + unsigned long implVersion; + unsigned long currentVersion; + unsigned short numSections; + unsigned short loadableSections; + unsigned long memoryAddress; +}; + +#define PEF_MAGIC 0x4A6F7921 /* Joy! */ +#define PEF_FILE 0x70656666 /* peff */ +#define PEF_PPC 0x70777063 /* pwpc */ + +struct SectionHeader +{ + unsigned long sectionName; + unsigned long sectionAddress; + unsigned long execSize; + unsigned long initSize; + unsigned long rawSize; + unsigned long fileOffset; + unsigned char regionKind; + unsigned char shareKind; + unsigned char alignment; + unsigned char _reserved; +}; + +#define CodeSection 0 +#define DataSection 1 +#define PIDataSection 2 +#define ConstantSection 3 +#define LoaderSection 4 + +#define NeverShare 0 +#define ContextShare 1 +#define TeamShare 2 +#define TaskShare 3 +#define GlobalShare 4 + +struct LoaderHeader +{ + unsigned long entryPointSection; + unsigned long entryPointOffset; + unsigned long initPointSection; + unsigned long initPointOffset; + unsigned long termPointSection; + unsigned long termPointOffset; + unsigned long numImportFiles; + unsigned long numImportSyms; + unsigned long numSections; + unsigned long relocationsOffset; + unsigned long stringsOffset; + unsigned long hashSlotTable; + unsigned long hashSlotTableSize; + unsigned long numExportSyms; +};