Linux-2.6.12-rc2

Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
diff --git a/arch/alpha/boot/Makefile b/arch/alpha/boot/Makefile
new file mode 100644
index 0000000..e1ae14c
--- /dev/null
+++ b/arch/alpha/boot/Makefile
@@ -0,0 +1,116 @@
+#
+# arch/alpha/boot/Makefile
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1994 by Linus Torvalds
+#
+
+hostprogs-y	:= tools/mkbb tools/objstrip
+targets		:= vmlinux.gz vmlinux \
+		   vmlinux.nh tools/lxboot tools/bootlx tools/bootph \
+		   tools/bootpzh bootloader bootpheader bootpzheader 
+OBJSTRIP	:= $(obj)/tools/objstrip
+
+# SRM bootable image.  Copy to offset 512 of a partition.
+$(obj)/bootimage: $(addprefix $(obj)/tools/,mkbb lxboot bootlx) $(obj)/vmlinux.nh
+	( cat $(obj)/tools/lxboot $(obj)/tools/bootlx $(obj)/vmlinux.nh ) > $@ 
+	$(obj)/tools/mkbb $@ $(obj)/tools/lxboot
+	@echo '  Bootimage $@ is ready'
+
+# BOOTP bootable image.  Define INITRD during make to append initrd image.
+$(obj)/bootpfile: $(obj)/tools/bootph $(obj)/vmlinux.nh
+	cat $(obj)/tools/bootph $(obj)/vmlinux.nh > $@
+ifdef INITRD
+	cat $(INITRD) >> $@
+endif
+
+# Compressed kernel BOOTP bootable image.
+# Define INITRD during make to append initrd image.
+$(obj)/bootpzfile: $(obj)/tools/bootpzh $(obj)/vmlinux.nh.gz
+	cat $(obj)/tools/bootpzh $(obj)/vmlinux.nh.gz > $@
+ifdef INITRD
+	cat $(INITRD) >> $@
+endif
+
+# Compressed kernel image
+$(obj)/vmlinux.gz: $(obj)/vmlinux FORCE
+	$(call if_changed,gzip)
+	@echo '  Kernel $@ is ready'
+
+$(obj)/main.o: $(obj)/ksize.h
+$(obj)/bootp.o: $(obj)/ksize.h
+$(obj)/bootpz.o: $(obj)/kzsize.h
+
+$(obj)/ksize.h: $(obj)/vmlinux.nh FORCE
+	echo "#define KERNEL_SIZE `ls -l $(obj)/vmlinux.nh | awk '{print $$5}'`" > $@T
+ifdef INITRD
+	[ -f $(INITRD) ] || exit 1
+	echo "#define INITRD_IMAGE_SIZE `ls -l $(INITRD) | awk '{print $$5}'`" >> $@T
+endif
+	cmp -s $@T $@ || mv -f $@T $@
+	rm -f $@T
+
+$(obj)/kzsize.h: $(obj)/vmlinux.nh.gz FORCE
+	echo "#define KERNEL_SIZE `ls -l $(obj)/vmlinux.nh | awk '{print $$5}'`" > $@T
+	echo "#define KERNEL_Z_SIZE `ls -l $(obj)/vmlinux.nh.gz | awk '{print $$5}'`" >> $@T
+ifdef INITRD
+	[ -f $(INITRD) ] || exit 1
+	echo "#define INITRD_IMAGE_SIZE `ls -l $(INITRD) | awk '{print $$5}'`" >> $@T
+endif
+	cmp -s $@T $@ || mv -f $@T $@
+	rm -f $@T
+
+quiet_cmd_strip = STRIP  $@
+      cmd_strip = $(STRIP) -o $@ $<
+
+$(obj)/vmlinux: vmlinux FORCE
+	$(call if_changed,strip)
+
+quiet_cmd_objstrip = OBJSTRIP $@
+      cmd_objstrip = $(OBJSTRIP) $(OSFLAGS_$(@F)) $< $@
+
+OSFLAGS_vmlinux.nh	:= -v
+OSFLAGS_lxboot		:= -p
+OSFLAGS_bootlx		:= -vb
+OSFLAGS_bootph		:= -vb
+OSFLAGS_bootpzh		:= -vb
+
+$(obj)/vmlinux.nh: vmlinux $(OBJSTRIP) FORCE
+	$(call if_changed,objstrip)
+
+$(obj)/vmlinux.nh.gz: $(obj)/vmlinux.nh FORCE
+	$(call if_changed,gzip)
+
+$(obj)/tools/lxboot: $(obj)/bootloader $(OBJSTRIP) FORCE
+	$(call if_changed,objstrip)
+
+$(obj)/tools/bootlx: $(obj)/bootloader $(OBJSTRIP) FORCE
+	$(call if_changed,objstrip)
+
+$(obj)/tools/bootph: $(obj)/bootpheader $(OBJSTRIP) FORCE
+	$(call if_changed,objstrip)
+
+$(obj)/tools/bootpzh: $(obj)/bootpzheader $(OBJSTRIP) FORCE
+	$(call if_changed,objstrip)
+
+LDFLAGS_bootloader   := -static -uvsprintf -T  #-N -relax
+LDFLAGS_bootpheader  := -static -uvsprintf -T  #-N -relax
+LDFLAGS_bootpzheader := -static -uvsprintf -T  #-N -relax
+
+OBJ_bootlx   := $(obj)/head.o $(obj)/main.o
+OBJ_bootph   := $(obj)/head.o $(obj)/bootp.o
+OBJ_bootpzh  := $(obj)/head.o $(obj)/bootpz.o $(obj)/misc.o
+
+$(obj)/bootloader: $(obj)/bootloader.lds $(OBJ_bootlx) FORCE
+	$(call if_changed,ld)
+
+$(obj)/bootpheader: $(obj)/bootloader.lds $(OBJ_bootph) $(LIBS_Y) FORCE
+	$(call if_changed,ld)
+
+$(obj)/bootpzheader: $(obj)/bootloader.lds $(OBJ_bootpzh) $(LIBS_Y) FORCE
+	$(call if_changed,ld)
+
+$(obj)/misc.o: lib/inflate.c
diff --git a/arch/alpha/boot/bootloader.lds b/arch/alpha/boot/bootloader.lds
new file mode 100644
index 0000000..31c081c
--- /dev/null
+++ b/arch/alpha/boot/bootloader.lds
@@ -0,0 +1,24 @@
+OUTPUT_FORMAT("elf64-alpha")
+ENTRY(__start)
+printk = srm_printk;
+SECTIONS
+{
+  . = 0x20000000;
+  .text : { *(.text) }
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata : { *(.rodata) *(.rodata.*) }
+  .data : { *(.data) CONSTRUCTORS }
+  .got : { *(.got) }
+  .sdata : { *(.sdata) }
+  _edata = .;
+  PROVIDE (edata = .);
+  .sbss : { *(.sbss) *(.scommon) }
+  .bss : { *(.bss) *(COMMON) }
+  _end = . ;
+  PROVIDE (end = .);
+
+  .mdebug 0 : { *(.mdebug) }
+  .note 0 : { *(.note) }
+  .comment 0 : { *(.comment) }
+}
diff --git a/arch/alpha/boot/bootp.c b/arch/alpha/boot/bootp.c
new file mode 100644
index 0000000..ec53c28
--- /dev/null
+++ b/arch/alpha/boot/bootp.c
@@ -0,0 +1,214 @@
+/*
+ * arch/alpha/boot/bootp.c
+ *
+ * Copyright (C) 1997 Jay Estabrook
+ *
+ * This file is used for creating a bootp file for the Linux/AXP kernel
+ *
+ * based significantly on the arch/alpha/boot/main.c of Linus Torvalds
+ */
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/version.h>
+#include <linux/mm.h>
+
+#include <asm/system.h>
+#include <asm/console.h>
+#include <asm/hwrpb.h>
+#include <asm/pgtable.h>
+#include <asm/io.h>
+
+#include <stdarg.h>
+
+#include "ksize.h"
+
+extern unsigned long switch_to_osf_pal(unsigned long nr,
+	struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa,
+	unsigned long *vptb);
+
+extern void move_stack(unsigned long new_stack);
+
+struct hwrpb_struct *hwrpb = INIT_HWRPB;
+static struct pcb_struct pcb_va[1];
+
+/*
+ * Find a physical address of a virtual object..
+ *
+ * This is easy using the virtual page table address.
+ */
+
+static inline void *
+find_pa(unsigned long *vptb, void *ptr)
+{
+	unsigned long address = (unsigned long) ptr;
+	unsigned long result;
+
+	result = vptb[address >> 13];
+	result >>= 32;
+	result <<= 13;
+	result |= address & 0x1fff;
+	return (void *) result;
+}	
+
+/*
+ * This function moves into OSF/1 pal-code, and has a temporary
+ * PCB for that. The kernel proper should replace this PCB with
+ * the real one as soon as possible.
+ *
+ * The page table muckery in here depends on the fact that the boot
+ * code has the L1 page table identity-map itself in the second PTE
+ * in the L1 page table. Thus the L1-page is virtually addressable
+ * itself (through three levels) at virtual address 0x200802000.
+ */
+
+#define VPTB	((unsigned long *) 0x200000000)
+#define L1	((unsigned long *) 0x200802000)
+
+void
+pal_init(void)
+{
+	unsigned long i, rev;
+	struct percpu_struct * percpu;
+	struct pcb_struct * pcb_pa;
+
+	/* Create the dummy PCB.  */
+	pcb_va->ksp = 0;
+	pcb_va->usp = 0;
+	pcb_va->ptbr = L1[1] >> 32;
+	pcb_va->asn = 0;
+	pcb_va->pcc = 0;
+	pcb_va->unique = 0;
+	pcb_va->flags = 1;
+	pcb_va->res1 = 0;
+	pcb_va->res2 = 0;
+	pcb_pa = find_pa(VPTB, pcb_va);
+
+	/*
+	 * a0 = 2 (OSF)
+	 * a1 = return address, but we give the asm the vaddr of the PCB
+	 * a2 = physical addr of PCB
+	 * a3 = new virtual page table pointer
+	 * a4 = KSP (but the asm sets it)
+	 */
+	srm_printk("Switching to OSF PAL-code .. ");
+
+	i = switch_to_osf_pal(2, pcb_va, pcb_pa, VPTB);
+	if (i) {
+		srm_printk("failed, code %ld\n", i);
+		__halt();
+	}
+
+	percpu = (struct percpu_struct *)
+		(INIT_HWRPB->processor_offset + (unsigned long) INIT_HWRPB);
+	rev = percpu->pal_revision = percpu->palcode_avail[2];
+
+	srm_printk("Ok (rev %lx)\n", rev);
+
+	tbia(); /* do it directly in case we are SMP */
+}
+
+static inline void
+load(unsigned long dst, unsigned long src, unsigned long count)
+{
+	memcpy((void *)dst, (void *)src, count);
+}
+
+/*
+ * Start the kernel.
+ */
+static inline void
+runkernel(void)
+{
+	__asm__ __volatile__(
+		"bis %0,%0,$27\n\t"
+		"jmp ($27)"
+		: /* no outputs: it doesn't even return */
+		: "r" (START_ADDR));
+}
+
+extern char _end;
+#define KERNEL_ORIGIN \
+	((((unsigned long)&_end) + 511) & ~511)
+
+void
+start_kernel(void)
+{
+	/*
+	 * Note that this crufty stuff with static and envval
+	 * and envbuf is because:
+	 *
+	 * 1. Frequently, the stack is short, and we don't want to overrun;
+	 * 2. Frequently the stack is where we are going to copy the kernel to;
+	 * 3. A certain SRM console required the GET_ENV output to stack.
+	 *    ??? A comment in the aboot sources indicates that the GET_ENV
+	 *    destination must be quadword aligned.  Might this explain the
+	 *    behaviour, rather than requiring output to the stack, which
+	 *    seems rather far-fetched.
+	 */
+	static long nbytes;
+	static char envval[256] __attribute__((aligned(8)));
+	static unsigned long initrd_start;
+
+	srm_printk("Linux/AXP bootp loader for Linux " UTS_RELEASE "\n");
+	if (INIT_HWRPB->pagesize != 8192) {
+		srm_printk("Expected 8kB pages, got %ldkB\n",
+		           INIT_HWRPB->pagesize >> 10);
+		return;
+	}
+	if (INIT_HWRPB->vptb != (unsigned long) VPTB) {
+		srm_printk("Expected vptb at %p, got %p\n",
+			   VPTB, (void *)INIT_HWRPB->vptb);
+		return;
+	}
+	pal_init();
+
+	/* The initrd must be page-aligned.  See below for the 
+	   cause of the magic number 5.  */
+	initrd_start = ((START_ADDR + 5*KERNEL_SIZE + PAGE_SIZE) |
+			(PAGE_SIZE-1)) + 1;
+#ifdef INITRD_IMAGE_SIZE
+	srm_printk("Initrd positioned at %#lx\n", initrd_start);
+#endif
+
+	/*
+	 * Move the stack to a safe place to ensure it won't be
+	 * overwritten by kernel image.
+	 */
+	move_stack(initrd_start - PAGE_SIZE);
+
+	nbytes = callback_getenv(ENV_BOOTED_OSFLAGS, envval, sizeof(envval));
+	if (nbytes < 0 || nbytes >= sizeof(envval)) {
+		nbytes = 0;
+	}
+	envval[nbytes] = '\0';
+	srm_printk("Loading the kernel...'%s'\n", envval);
+
+	/* NOTE: *no* callbacks or printouts from here on out!!! */
+
+	/* This is a hack, as some consoles seem to get virtual 20000000 (ie
+	 * where the SRM console puts the kernel bootp image) memory
+	 * overlapping physical memory where the kernel wants to be put,
+	 * which causes real problems when attempting to copy the former to
+	 * the latter... :-(
+	 *
+	 * So, we first move the kernel virtual-to-physical way above where
+	 * we physically want the kernel to end up, then copy it from there
+	 * to its final resting place... ;-}
+	 *
+	 * Sigh...  */
+
+#ifdef INITRD_IMAGE_SIZE
+	load(initrd_start, KERNEL_ORIGIN+KERNEL_SIZE, INITRD_IMAGE_SIZE);
+#endif
+        load(START_ADDR+(4*KERNEL_SIZE), KERNEL_ORIGIN, KERNEL_SIZE);
+        load(START_ADDR, START_ADDR+(4*KERNEL_SIZE), KERNEL_SIZE);
+
+	memset((char*)ZERO_PGE, 0, PAGE_SIZE);
+	strcpy((char*)ZERO_PGE, envval);
+#ifdef INITRD_IMAGE_SIZE
+	((long *)(ZERO_PGE+256))[0] = initrd_start;
+	((long *)(ZERO_PGE+256))[1] = INITRD_IMAGE_SIZE;
+#endif
+
+	runkernel();
+}
diff --git a/arch/alpha/boot/bootpz.c b/arch/alpha/boot/bootpz.c
new file mode 100644
index 0000000..a6657f2
--- /dev/null
+++ b/arch/alpha/boot/bootpz.c
@@ -0,0 +1,469 @@
+/*
+ * arch/alpha/boot/bootpz.c
+ *
+ * Copyright (C) 1997 Jay Estabrook
+ *
+ * This file is used for creating a compressed BOOTP file for the
+ * Linux/AXP kernel
+ *
+ * based significantly on the arch/alpha/boot/main.c of Linus Torvalds
+ * and the decompression code from MILO.
+ */
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/version.h>
+#include <linux/mm.h>
+
+#include <asm/system.h>
+#include <asm/console.h>
+#include <asm/hwrpb.h>
+#include <asm/pgtable.h>
+#include <asm/io.h>
+
+#include <stdarg.h>
+
+#include "kzsize.h"
+
+/* FIXME FIXME FIXME */
+#define MALLOC_AREA_SIZE 0x200000 /* 2MB for now */
+/* FIXME FIXME FIXME */
+
+
+/*
+  WARNING NOTE
+
+  It is very possible that turning on additional messages may cause
+  kernel image corruption due to stack usage to do the printing.
+
+*/
+
+#undef DEBUG_CHECK_RANGE
+#undef DEBUG_ADDRESSES
+#undef DEBUG_LAST_STEPS
+
+extern unsigned long switch_to_osf_pal(unsigned long nr,
+	struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa,
+	unsigned long *vptb);
+
+extern int decompress_kernel(void* destination, void *source,
+			     size_t ksize, size_t kzsize);
+
+extern void move_stack(unsigned long new_stack);
+
+struct hwrpb_struct *hwrpb = INIT_HWRPB;
+static struct pcb_struct pcb_va[1];
+
+/*
+ * Find a physical address of a virtual object..
+ *
+ * This is easy using the virtual page table address.
+ */
+#define VPTB	((unsigned long *) 0x200000000)
+
+static inline unsigned long
+find_pa(unsigned long address)
+{
+	unsigned long result;
+
+	result = VPTB[address >> 13];
+	result >>= 32;
+	result <<= 13;
+	result |= address & 0x1fff;
+	return result;
+}	
+
+int
+check_range(unsigned long vstart, unsigned long vend,
+	    unsigned long kstart, unsigned long kend)
+{
+	unsigned long vaddr, kaddr;
+
+#ifdef DEBUG_CHECK_RANGE
+	srm_printk("check_range: V[0x%lx:0x%lx] K[0x%lx:0x%lx]\n",
+		   vstart, vend, kstart, kend);
+#endif
+	/* do some range checking for detecting an overlap... */
+	for (vaddr = vstart; vaddr <= vend; vaddr += PAGE_SIZE)
+	{
+		kaddr = (find_pa(vaddr) | PAGE_OFFSET);
+		if (kaddr >= kstart && kaddr <= kend)
+		{
+#ifdef DEBUG_CHECK_RANGE
+			srm_printk("OVERLAP: vaddr 0x%lx kaddr 0x%lx"
+				   " [0x%lx:0x%lx]\n",
+				   vaddr, kaddr, kstart, kend);
+#endif
+			return 1;
+		}
+	}
+	return 0;
+}
+
+/*
+ * This function moves into OSF/1 pal-code, and has a temporary
+ * PCB for that. The kernel proper should replace this PCB with
+ * the real one as soon as possible.
+ *
+ * The page table muckery in here depends on the fact that the boot
+ * code has the L1 page table identity-map itself in the second PTE
+ * in the L1 page table. Thus the L1-page is virtually addressable
+ * itself (through three levels) at virtual address 0x200802000.
+ */
+
+#define L1	((unsigned long *) 0x200802000)
+
+void
+pal_init(void)
+{
+	unsigned long i, rev;
+	struct percpu_struct * percpu;
+	struct pcb_struct * pcb_pa;
+
+	/* Create the dummy PCB.  */
+	pcb_va->ksp = 0;
+	pcb_va->usp = 0;
+	pcb_va->ptbr = L1[1] >> 32;
+	pcb_va->asn = 0;
+	pcb_va->pcc = 0;
+	pcb_va->unique = 0;
+	pcb_va->flags = 1;
+	pcb_va->res1 = 0;
+	pcb_va->res2 = 0;
+	pcb_pa = (struct pcb_struct *)find_pa((unsigned long)pcb_va);
+
+	/*
+	 * a0 = 2 (OSF)
+	 * a1 = return address, but we give the asm the vaddr of the PCB
+	 * a2 = physical addr of PCB
+	 * a3 = new virtual page table pointer
+	 * a4 = KSP (but the asm sets it)
+	 */
+	srm_printk("Switching to OSF PAL-code... ");
+
+	i = switch_to_osf_pal(2, pcb_va, pcb_pa, VPTB);
+	if (i) {
+		srm_printk("failed, code %ld\n", i);
+		__halt();
+	}
+
+	percpu = (struct percpu_struct *)
+		(INIT_HWRPB->processor_offset + (unsigned long) INIT_HWRPB);
+	rev = percpu->pal_revision = percpu->palcode_avail[2];
+
+	srm_printk("OK (rev %lx)\n", rev);
+
+	tbia(); /* do it directly in case we are SMP */
+}
+
+/*
+ * Start the kernel.
+ */
+static inline void
+runkernel(void)
+{
+	__asm__ __volatile__(
+		"bis %0,%0,$27\n\t"
+		"jmp ($27)"
+		: /* no outputs: it doesn't even return */
+		: "r" (START_ADDR));
+}
+
+/* Must record the SP (it is virtual) on entry, so we can make sure
+   not to overwrite it during movement or decompression. */
+unsigned long SP_on_entry;
+
+/* Calculate the kernel image address based on the end of the BOOTP
+   bootstrapper (ie this program).
+*/
+extern char _end;
+#define KERNEL_ORIGIN \
+	((((unsigned long)&_end) + 511) & ~511)
+
+/* Round address to next higher page boundary. */
+#define NEXT_PAGE(a)	(((a) | (PAGE_SIZE - 1)) + 1)
+
+#ifdef INITRD_IMAGE_SIZE
+# define REAL_INITRD_SIZE INITRD_IMAGE_SIZE
+#else
+# define REAL_INITRD_SIZE 0
+#endif
+
+/* Defines from include/asm-alpha/system.h
+
+	BOOT_ADDR	Virtual address at which the consoles loads
+			the BOOTP image.
+
+	KERNEL_START    KSEG address at which the kernel is built to run,
+			which includes some initial data pages before the
+			code.
+
+	START_ADDR	KSEG address of the entry point of kernel code.
+
+	ZERO_PGE	KSEG address of page full of zeroes, but 
+			upon entry to kerne cvan be expected
+			to hold the parameter list and possible
+			INTRD information.
+
+   These are used in the local defines below.
+*/
+  
+
+/* Virtual addresses for the BOOTP image. Note that this includes the
+   bootstrapper code as well as the compressed kernel image, and
+   possibly the INITRD image.
+
+   Oh, and do NOT forget the STACK, which appears to be placed virtually
+   beyond the end of the loaded image.
+*/
+#define V_BOOT_IMAGE_START	BOOT_ADDR
+#define V_BOOT_IMAGE_END	SP_on_entry
+
+/* Virtual addresses for just the bootstrapper part of the BOOTP image. */
+#define V_BOOTSTRAPPER_START	BOOT_ADDR
+#define V_BOOTSTRAPPER_END	KERNEL_ORIGIN
+
+/* Virtual addresses for just the data part of the BOOTP
+   image. This may also include the INITRD image, but always
+   includes the STACK.
+*/
+#define V_DATA_START		KERNEL_ORIGIN
+#define V_INITRD_START		(KERNEL_ORIGIN + KERNEL_Z_SIZE)
+#define V_INTRD_END		(V_INITRD_START + REAL_INITRD_SIZE)
+#define V_DATA_END	 	V_BOOT_IMAGE_END
+
+/* KSEG addresses for the uncompressed kernel.
+
+   Note that the end address includes workspace for the decompression.
+   Note also that the DATA_START address is ZERO_PGE, to which we write
+   just before jumping to the kernel image at START_ADDR.
+ */
+#define K_KERNEL_DATA_START	ZERO_PGE
+#define K_KERNEL_IMAGE_START	START_ADDR
+#define K_KERNEL_IMAGE_END	(START_ADDR + KERNEL_SIZE)
+
+/* Define to where we may have to decompress the kernel image, before
+   we move it to the final position, in case of overlap. This will be
+   above the final position of the kernel.
+
+   Regardless of overlap, we move the INITRD image to the end of this
+   copy area, because there needs to be a buffer area after the kernel
+   for "bootmem" anyway.
+*/
+#define K_COPY_IMAGE_START	NEXT_PAGE(K_KERNEL_IMAGE_END)
+/* Reserve one page below INITRD for the new stack. */
+#define K_INITRD_START \
+    NEXT_PAGE(K_COPY_IMAGE_START + KERNEL_SIZE + PAGE_SIZE)
+#define K_COPY_IMAGE_END \
+    (K_INITRD_START + REAL_INITRD_SIZE + MALLOC_AREA_SIZE)
+#define K_COPY_IMAGE_SIZE \
+    NEXT_PAGE(K_COPY_IMAGE_END - K_COPY_IMAGE_START)
+
+void
+start_kernel(void)
+{
+	int must_move = 0;
+
+	/* Initialize these for the decompression-in-place situation,
+	   which is the smallest amount of work and most likely to
+	   occur when using the normal START_ADDR of the kernel
+	   (currently set to 16MB, to clear all console code.
+	*/
+	unsigned long uncompressed_image_start = K_KERNEL_IMAGE_START;
+	unsigned long uncompressed_image_end = K_KERNEL_IMAGE_END;
+
+	unsigned long initrd_image_start = K_INITRD_START;
+
+	/*
+	 * Note that this crufty stuff with static and envval
+	 * and envbuf is because:
+	 *
+	 * 1. Frequently, the stack is short, and we don't want to overrun;
+	 * 2. Frequently the stack is where we are going to copy the kernel to;
+	 * 3. A certain SRM console required the GET_ENV output to stack.
+	 *    ??? A comment in the aboot sources indicates that the GET_ENV
+	 *    destination must be quadword aligned.  Might this explain the
+	 *    behaviour, rather than requiring output to the stack, which
+	 *    seems rather far-fetched.
+	 */
+	static long nbytes;
+	static char envval[256] __attribute__((aligned(8)));
+	register unsigned long asm_sp asm("30");
+
+	SP_on_entry = asm_sp;
+
+	srm_printk("Linux/Alpha BOOTPZ Loader for Linux " UTS_RELEASE "\n");
+
+	/* Validity check the HWRPB. */
+	if (INIT_HWRPB->pagesize != 8192) {
+		srm_printk("Expected 8kB pages, got %ldkB\n",
+		           INIT_HWRPB->pagesize >> 10);
+		return;
+	}
+	if (INIT_HWRPB->vptb != (unsigned long) VPTB) {
+		srm_printk("Expected vptb at %p, got %p\n",
+			   VPTB, (void *)INIT_HWRPB->vptb);
+		return;
+	}
+
+	/* PALcode (re)initialization. */
+	pal_init();
+
+	/* Get the parameter list from the console environment variable. */
+	nbytes = callback_getenv(ENV_BOOTED_OSFLAGS, envval, sizeof(envval));
+	if (nbytes < 0 || nbytes >= sizeof(envval)) {
+		nbytes = 0;
+	}
+	envval[nbytes] = '\0';
+
+#ifdef DEBUG_ADDRESSES
+	srm_printk("START_ADDR 0x%lx\n", START_ADDR);
+	srm_printk("KERNEL_ORIGIN 0x%lx\n", KERNEL_ORIGIN);
+	srm_printk("KERNEL_SIZE 0x%x\n", KERNEL_SIZE);
+	srm_printk("KERNEL_Z_SIZE 0x%x\n", KERNEL_Z_SIZE);
+#endif
+
+	/* Since all the SRM consoles load the BOOTP image at virtual
+	 * 0x20000000, we have to ensure that the physical memory
+	 * pages occupied by that image do NOT overlap the physical
+	 * address range where the kernel wants to be run.  This
+	 * causes real problems when attempting to cdecompress the
+	 * former into the latter... :-(
+	 *
+	 * So, we may have to decompress/move the kernel/INITRD image
+	 * virtual-to-physical someplace else first before moving
+	 * kernel /INITRD to their final resting places... ;-}
+	 *
+	 * Sigh...
+	 */
+
+	/* First, check to see if the range of addresses occupied by
+	   the bootstrapper part of the BOOTP image include any of the
+	   physical pages into which the kernel will be placed for
+	   execution.
+
+	   We only need check on the final kernel image range, since we
+	   will put the INITRD someplace that we can be sure is not
+	   in conflict.
+	 */
+	if (check_range(V_BOOTSTRAPPER_START, V_BOOTSTRAPPER_END,
+			K_KERNEL_DATA_START, K_KERNEL_IMAGE_END))
+	{
+		srm_printk("FATAL ERROR: overlap of bootstrapper code\n");
+		__halt();
+	}
+
+	/* Next, check to see if the range of addresses occupied by
+	   the compressed kernel/INITRD/stack portion of the BOOTP
+	   image include any of the physical pages into which the
+	   decompressed kernel or the INITRD will be placed for
+	   execution.
+	 */
+	if (check_range(V_DATA_START, V_DATA_END,
+			K_KERNEL_IMAGE_START, K_COPY_IMAGE_END))
+	{
+#ifdef DEBUG_ADDRESSES
+		srm_printk("OVERLAP: cannot decompress in place\n");
+#endif
+		uncompressed_image_start = K_COPY_IMAGE_START;
+		uncompressed_image_end = K_COPY_IMAGE_END;
+		must_move = 1;
+
+		/* Finally, check to see if the range of addresses
+		   occupied by the compressed kernel/INITRD part of
+		   the BOOTP image include any of the physical pages
+		   into which that part is to be copied for
+		   decompression.
+		*/
+		while (check_range(V_DATA_START, V_DATA_END,
+				   uncompressed_image_start,
+				   uncompressed_image_end))
+		{
+#if 0
+			uncompressed_image_start += K_COPY_IMAGE_SIZE;
+			uncompressed_image_end += K_COPY_IMAGE_SIZE;
+			initrd_image_start += K_COPY_IMAGE_SIZE;
+#else
+			/* Keep as close as possible to end of BOOTP image. */
+			uncompressed_image_start += PAGE_SIZE;
+			uncompressed_image_end += PAGE_SIZE;
+			initrd_image_start += PAGE_SIZE;
+#endif
+		}
+	}
+
+	srm_printk("Starting to load the kernel with args '%s'\n", envval);
+
+#ifdef DEBUG_ADDRESSES
+	srm_printk("Decompressing the kernel...\n"
+		   "...from 0x%lx to 0x%lx size 0x%x\n",
+		   V_DATA_START,
+		   uncompressed_image_start,
+		   KERNEL_SIZE);
+#endif
+        decompress_kernel((void *)uncompressed_image_start,
+			  (void *)V_DATA_START,
+			  KERNEL_SIZE, KERNEL_Z_SIZE);
+
+	/*
+	 * Now, move things to their final positions, if/as required.
+	 */
+
+#ifdef INITRD_IMAGE_SIZE
+
+	/* First, we always move the INITRD image, if present. */
+#ifdef DEBUG_ADDRESSES
+	srm_printk("Moving the INITRD image...\n"
+		   " from 0x%lx to 0x%lx size 0x%x\n",
+		   V_INITRD_START,
+		   initrd_image_start,
+		   INITRD_IMAGE_SIZE);
+#endif
+	memcpy((void *)initrd_image_start, (void *)V_INITRD_START,
+	       INITRD_IMAGE_SIZE);
+
+#endif /* INITRD_IMAGE_SIZE */
+
+	/* Next, we may have to move the uncompressed kernel to the
+	   final destination.
+	 */
+	if (must_move) {
+#ifdef DEBUG_ADDRESSES
+		srm_printk("Moving the uncompressed kernel...\n"
+			   "...from 0x%lx to 0x%lx size 0x%x\n",
+			   uncompressed_image_start,
+			   K_KERNEL_IMAGE_START,
+			   (unsigned)KERNEL_SIZE);
+#endif
+		/*
+		 * Move the stack to a safe place to ensure it won't be
+		 * overwritten by kernel image.
+		 */
+		move_stack(initrd_image_start - PAGE_SIZE);
+
+		memcpy((void *)K_KERNEL_IMAGE_START,
+		       (void *)uncompressed_image_start, KERNEL_SIZE);
+	}
+	
+	/* Clear the zero page, then move the argument list in. */
+#ifdef DEBUG_LAST_STEPS
+	srm_printk("Preparing ZERO_PGE...\n");
+#endif
+	memset((char*)ZERO_PGE, 0, PAGE_SIZE);
+	strcpy((char*)ZERO_PGE, envval);
+
+#ifdef INITRD_IMAGE_SIZE
+
+#ifdef DEBUG_LAST_STEPS
+	srm_printk("Preparing INITRD info...\n");
+#endif
+	/* Finally, set the INITRD paramenters for the kernel. */
+	((long *)(ZERO_PGE+256))[0] = initrd_image_start;
+	((long *)(ZERO_PGE+256))[1] = INITRD_IMAGE_SIZE;
+
+#endif /* INITRD_IMAGE_SIZE */
+
+#ifdef DEBUG_LAST_STEPS
+	srm_printk("Doing 'runkernel()'...\n");
+#endif
+	runkernel();
+}
diff --git a/arch/alpha/boot/head.S b/arch/alpha/boot/head.S
new file mode 100644
index 0000000..f3d9808
--- /dev/null
+++ b/arch/alpha/boot/head.S
@@ -0,0 +1,123 @@
+/*
+ * arch/alpha/boot/head.S
+ *
+ * initial bootloader stuff..
+ */
+
+#include <asm/system.h>
+
+	.set noreorder
+	.globl	__start
+	.ent	__start
+__start:
+	br	$29,2f
+2:	ldgp	$29,0($29)
+	jsr	$26,start_kernel
+	call_pal PAL_halt
+	.end __start
+
+	.align 5
+	.globl	wrent
+	.ent	wrent
+wrent:
+	.prologue 0
+	call_pal PAL_wrent
+	ret ($26)
+	.end wrent
+
+	.align 5
+	.globl	wrkgp
+	.ent	wrkgp
+wrkgp:
+	.prologue 0
+	call_pal PAL_wrkgp
+	ret ($26)
+	.end wrkgp
+
+	.align 5
+	.globl	switch_to_osf_pal
+	.ent	switch_to_osf_pal
+switch_to_osf_pal:
+	subq	$30,128,$30
+	.frame	$30,128,$26
+	stq	$26,0($30)
+	stq	$1,8($30)
+	stq	$2,16($30)
+	stq	$3,24($30)
+	stq	$4,32($30)
+	stq	$5,40($30)
+	stq	$6,48($30)
+	stq	$7,56($30)
+	stq	$8,64($30)
+	stq	$9,72($30)
+	stq	$10,80($30)
+	stq	$11,88($30)
+	stq	$12,96($30)
+	stq	$13,104($30)
+	stq	$14,112($30)
+	stq	$15,120($30)
+	.prologue 0
+
+	stq	$30,0($17)	/* save KSP in PCB */
+
+	bis	$30,$30,$20	/* a4 = KSP */
+	br	$17,1f
+
+	ldq	$26,0($30)
+	ldq	$1,8($30)
+	ldq	$2,16($30)
+	ldq	$3,24($30)
+	ldq	$4,32($30)
+	ldq	$5,40($30)
+	ldq	$6,48($30)
+	ldq	$7,56($30)
+	ldq	$8,64($30)
+	ldq	$9,72($30)
+	ldq	$10,80($30)
+	ldq	$11,88($30)
+	ldq	$12,96($30)
+	ldq	$13,104($30)
+	ldq	$14,112($30)
+	ldq	$15,120($30)
+	addq	$30,128,$30
+	ret ($26)
+1:	call_pal PAL_swppal
+	.end	switch_to_osf_pal
+
+	.align 3
+	.globl	tbi
+	.ent	tbi
+tbi:
+	.prologue 0
+	call_pal PAL_tbi
+	ret	($26)
+	.end tbi
+
+	.align 3
+	.globl	halt
+	.ent	halt
+halt:
+	.prologue 0
+	call_pal PAL_halt
+	.end halt
+
+/* $16 - new stack page */
+	.align 3
+	.globl	move_stack
+	.ent	move_stack
+move_stack:
+	.prologue 0
+	lda	$0, 0x1fff($31)
+	and	$0, $30, $1			/* Stack offset */
+	or	$1, $16, $16			/* New stack pointer */
+	mov	$30, $1
+	mov	$16, $2
+1:	ldq	$3, 0($1)			/* Move the stack */
+	addq	$1, 8, $1
+	stq	$3, 0($2)
+	and	$0, $1, $4
+	addq	$2, 8, $2
+	bne	$4, 1b
+	mov	$16, $30
+	ret	($26)
+	.end move_stack
diff --git a/arch/alpha/boot/main.c b/arch/alpha/boot/main.c
new file mode 100644
index 0000000..78c9b0b
--- /dev/null
+++ b/arch/alpha/boot/main.c
@@ -0,0 +1,191 @@
+/*
+ * arch/alpha/boot/main.c
+ *
+ * Copyright (C) 1994, 1995 Linus Torvalds
+ *
+ * This file is the bootloader for the Linux/AXP kernel
+ */
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/version.h>
+#include <linux/mm.h>
+
+#include <asm/system.h>
+#include <asm/console.h>
+#include <asm/hwrpb.h>
+#include <asm/pgtable.h>
+
+#include <stdarg.h>
+
+#include "ksize.h"
+
+extern int vsprintf(char *, const char *, va_list);
+extern unsigned long switch_to_osf_pal(unsigned long nr,
+	struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa,
+	unsigned long *vptb);
+struct hwrpb_struct *hwrpb = INIT_HWRPB;
+static struct pcb_struct pcb_va[1];
+
+/*
+ * Find a physical address of a virtual object..
+ *
+ * This is easy using the virtual page table address.
+ */
+
+static inline void *
+find_pa(unsigned long *vptb, void *ptr)
+{
+	unsigned long address = (unsigned long) ptr;
+	unsigned long result;
+
+	result = vptb[address >> 13];
+	result >>= 32;
+	result <<= 13;
+	result |= address & 0x1fff;
+	return (void *) result;
+}	
+
+/*
+ * This function moves into OSF/1 pal-code, and has a temporary
+ * PCB for that. The kernel proper should replace this PCB with
+ * the real one as soon as possible.
+ *
+ * The page table muckery in here depends on the fact that the boot
+ * code has the L1 page table identity-map itself in the second PTE
+ * in the L1 page table. Thus the L1-page is virtually addressable
+ * itself (through three levels) at virtual address 0x200802000.
+ */
+
+#define VPTB	((unsigned long *) 0x200000000)
+#define L1	((unsigned long *) 0x200802000)
+
+void
+pal_init(void)
+{
+	unsigned long i, rev;
+	struct percpu_struct * percpu;
+	struct pcb_struct * pcb_pa;
+
+	/* Create the dummy PCB.  */
+	pcb_va->ksp = 0;
+	pcb_va->usp = 0;
+	pcb_va->ptbr = L1[1] >> 32;
+	pcb_va->asn = 0;
+	pcb_va->pcc = 0;
+	pcb_va->unique = 0;
+	pcb_va->flags = 1;
+	pcb_va->res1 = 0;
+	pcb_va->res2 = 0;
+	pcb_pa = find_pa(VPTB, pcb_va);
+
+	/*
+	 * a0 = 2 (OSF)
+	 * a1 = return address, but we give the asm the vaddr of the PCB
+	 * a2 = physical addr of PCB
+	 * a3 = new virtual page table pointer
+	 * a4 = KSP (but the asm sets it)
+	 */
+	srm_printk("Switching to OSF PAL-code .. ");
+
+	i = switch_to_osf_pal(2, pcb_va, pcb_pa, VPTB);
+	if (i) {
+		srm_printk("failed, code %ld\n", i);
+		__halt();
+	}
+
+	percpu = (struct percpu_struct *)
+		(INIT_HWRPB->processor_offset + (unsigned long) INIT_HWRPB);
+	rev = percpu->pal_revision = percpu->palcode_avail[2];
+
+	srm_printk("Ok (rev %lx)\n", rev);
+
+	tbia(); /* do it directly in case we are SMP */
+}
+
+static inline long openboot(void)
+{
+	char bootdev[256];
+	long result;
+
+	result = callback_getenv(ENV_BOOTED_DEV, bootdev, 255);
+	if (result < 0)
+		return result;
+	return callback_open(bootdev, result & 255);
+}
+
+static inline long close(long dev)
+{
+	return callback_close(dev);
+}
+
+static inline long load(long dev, unsigned long addr, unsigned long count)
+{
+	char bootfile[256];
+	extern char _end;
+	long result, boot_size = &_end - (char *) BOOT_ADDR;
+
+	result = callback_getenv(ENV_BOOTED_FILE, bootfile, 255);
+	if (result < 0)
+		return result;
+	result &= 255;
+	bootfile[result] = '\0';
+	if (result)
+		srm_printk("Boot file specification (%s) not implemented\n",
+		       bootfile);
+	return callback_read(dev, count, addr, boot_size/512 + 1);
+}
+
+/*
+ * Start the kernel.
+ */
+static void runkernel(void)
+{
+	__asm__ __volatile__(
+		"bis %1,%1,$30\n\t"
+		"bis %0,%0,$26\n\t"
+		"ret ($26)"
+		: /* no outputs: it doesn't even return */
+		: "r" (START_ADDR),
+		  "r" (PAGE_SIZE + INIT_STACK));
+}
+
+void start_kernel(void)
+{
+	long i;
+	long dev;
+	int nbytes;
+	char envval[256];
+
+	srm_printk("Linux/AXP bootloader for Linux " UTS_RELEASE "\n");
+	if (INIT_HWRPB->pagesize != 8192) {
+		srm_printk("Expected 8kB pages, got %ldkB\n", INIT_HWRPB->pagesize >> 10);
+		return;
+	}
+	pal_init();
+	dev = openboot();
+	if (dev < 0) {
+		srm_printk("Unable to open boot device: %016lx\n", dev);
+		return;
+	}
+	dev &= 0xffffffff;
+	srm_printk("Loading vmlinux ...");
+	i = load(dev, START_ADDR, KERNEL_SIZE);
+	close(dev);
+	if (i != KERNEL_SIZE) {
+		srm_printk("Failed (%lx)\n", i);
+		return;
+	}
+
+	nbytes = callback_getenv(ENV_BOOTED_OSFLAGS, envval, sizeof(envval));
+	if (nbytes < 0) {
+		nbytes = 0;
+	}
+	envval[nbytes] = '\0';
+	strcpy((char*)ZERO_PGE, envval);
+
+	srm_printk(" Ok\nNow booting the kernel\n");
+	runkernel();
+	for (i = 0 ; i < 0x100000000 ; i++)
+		/* nothing */;
+	__halt();
+}
diff --git a/arch/alpha/boot/misc.c b/arch/alpha/boot/misc.c
new file mode 100644
index 0000000..1d65adf
--- /dev/null
+++ b/arch/alpha/boot/misc.c
@@ -0,0 +1,207 @@
+/*
+ * misc.c
+ * 
+ * This is a collection of several routines from gzip-1.0.3 
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ *
+ * Modified for ARM Linux by Russell King
+ *
+ * Nicolas Pitre <nico@visuaide.com>  1999/04/14 :
+ *  For this code to run directly from Flash, all constant variables must
+ *  be marked with 'const' and all other variables initialized at run-time 
+ *  only.  This way all non constant variables will end up in the bss segment,
+ *  which should point to addresses in RAM and cleared to 0 on start.
+ *  This allows for a much quicker boot time.
+ *
+ * Modified for Alpha, from the ARM version, by Jay Estabrook 2003.
+ */
+
+#include <linux/kernel.h>
+
+#include <asm/uaccess.h>
+
+#define memzero(s,n)	memset ((s),0,(n))
+#define puts		srm_printk
+extern long srm_printk(const char *, ...)
+     __attribute__ ((format (printf, 1, 2)));
+
+/*
+ * gzip delarations
+ */
+#define OF(args)  args
+#define STATIC static
+
+typedef unsigned char  uch;
+typedef unsigned short ush;
+typedef unsigned long  ulg;
+
+#define WSIZE 0x8000		/* Window size must be at least 32k, */
+				/* and a power of two */
+
+static uch *inbuf;		/* input buffer */
+static uch *window;		/* Sliding window buffer */
+
+static unsigned insize;		/* valid bytes in inbuf */
+static unsigned inptr;		/* index of next byte to be processed in inbuf */
+static unsigned outcnt;		/* bytes in output buffer */
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
+#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
+#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
+#define COMMENT      0x10 /* bit 4 set: file comment present */
+#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
+#define RESERVED     0xC0 /* bit 6,7:   reserved */
+
+#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
+
+/* Diagnostic functions */
+#ifdef DEBUG
+#  define Assert(cond,msg) {if(!(cond)) error(msg);}
+#  define Trace(x) fprintf x
+#  define Tracev(x) {if (verbose) fprintf x ;}
+#  define Tracevv(x) {if (verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+static int  fill_inbuf(void);
+static void flush_window(void);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+static char *input_data;
+static int  input_data_size;
+
+static uch *output_data;
+static ulg output_ptr;
+static ulg bytes_out;
+
+static void *malloc(int size);
+static void free(void *where);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+extern int end;
+static ulg free_mem_ptr;
+static ulg free_mem_ptr_end;
+
+#define HEAP_SIZE 0x2000
+
+#include "../../../lib/inflate.c"
+
+static void *malloc(int size)
+{
+	void *p;
+
+	if (size <0) error("Malloc error");
+	if (free_mem_ptr <= 0) error("Memory error");
+
+	free_mem_ptr = (free_mem_ptr + 3) & ~3;	/* Align */
+
+	p = (void *)free_mem_ptr;
+	free_mem_ptr += size;
+
+	if (free_mem_ptr >= free_mem_ptr_end)
+		error("Out of memory");
+	return p;
+}
+
+static void free(void *where)
+{ /* gzip_mark & gzip_release do the free */
+}
+
+static void gzip_mark(void **ptr)
+{
+	*ptr = (void *) free_mem_ptr;
+}
+
+static void gzip_release(void **ptr)
+{
+	free_mem_ptr = (long) *ptr;
+}
+
+/* ===========================================================================
+ * Fill the input buffer. This is called only when the buffer is empty
+ * and at least one byte is really needed.
+ */
+int fill_inbuf(void)
+{
+	if (insize != 0)
+		error("ran out of input data");
+
+	inbuf = input_data;
+	insize = input_data_size;
+
+	inptr = 1;
+	return inbuf[0];
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+void flush_window(void)
+{
+	ulg c = crc;
+	unsigned n;
+	uch *in, *out, ch;
+
+	in = window;
+	out = &output_data[output_ptr];
+	for (n = 0; n < outcnt; n++) {
+		ch = *out++ = *in++;
+		c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+	}
+	crc = c;
+	bytes_out += (ulg)outcnt;
+	output_ptr += (ulg)outcnt;
+	outcnt = 0;
+/*	puts("."); */
+}
+
+static void error(char *x)
+{
+	puts("\n\n");
+	puts(x);
+	puts("\n\n -- System halted");
+
+	while(1);	/* Halt */
+}
+
+unsigned int
+decompress_kernel(void *output_start,
+		  void *input_start,
+		  size_t ksize,
+		  size_t kzsize)
+{
+	output_data		= (uch *)output_start;
+	input_data		= (uch *)input_start;
+	input_data_size		= kzsize; /* use compressed size */
+
+	/* FIXME FIXME FIXME */
+	free_mem_ptr		= (ulg)output_start + ksize;
+	free_mem_ptr_end	= (ulg)output_start + ksize + 0x200000;
+	/* FIXME FIXME FIXME */
+
+	/* put in temp area to reduce initial footprint */
+	window = malloc(WSIZE);
+
+	makecrc();
+/*	puts("Uncompressing Linux..."); */
+	gunzip();
+/*	puts(" done, booting the kernel.\n"); */
+	return output_ptr;
+}
diff --git a/arch/alpha/boot/tools/mkbb.c b/arch/alpha/boot/tools/mkbb.c
new file mode 100644
index 0000000..23c7190
--- /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 0000000..67beb1b
--- /dev/null
+++ b/arch/alpha/boot/tools/objstrip.c
@@ -0,0 +1,281 @@
+/*
+ * 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 immediately
+ * 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 <string.h>
+#include <stdlib.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 <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)) {
+	    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;
+}