summaryrefslogtreecommitdiffstats
path: root/arch/alpha/boot/tools
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-01-07 02:33:00 +0000
committer <ralf@linux-mips.org>1997-01-07 02:33:00 +0000
commitbeb116954b9b7f3bb56412b2494b562f02b864b1 (patch)
tree120e997879884e1b9d93b265221b939d2ef1ade1 /arch/alpha/boot/tools
parent908d4681a1dc3792ecafbe64265783a86c4cccb6 (diff)
Import of Linux/MIPS 2.1.14
Diffstat (limited to 'arch/alpha/boot/tools')
-rw-r--r--arch/alpha/boot/tools/build.c173
-rw-r--r--arch/alpha/boot/tools/mkbb.c151
-rw-r--r--arch/alpha/boot/tools/objstrip.c280
3 files changed, 431 insertions, 173 deletions
diff --git a/arch/alpha/boot/tools/build.c b/arch/alpha/boot/tools/build.c
deleted file mode 100644
index 040655a54..000000000
--- a/arch/alpha/boot/tools/build.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * arch/alpha/boot/tools/build.c
- *
- * Build a bootable image from the vmlinux binary
- */
-#include <string.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include <a.out.h>
-
-#include <asm/system.h>
-
-#define MAXSECT 10
-#define MAXBUF 8192
-
-int verbose = 0;
-int pad = 0;
-char * program = "tools/build";
-char buffer[MAXBUF];
-unsigned long bootblock[64];
-struct filehdr fhdr;
-struct aouthdr ahdr;
-struct scnhdr shdr[MAXSECT];
-
-char * usage = "'build [-b] system > secondary' or 'build > primary'";
-
-static void die(char * str)
-{
- fprintf(stderr,"%s: %s\n", program, str);
- exit(1);
-}
-
-static int comp(struct scnhdr * a, struct scnhdr * b)
-{
- return a->s_vaddr - b->s_vaddr;
-}
-
-int main(int argc, char ** argv)
-{
- int fd, i;
- unsigned long tmp, start;
- unsigned long system_start, system_size;
- char * infile = NULL;
-
- system_start = START_ADDR;
- system_size = START_SIZE;
- if (argc) {
- program = *(argv++);
- argc--;
- }
- while (argc > 0) {
- if (**argv == '-') {
- while (*++*argv) {
- switch (**argv) {
- case 'b':
- system_start = BOOT_ADDR;
- system_size = BOOT_SIZE;
- pad = 1;
- break;
- case 'v':
- verbose++;
- break;
- default:
- die(usage);
- }
- }
- } else if (infile)
- die(usage);
- else
- infile = *argv;
- argv++;
- argc--;
- }
- if (!infile) {
- memcpy(bootblock, "Linux Test", 10);
- bootblock[60] = BOOT_SIZE / 512; /* count */
- bootblock[61] = 1; /* starting LBM */
- bootblock[62] = 0; /* flags */
- tmp = 0;
- for (i = 0 ; i < 63 ; i++)
- tmp += bootblock[i];
- bootblock[63] = tmp;
- if (write(1, (char *) bootblock, 512) != 512) {
- perror("bbwrite");
- exit(1);
- }
- return 0;
- }
- fd = open(infile, O_RDONLY);
- if (fd < 0) {
- perror(infile);
- exit(1);
- }
- if (read(fd, &fhdr, sizeof(struct filehdr)) != sizeof(struct filehdr))
- die("unable to read file header");
- if (fhdr.f_nscns > MAXSECT)
- die("Too many sections");
- if (fhdr.f_opthdr != AOUTHSZ)
- die("optional header doesn't look like a.out");
- if (read(fd, &ahdr, sizeof(struct aouthdr)) != sizeof(struct aouthdr))
- die("unable to read a.out header");
- for (i = 0 ; i < fhdr.f_nscns ; i++) {
- if (read(fd, i+shdr, sizeof(struct scnhdr)) != sizeof(struct scnhdr))
- die("unable to read section header");
- if (shdr[i].s_paddr != shdr[i].s_vaddr)
- die("unable to handle different phys/virt addresses");
- if (shdr[i].s_relptr)
- die("Unable to handle relocation info");
- if (verbose) {
- fprintf(stderr, "section %d (%.8s):\t%lx - %lx (at %x)\n",
- i, shdr[i].s_name,
- shdr[i].s_vaddr,
- shdr[i].s_vaddr + shdr[i].s_size,
- shdr[i].s_scnptr);
- }
- }
- qsort(shdr, fhdr.f_nscns, sizeof(shdr[1]), comp);
- start = system_start;
- for (i = 0 ; i < fhdr.f_nscns ; i++) {
- unsigned long size, offset;
- memset(buffer, 0, MAXBUF);
- if (!strcmp(shdr[i].s_name, ".comment"))
- continue;
- if (shdr[i].s_vaddr != start)
- die("Unordered or badly placed segments");
- size = shdr[i].s_size;
- start += size;
- offset = shdr[i].s_scnptr;
- if (lseek(fd, offset, SEEK_SET) != offset)
- die("Unable to seek in in-file");
- while (size > 0) {
- unsigned long num = size;
- if (num > MAXBUF)
- num = MAXBUF;
- if (offset)
- if (read(fd, buffer, num) != num)
- die("partial read");
- if (write(1, buffer, num) != num)
- die("partial write");
- size -= num;
- }
- if (verbose) {
- fprintf(stderr, "section %d (%.8s):\t%lx - %lx (at %x)\n",
- i, shdr[i].s_name,
- shdr[i].s_vaddr,
- shdr[i].s_vaddr + shdr[i].s_size,
- shdr[i].s_scnptr);
- }
- }
- if (start > system_start + system_size) {
- fprintf(stderr, "Boot image too large\n");
- exit(1);
- }
- if (pad) {
- unsigned long count = (system_start + system_size) - start;
- memset(buffer, 0, MAXBUF);
- while (count > 0) {
- int i = MAXBUF;
- if (i > count)
- i = count;
- i = write(1, buffer, i);
- if (i <= 0) {
- perror("pad write");
- exit(1);
- }
- count -= i;
- }
- }
-
- return 0;
-}
diff --git a/arch/alpha/boot/tools/mkbb.c b/arch/alpha/boot/tools/mkbb.c
new file mode 100644
index 000000000..23c7190b0
--- /dev/null
+++ b/arch/alpha/boot/tools/mkbb.c
@@ -0,0 +1,151 @@
+/* This utility makes a bootblock suitable for the SRM console/miniloader */
+
+/* Usage:
+ * mkbb <device> <lxboot>
+ *
+ * Where <device> is the name of the device to install the bootblock on,
+ * and <lxboot> is the name of a bootblock to merge in. This bootblock
+ * contains the offset and size of the bootloader. It must be exactly
+ * 512 bytes long.
+ */
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+
+/* Minimal definition of disklabel, so we don't have to include
+ * asm/disklabel.h (confuses make)
+ */
+#ifndef MAXPARTITIONS
+#define MAXPARTITIONS 8 /* max. # of partitions */
+#endif
+
+#ifndef u8
+#define u8 unsigned char
+#endif
+
+#ifndef u16
+#define u16 unsigned short
+#endif
+
+#ifndef u32
+#define u32 unsigned int
+#endif
+
+struct disklabel {
+ u32 d_magic; /* must be DISKLABELMAGIC */
+ u16 d_type, d_subtype;
+ u8 d_typename[16];
+ u8 d_packname[16];
+ u32 d_secsize;
+ u32 d_nsectors;
+ u32 d_ntracks;
+ u32 d_ncylinders;
+ u32 d_secpercyl;
+ u32 d_secprtunit;
+ u16 d_sparespertrack;
+ u16 d_sparespercyl;
+ u32 d_acylinders;
+ u16 d_rpm, d_interleave, d_trackskew, d_cylskew;
+ u32 d_headswitch, d_trkseek, d_flags;
+ u32 d_drivedata[5];
+ u32 d_spare[5];
+ u32 d_magic2; /* must be DISKLABELMAGIC */
+ u16 d_checksum;
+ u16 d_npartitions;
+ u32 d_bbsize, d_sbsize;
+ struct d_partition {
+ u32 p_size;
+ u32 p_offset;
+ u32 p_fsize;
+ u8 p_fstype;
+ u8 p_frag;
+ u16 p_cpg;
+ } d_partitions[MAXPARTITIONS];
+};
+
+
+typedef union __bootblock {
+ struct {
+ char __pad1[64];
+ struct disklabel __label;
+ } __u1;
+ struct {
+ unsigned long __pad2[63];
+ unsigned long __checksum;
+ } __u2;
+ char bootblock_bytes[512];
+ unsigned long bootblock_quadwords[64];
+} bootblock;
+
+#define bootblock_label __u1.__label
+#define bootblock_checksum __u2.__checksum
+
+main(int argc, char ** argv)
+{
+ bootblock bootblock_from_disk;
+ bootblock bootloader_image;
+ int dev, fd;
+ int i;
+ int nread;
+
+ /* Make sure of the arg count */
+ if(argc != 3) {
+ fprintf(stderr, "Usage: %s device lxboot\n", argv[0]);
+ exit(0);
+ }
+
+ /* First, open the device and make sure it's accessible */
+ dev = open(argv[1], O_RDWR);
+ if(dev < 0) {
+ perror(argv[1]);
+ exit(0);
+ }
+
+ /* Now open the lxboot and make sure it's reasonable */
+ fd = open(argv[2], O_RDONLY);
+ if(fd < 0) {
+ perror(argv[2]);
+ close(dev);
+ exit(0);
+ }
+
+ /* Read in the lxboot */
+ nread = read(fd, &bootloader_image, sizeof(bootblock));
+ if(nread != sizeof(bootblock)) {
+ perror("lxboot read");
+ fprintf(stderr, "expected %d, got %d\n", sizeof(bootblock), nread);
+ exit(0);
+ }
+
+ /* Read in the bootblock from disk. */
+ nread = read(dev, &bootblock_from_disk, sizeof(bootblock));
+ if(nread != sizeof(bootblock)) {
+ perror("bootblock read");
+ fprintf(stderr, "expected %d, got %d\n", sizeof(bootblock), nread);
+ exit(0);
+ }
+
+ /* Swap the bootblock's disklabel into the bootloader */
+ bootloader_image.bootblock_label = bootblock_from_disk.bootblock_label;
+
+ /* Calculate the bootblock checksum */
+ bootloader_image.bootblock_checksum = 0;
+ for(i = 0; i < 63; i++) {
+ bootloader_image.bootblock_checksum +=
+ bootloader_image.bootblock_quadwords[i];
+ }
+
+ /* Write the whole thing out! */
+ lseek(dev, 0L, SEEK_SET);
+ if(write(dev, &bootloader_image, sizeof(bootblock)) != sizeof(bootblock)) {
+ perror("bootblock write");
+ exit(0);
+ }
+
+ close(fd);
+ close(dev);
+ exit(0);
+}
+
+
diff --git a/arch/alpha/boot/tools/objstrip.c b/arch/alpha/boot/tools/objstrip.c
new file mode 100644
index 000000000..765e68f2e
--- /dev/null
+++ b/arch/alpha/boot/tools/objstrip.c
@@ -0,0 +1,280 @@
+/*
+ * arch/alpha/boot/tools/objstrip.c
+ *
+ * Strip the object file headers/trailers from an executable (ELF or ECOFF).
+ *
+ * Copyright (C) 1996 David Mosberger-Tang.
+ */
+/*
+ * Converts an ECOFF or ELF object file into a bootable file. The
+ * object file must be a OMAGIC file (i.e., data and bss follow immediatly
+ * behind the text). See DEC "Assembly Language Programmer's Guide"
+ * documentation for details. The SRM boot process is documented in
+ * the Alpha AXP Architecture Reference Manual, Second Edition by
+ * Richard L. Sites and Richard T. Witek.
+ */
+#include <stdio.h>
+#include <unistd.h>
+
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <linux/a.out.h>
+#include <linux/coff.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#ifdef __ELF__
+# include <asm/elf.h>
+# include <linux/elf.h>
+#endif
+
+/* bootfile size must be multiple of BLOCK_SIZE: */
+#define BLOCK_SIZE 512
+
+const char * prog_name;
+
+
+void
+usage (void)
+{
+ fprintf(stderr,
+ "usage: %s [-v] -p file primary\n"
+ " %s [-vb] file [secondary]\n", prog_name, prog_name);
+ exit(1);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ size_t nwritten, tocopy, n, mem_size, fil_size, pad = 0;
+ int fd, ofd, i, j, verbose = 0, primary = 0;
+ char buf[8192], *inname;
+ struct exec * aout; /* includes file & aout header */
+ long offset;
+#ifdef __ELF__
+ struct elfhdr *elf;
+ struct elf_phdr *elf_phdr; /* program header */
+ unsigned long long e_entry;
+#endif
+
+ prog_name = argv[0];
+
+ for (i = 1; i < argc && argv[i][0] == '-'; ++i) {
+ for (j = 1; argv[i][j]; ++j) {
+ switch (argv[i][j]) {
+ case 'v':
+ verbose = ~verbose;
+ break;
+
+ case 'b':
+ pad = BLOCK_SIZE;
+ break;
+
+ case 'p':
+ primary = 1; /* make primary bootblock */
+ break;
+ }
+ }
+ }
+
+ if (i >= argc) {
+ usage();
+ }
+ inname = argv[i++];
+
+ fd = open(inname, O_RDONLY);
+ if (fd == -1) {
+ perror("open");
+ exit(1);
+ }
+
+ ofd = 1;
+ if (i < argc) {
+ ofd = open(argv[i++], O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ if (fd == -1) {
+ perror("open");
+ exit(1);
+ }
+ }
+
+ if (primary) {
+ /* generate bootblock for primary loader */
+
+ unsigned long bb[64], sum = 0;
+ struct stat st;
+ off_t size;
+ int i;
+
+ if (ofd == 1) {
+ usage();
+ }
+
+ if (fstat(fd, &st) == -1) {
+ perror("fstat");
+ exit(1);
+ }
+
+ size = (st.st_size + BLOCK_SIZE - 1) & ~(BLOCK_SIZE - 1);
+ memset(bb, 0, sizeof(bb));
+ strcpy((char *) bb, "Linux SRM bootblock");
+ bb[60] = size / BLOCK_SIZE; /* count */
+ bb[61] = 1; /* starting sector # */
+ bb[62] = 0; /* flags---must be 0 */
+ for (i = 0; i < 63; ++i) {
+ sum += bb[i];
+ }
+ bb[63] = sum;
+ if (write(ofd, bb, sizeof(bb)) != sizeof(bb)) {
+ perror("boot-block write");
+ exit(1);
+ }
+ printf("%lu\n", size);
+ return 0;
+ }
+
+ /* read and inspect exec header: */
+
+ if (read(fd, buf, sizeof(buf)) < 0) {
+ perror("read");
+ exit(1);
+ }
+
+#ifdef __ELF__
+ elf = (struct elfhdr *) buf;
+
+ if (elf->e_ident[0] == 0x7f && strncmp(elf->e_ident + 1, "ELF", 3) == 0) {
+ if (elf->e_type != ET_EXEC) {
+ fprintf(stderr, "%s: %s is not an ELF executable\n",
+ prog_name, inname);
+ exit(1);
+ }
+ if (!elf_check_arch(elf->e_machine)) {
+ fprintf(stderr, "%s: is not for this processor (e_machine=%d)\n",
+ prog_name, elf->e_machine);
+ exit(1);
+ }
+ if (elf->e_phnum != 1) {
+ fprintf(stderr,
+ "%s: %d program headers (forgot to link with -N?)\n",
+ prog_name, elf->e_phnum);
+ }
+
+ e_entry = elf->e_entry;
+
+ lseek(fd, elf->e_phoff, SEEK_SET);
+ if (read(fd, buf, sizeof(*elf_phdr)) != sizeof(*elf_phdr)) {
+ perror("read");
+ exit(1);
+ }
+
+ elf_phdr = (struct elf_phdr *) buf;
+ offset = elf_phdr->p_offset;
+ mem_size = elf_phdr->p_memsz;
+ fil_size = elf_phdr->p_filesz;
+
+ /* work around ELF bug: */
+ if (elf_phdr->p_vaddr < e_entry) {
+ unsigned long delta = e_entry - elf_phdr->p_vaddr;
+ offset += delta;
+ mem_size -= delta;
+ fil_size -= delta;
+ elf_phdr->p_vaddr += delta;
+ }
+
+ if (verbose) {
+ fprintf(stderr, "%s: extracting %#016lx-%#016lx (at %lx)\n",
+ prog_name, (long) elf_phdr->p_vaddr,
+ elf_phdr->p_vaddr + fil_size, offset);
+ }
+ } else
+#endif
+ {
+ aout = (struct exec *) buf;
+
+ if (!(aout->fh.f_flags & COFF_F_EXEC)) {
+ fprintf(stderr, "%s: %s is not in executable format\n",
+ prog_name, inname);
+ exit(1);
+ }
+
+ if (aout->fh.f_opthdr != sizeof(aout->ah)) {
+ fprintf(stderr, "%s: %s has unexpected optional header size\n",
+ prog_name, inname);
+ exit(1);
+ }
+
+ if (N_MAGIC(*aout) != OMAGIC) {
+ fprintf(stderr, "%s: %s is not an OMAGIC file\n",
+ prog_name, inname);
+ exit(1);
+ }
+ offset = N_TXTOFF(*aout);
+ fil_size = aout->ah.tsize + aout->ah.dsize;
+ mem_size = fil_size + aout->ah.bsize;
+
+ if (verbose) {
+ fprintf(stderr, "%s: extracting %#016lx-%#016lx (at %lx)\n",
+ prog_name, aout->ah.text_start,
+ aout->ah.text_start + fil_size, offset);
+ }
+ }
+
+ if (lseek(fd, offset, SEEK_SET) != offset) {
+ perror("lseek");
+ exit(1);
+ }
+
+ if (verbose) {
+ fprintf(stderr, "%s: copying %lu byte from %s\n",
+ prog_name, (unsigned long) fil_size, inname);
+ }
+
+ tocopy = fil_size;
+ while (tocopy > 0) {
+ n = tocopy;
+ if (n > sizeof(buf)) {
+ n = sizeof(buf);
+ }
+ tocopy -= n;
+ if ((size_t) read(fd, buf, n) != n) {
+ perror("read");
+ exit(1);
+ }
+ do {
+ nwritten = write(ofd, buf, n);
+ if ((ssize_t) nwritten == -1) {
+ perror("write");
+ exit(1);
+ }
+ n -= nwritten;
+ } while (n > 0);
+ }
+
+ if (pad) {
+ mem_size = ((mem_size + pad - 1) / pad) * pad;
+ }
+
+ tocopy = mem_size - fil_size;
+ if (tocopy > 0) {
+ fprintf(stderr,
+ "%s: zero-filling bss and aligning to %lu with %lu bytes\n",
+ prog_name, pad, (unsigned long) tocopy);
+
+ memset(buf, 0x00, sizeof(buf));
+ do {
+ n = tocopy;
+ if (n > sizeof(buf)) {
+ n = sizeof(buf);
+ }
+ nwritten = write(ofd, buf, n);
+ if ((ssize_t) nwritten == -1) {
+ perror("write");
+ exit(1);
+ }
+ tocopy -= nwritten;
+ } while (tocopy > 0);
+ }
+ return 0;
+}