diff -u --recursive v1.1.33/linux/Makefile linux/Makefile
--- v1.1.33/linux/Makefile	Fri Jul 22 16:40:59 1994
+++ linux/Makefile	Fri Jul 22 16:11:08 1994
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 1
-SUBLEVEL = 33
+SUBLEVEL = 34
 
 all:	Version zImage
 
@@ -79,9 +79,21 @@
 AS86	=as86 -0 -a
 LD86	=ld86 -0
 
+# 
+# Set these to indicate how to link it..
+#
+# -zmagic:
+#
+#LOWLDFLAGS	= -Ttext 0x1000
+#HIGHLDFLAGS	= -Ttext 0x100000
+#
+# -qmagic (we need to remove the 32 byte header for bootup purposes)
+#
+LOWLDFLAGS	=-qmagic -Ttext 0xfe0
+HIGHLDFLAGS	=-qmagic -Ttext 0xfffe0
+
 AS	=as
 LD	=ld
-LDFLAGS	=#-qmagic
 HOSTCC	=gcc
 CC	=gcc -D__KERNEL__ -I$(TOPDIR)/include
 MAKE	=make
@@ -156,7 +168,7 @@
 	$(CC) $(CFLAGS) $(PROFILING) -c -o $*.o $<
 
 tools/system:	boot/head.o init/main.o tools/version.o linuxsubdirs
-	$(LD) $(LDFLAGS) -Ttext 1000 boot/head.o init/main.o tools/version.o \
+	$(LD) $(LOWLDFLAGS) boot/head.o init/main.o tools/version.o \
 		$(ARCHIVES) \
 		$(FILESYSTEMS) \
 		$(DRIVERS) \
@@ -201,7 +213,7 @@
 	if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
 
 tools/zSystem:	boot/head.o init/main.o tools/version.o linuxsubdirs
-	$(LD) $(LDFLAGS) -Ttext 100000 boot/head.o init/main.o tools/version.o \
+	$(LD) $(HIGHLDFLAGS) boot/head.o init/main.o tools/version.o \
 		$(ARCHIVES) \
 		$(FILESYSTEMS) \
 		$(DRIVERS) \
diff -u --recursive v1.1.33/linux/boot/setup.S linux/boot/setup.S
--- v1.1.33/linux/boot/setup.S	Thu Jul  7 21:37:11 1994
+++ linux/boot/setup.S	Fri Jul 22 11:57:54 1994
@@ -14,8 +14,8 @@
 ! Move PS/2 aux init code to psaux.c
 ! (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92
 !
-! some changes and additional features by Christoph Niemann, March 1993
-! (niemann@rubdv15.ETDV.Ruhr-Uni-Bochum.De)
+! some changes and additional features by Christoph Niemann,
+! March 1993/June 1994 (Christoph.Niemann@linux.org)
 !
 
 ! NOTE! These had better be the same as in bootsect.s!
@@ -97,9 +97,11 @@
 	mov	ds,ax
 	lds	si,[4*0x41]
 	mov	ax,#INITSEG
+	push	ax
 	mov	es,ax
 	mov	di,#0x0080
 	mov	cx,#0x10
+	push	cx
 	cld
 	rep
 	movsb
@@ -109,11 +111,9 @@
 	xor	ax,ax		! clear ax
 	mov	ds,ax
 	lds	si,[4*0x46]
-	mov	ax,#INITSEG
-	mov	es,ax
+	pop	cx
+	pop	es
 	mov	di,#0x0090
-	mov	cx,#0x10
-	cld
 	rep
 	movsb
 
@@ -159,7 +159,7 @@
 	cld			! 'direction'=0, movs moves forward
 do_move:
 	mov	es,ax		! destination segment
-	add	ax,#0x100
+	inc	ah		! instead of add ax,#0x100
 	cmp	ax,#0x9000
 	jz	end_move
 	mov	ds,bx		! source segment
@@ -246,7 +246,8 @@
 ! Note that the short jump isn't strictly needed, althought there are
 ! reasons why it might be a good idea. It won't hurt in any case.
 !
-	mov	ax,#0x0001	! protected mode (PE) bit
+	xor	ax,ax
+	inc	ax		! protected mode (PE) bit
 	lmsw	ax		! This is it!
 	jmp	flush_instr
 flush_instr:
@@ -394,33 +395,89 @@
 	mov	ax,#0x501c	! return 80x28
 	ret
 /* svga modes */
+!
+!	test for presence of an S3 VGA chip. The algorithm was taken
+!	from the SuperProbe package of XFree86 1.2.1
+!	report bugs to Christoph.Niemann@linux.org
+!
 svga:   cld
-        lea     si,id9GXE	! Check for the #9GXE (jyanowit@orixa.mtholyoke.edu,thanks dlm40629@uxa.cso.uiuc.edu)
-        mov     di,#0x49	! id string is at c000:049
-        mov     cx,#0x11	! length of "Graphics Power By"
-        repe
-        cmpsb
-        jne     of1280
-is9GXE:	lea 	si,dsc9GXE	! table of descriptions of video modes for BIOS
-	lea	di,mo9GXE	! table of sizes of video modes for my BIOS
+	mov	cx,#0x0f35	! we store some constants in cl/ch
+	mov	dx,#0x03d4
+	movb	al,#0x38
+	call	inidx
+	mov	bh,al		! store current value of CRT-register 0x38
+	mov	ax,#0x0038
+	call	outidx		! disable writing to special regs
+	movb	al,cl		! check wether we can write special reg 0x35
+	call	inidx
+	movb	bl,al		! save the current value of CRT reg 0x35
+	andb	al,#0xf0	! clear bits 0-3
+	movb	ah,al
+	movb	al,cl		! and write it to CRT reg 0x35
+	call	outidx
+	call	inidx		! now read it back
+	andb	al,ch		! clear the upper 4 bits
+	jz	s3_2		! the first test failed. But we have a
+	movb	ah,bl		! second chance
+	mov	al,cl
+	call	outidx
+	jmp	s3_1		! do the other tests
+s3_2:	mov	ax,cx		! load ah with 0xf and al with 0x35
+	orb	ah,bl		! set the upper 4 bits of ah with the orig value
+	call	outidx		! write ...
+	call	inidx		! ... and reread 
+	andb	al,cl		! turn off the upper 4 bits
+	push	ax
+	movb	ah,bl		! restore old value in register 0x35
+	movb	al,cl
+	call	outidx
+	pop	ax
+	cmp	al,ch		! setting lower 4 bits was successful => bad
+	je	no_s3		! writing is allowed => this is not an S3
+s3_1:	mov	ax,#0x4838	! allow writing to special regs by putting
+	call	outidx		! magic number into CRT-register 0x38
+	movb	al,cl		! check wether we can write special reg 0x35
+	call	inidx
+	movb	bl,al
+	andb	al,#0xf0
+	movb	ah,al
+	movb	al,cl
+	call	outidx
+	call	inidx
+	andb	al,ch
+	jnz	no_s3		! no, we can't write => no S3
+	mov	ax,cx
+	orb	ah,bl
+	call	outidx
+	call	inidx
+	andb	al,ch
+	push	ax
+	movb	ah,bl		! restore old value in register 0x35
+	movb	al,cl
+	call	outidx
+	pop	ax
+	cmp	al,ch
+	jne	no_s31		! writing not possible => no S3
+	movb	al,#0x30
+	call	inidx		! now get the S3 id ...
+	lea	di,idS3
+	mov	cx,#0x10
+	repne
+	scasb
+	je	no_s31
+	lea 	si,dsc_S3	! table of descriptions of video modes for BIOS
+	lea	di,mo_S3	! table of sizes of video modes for my BIOS
+	movb	ah,bh
+	movb	al,#0x38
+	call	outidx		! restore old value of CRT register 0x38
 	br	selmod		! go ask for video mode
-of1280:	cld	
-	lea	si,idf1280	! Check for Orchid F1280 (dingbat@diku.dk)
-	mov	di,#0x10a	! id string is at c000:010a
-	mov	cx,#0x21	! length
-	repe
-	cmpsb
-	jne	nf1280	
-isVRAM:	lea	si,dscf1280
-	lea	di,mof1280
-	br	selmod
-nf1280:	lea	si,idVRAM
-	mov	di,#0x10a
-	mov	cx,#0x0c
-	repe
-	cmpsb
-	je	isVRAM
-	cld
+no_s3:	movb	al,#0x35	! restore CRT register 0x35
+	movb	ah,bl
+	call	outidx
+no_s31:	movb	ah,bh
+	movb	al,#0x38
+	call	outidx		! restore old value of CRT register 0x38
+
 	lea 	si,idati		! Check ATI 'clues'
 	mov	di,#0x31
 	mov 	cx,#0x09
@@ -710,6 +767,29 @@
 	pop	ds
 	ret
 
+! Routine to write al into a VGA-register that is
+! accessed via an index register
+!
+! dx contains the address of the index register
+! al contains the index
+! ah contains the value to write to the data register (dx + 1)
+!
+! no registers are changed
+
+outidx:	out	dx,al
+	push	ax
+	mov	al,ah
+	inc	dx
+	out	dx,al
+	dec	dx
+	pop	ax
+	ret
+inidx:	out	dx,al
+	inc	dx
+	in	al,dx
+	dec	dx
+	ret
+
 ! Routine to print asciiz-string at DS:SI
 
 prtstr:	lodsb
@@ -817,9 +897,8 @@
 idgenoa:	.byte	0x77, 0x00, 0x99, 0x66
 idparadise:	.ascii	"VGA="
 idoakvga:	.ascii  "OAK VGA "
-idf1280:	.ascii	"Orchid Technology Fahrenheit 1280"
-id9GXE:		.ascii  "Graphics Power By"
-idVRAM:		.ascii	"Stealth VRAM"
+idS3:		.byte	0x81, 0x82, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95
+		.byte	0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xb0
 
 ! Manufacturer:	  Numofmodes+2:	Mode:
 ! Number of modes is the number of chip-specific svga modes plus the extended
@@ -836,8 +915,7 @@
 motseng:	.byte	0x07,	0x26, 0x2a, 0x23, 0x24, 0x22
 movideo7:	.byte	0x08,	0x40, 0x43, 0x44, 0x41, 0x42, 0x45
 mooakvga:	.byte   0x08,   0x00, 0x07, 0x4e, 0x4f, 0x50, 0x51
-mo9GXE:		.byte	0x04,	0x54, 0x55
-mof1280:	.byte	0x04,	0x54, 0x55
+mo_S3:		.byte	0x04,	0x54, 0x55
 mounknown:	.byte	0x02
 
 !			msb = Cols lsb = Rows:
@@ -855,8 +933,7 @@
 dsctseng:	.word	0x5032, 0x501c, 0x503c, 0x6428, 0x8419, 0x841c, 0x842c
 dscvideo7:	.word	0x5032, 0x501c, 0x502b, 0x503c, 0x643c, 0x8419, 0x842c, 0x841c
 dscoakvga:	.word   0x5032, 0x501c, 0x2819, 0x5019, 0x503c, 0x843c, 0x8419, 0x842b
-dscf1280:	.word	0x5032, 0x501c, 0x842b, 0x8419
-dsc9GXE:	.word	0x5032, 0x501c, 0x842b, 0x8419
+dsc_S3:		.word	0x5032, 0x501c, 0x842b, 0x8419
 dsunknown:	.word	0x5032, 0x501c
 modesave:	.word	SVGA_MODE
 
diff -u --recursive v1.1.33/linux/drivers/block/sbpcd.c linux/drivers/block/sbpcd.c
--- v1.1.33/linux/drivers/block/sbpcd.c	Fri Jul 22 16:41:00 1994
+++ linux/drivers/block/sbpcd.c	Sat Jul 23 00:42:50 1994
@@ -5,7 +5,7 @@
  *            and for "no-sound" interfaces like Lasermate and the
  *            Panasonic CI-101P.
  *
- *  NOTE:     This is release 2.3.
+ *  NOTE:     This is release 2.4.
  *            It works with my SbPro & drive CR-521 V2.11 from 2/92
  *            and with the new CR-562-B V0.75 on a "naked" Panasonic
  *            CI-101P interface. And vice versa. 
@@ -117,6 +117,9 @@
  *  2.3  Let "door lock" and "eject" live together.
  *       Implemented "close tray" (done automatically during open).
  *
+ *  2.4  Use different names for device registering.
+ *       
+ *
  *  TODO
  *
  *     disk change detection
@@ -192,7 +195,7 @@
 
 #include "blk.h"
 
-#define VERSION "2.3 Eberhard Moenkeberg <emoenke@gwdg.de>"
+#define VERSION "2.4 Eberhard Moenkeberg <emoenke@gwdg.de>"
 
 #define SBPCD_DEBUG
 
@@ -397,6 +400,18 @@
 static char *str_lm = "LaserMate";
 static char *str_sp = "SPEA";
 char *type;
+#if !(SBPCD_ISSUE-1)
+static char *major_name="sbpcd";
+#endif
+#if !(SBPCD_ISSUE-2)
+static char *major_name="sbpcd2";
+#endif
+#if !(SBPCD_ISSUE-3)
+static char *major_name="sbpcd3";
+#endif
+#if !(SBPCD_ISSUE-4)
+static char *major_name="sbpcd4";
+#endif
 
 /*==========================================================================*/
 
@@ -2840,7 +2855,6 @@
 /*==========================================================================*/
 /*
  *  Take care of the different block sizes between cdrom and Linux.
- *  When Linux gets variable block sizes this will probably go away.
  */
 static void sbp_transfer(void)
 {
@@ -3551,7 +3565,7 @@
       OUT(MIXER_data,0xCC); /* one nibble per channel */
     }
   
-  if (register_blkdev(MAJOR_NR, "sbpcd", &sbpcd_fops) != 0)
+  if (register_blkdev(MAJOR_NR, major_name, &sbpcd_fops) != 0)
     {
       printk("SBPCD: Can't get MAJOR %d for Matsushita CDROM\n", MAJOR_NR);
 #if PRINTK_BUG
diff -u --recursive v1.1.33/linux/drivers/net/Makefile linux/drivers/net/Makefile
--- v1.1.33/linux/drivers/net/Makefile	Mon Jul 18 14:48:29 1994
+++ linux/drivers/net/Makefile	Fri Jul 22 11:29:18 1994
@@ -21,7 +21,7 @@
 net_init.o: ../../include/linux/autoconf.h
 
 ifdef CONFIG_SK_G16
-NETDRV_OBJS := $(NETDRV_OBJS) net.a(sk_g16.o)
+NETDRV_OBJS := $(NETDRV_OBJS) sk_g16.o
 endif
 
 ifdef CONFIG_WD80x3
@@ -53,7 +53,7 @@
 endif
 
 ifdef CONFIG_HPLAN_PLUS
-NETDRV_OBJS := $(NETDRV_OBJS) net.a(hp-plus.o)
+NETDRV_OBJS := $(NETDRV_OBJS) hp-plus.o
 CONFIG_8390 = CONFIG_8390
 endif
 
@@ -104,7 +104,7 @@
 	$(CC) $(CPPFLAGS) $(CFLAGS) $(DE600_OPTS) -c $<
 	
 ifdef CONFIG_DE620
-NETDRV_OBJS := $(NETDRV_OBJS) net.a(de620.o)
+NETDRV_OBJS := $(NETDRV_OBJS) de620.o
 endif
 de620.o: de620.c CONFIG
 	$(CC) $(CPPFLAGS) $(CFLAGS) $(DE620_OPTS) -c $<
@@ -155,7 +155,7 @@
 CONFIG_8390 = CONFIG_8390
 endif
 ifdef CONFIG_APRICOT
-NETDRV_OBJS := $(NETDRV_OBJS) net.a(apricot.o)
+NETDRV_OBJS := $(NETDRV_OBJS) apricot.o
 endif
 
 ifdef CONFIG_8390
diff -u --recursive v1.1.33/linux/drivers/net/e2100.c linux/drivers/net/e2100.c
--- v1.1.33/linux/drivers/net/e2100.c	Mon Jun 27 16:47:00 1994
+++ linux/drivers/net/e2100.c	Fri Jul 22 11:32:04 1994
@@ -1,23 +1,25 @@
 /* e2100.c: A Cabletron E2100 series ethernet driver for linux. */
 /*
-    Written 1993 by Donald Becker.
-    Copyright 1993 United States Government as represented by the
-    Director, National Security Agency.  This software may be used and
-    distributed according to the terms of the GNU Public License,
-    incorporated herein by reference.
+	Written 1993-1994 by Donald Becker.
 
-    This is a driver for the Cabletron E2100 series ethercards.
+	Copyright 1994 by Donald Becker.
+	Copyright 1993 United States Government as represented by the
+	Director, National Security Agency.  This software may be used and
+	distributed according to the terms of the GNU Public License,
+	incorporated herein by reference.
 
-    The Author may be reached as becker@cesdis.gsfc.nasa.gov, or
-    C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
+	This is a driver for the Cabletron E2100 series ethercards.
 
+	The Author may be reached as becker@cesdis.gsfc.nasa.gov, or
+	C/O Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
+
 	The E2100 series ethercard is a fairly generic shared memory 8390
 	implementation.  The only unusual aspect is the way the shared memory
 	registers are set: first you do an inb() in what is normally the
-	station address region, and the low four bits of next outb() is used
-	as the write value for that register.  Either someone wasn't too used
-	to dem bit en bites, or they were trying to obfusicate the programming
-	interface.
+	station address region, and the low three bits of next outb() *address*
+	is used	as the write value for that register.  Either someone wasn't
+	too used to dem bit en bites, or they were trying to obfusicate the
+	programming	interface.
 
 	There is an additional complication when setting the window on the packet
 	buffer.  You must first do a read into the packet buffer region with the
@@ -30,7 +32,7 @@
 */
 
 static char *version =
-    "e2100.c:v0.01 11/21/93 Donald Becker (becker@super.org)\n";
+	"e2100.c:v1.01 7/21/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
 
 #include <linux/config.h>
 #include <linux/kernel.h>
@@ -39,42 +41,29 @@
 #include <linux/string.h>
 #include <asm/io.h>
 #include <asm/system.h>
-#ifndef PRE_PL13
-#include <linux/ioport.h>       /* Delete if your kernel doesn't have it. */
-#endif
+#include <linux/ioport.h>
 
 #include <linux/netdevice.h>
 #include "8390.h"
 
-/* Compatibility definitions for earlier kernel versions. */
-#ifndef HAVE_PORTRESERVE
-#define check_region(ioaddr, size)              0
-#define snarf_region(ioaddr, size);             do ; while (0)
-#endif
-#ifndef HAVE_AUTOIRQ
-/* From auto_irq.c, in ioport.h for later versions. */
-extern void autoirq_setup(int waittime);
-extern int autoirq_report(int waittime);
-/* The map from IRQ number (as passed to the interrupt handler) to
-   'struct device'. */
-extern struct device *irq2dev_map[16];
-#endif
+static int e21_probe_list[] = {0x300, 0x280, 0x380, 0x220, 0};
 
 /* Offsets from the base_addr.
-   Read from the ASIC register, and the low 3(?) bits of the next outb() address
-   is used to set the cooresponding register. */
-#define E21_NIC_OFFSET  0       /* Offset to the 8390 NIC. */
+   Read from the ASIC register, and the low three bits of the next outb()
+   address is used to set the cooresponding register. */
+#define E21_NIC_OFFSET  0		/* Offset to the 8390 NIC. */
 #define E21_ASIC		0x10
 #define E21_MEM_ENABLE	0x10
 #define  E21_MEM_ON		0x05	/* Enable memory in 16 bit mode. */
 #define  E21_MEM_ON_8	0x07	/* Enable memory in  8 bit mode. */
 #define E21_MEM_BASE	0x11	
 #define E21_IRQ_LOW		0x12	/* The low three bits of the IRQ number. */
-#define E21_IRQ_HIGH	0x14	/* The high IRQ bit, and ...  */
+#define E21_IRQ_HIGH	0x14	/* The high IRQ bit and media select ...  */
+#define E21_MEDIA		0x14	/* (alias). */
 #define  E21_ALT_IFPORT 0x02	/* Set to use the other (BNC,AUI) port. */
 #define  E21_BIG_MEM	0x04	/* Use a bigger (64K) buffer (we don't) */
-#define E21_SAPROM      0x10    /* Offset to station address data. */
-#define ETHERCARD_TOTAL_SIZE    0x20
+#define E21_SAPROM		0x10	/* Offset to station address data. */
+#define E21_IO_EXTENT	 0x20
 
 extern inline void mem_on(short port, volatile char *mem_base,
 						  unsigned char start_page )
@@ -96,10 +85,10 @@
    is designed to have a 4K Tx region last. The windowing circuitry wraps the
    window at 0x2fff->0x0000 so that the packets at e.g. 0x2f00 in the RX ring
    appear contiguously in the window. */
-#define E21_RX_START_PG    0x00    /* First page of RX buffer */
-#define E21_RX_STOP_PG     0x30    /* Last page +1 of RX ring */
-#define E21_BIG_RX_STOP_PG 0xF0    /* Last page +1 of RX ring */
-#define E21_TX_START_PG  E21_RX_STOP_PG    /* First page of TX buffer */
+#define E21_RX_START_PG		0x00	/* First page of RX buffer */
+#define E21_RX_STOP_PG		0x30	/* Last page +1 of RX ring */
+#define E21_BIG_RX_STOP_PG	0xF0	/* Last page +1 of RX ring */
+#define E21_TX_START_PG		E21_RX_STOP_PG	/* First page of TX buffer */
 
 int e2100_probe(struct device *dev);
 int e21_probe1(struct device *dev, int ioaddr);
@@ -107,9 +96,9 @@
 static int e21_open(struct device *dev);
 static void e21_reset_8390(struct device *dev);
 static int e21_block_input(struct device *dev, int count,
-                          char *buf, int ring_offset);
+						   char *buf, int ring_offset);
 static void e21_block_output(struct device *dev, int count,
-                            const unsigned char *buf, const start_page);
+							 const unsigned char *buf, const start_page);
 static int e21_close(struct device *dev);
 
 
@@ -122,26 +111,22 @@
 
 int e2100_probe(struct device *dev)
 {
-    int *port, ports[] = {0x300, 0x280, 0x380, 0x220, 0};
-    short base_addr = dev->base_addr;
+	int *port;
+	int base_addr = dev->base_addr;
 
-    if (base_addr > 0x1ff)              /* Check a single specified location. */
-        return e21_probe1(dev, base_addr);
-    else if (base_addr > 0)             /* Don't probe at all. */
-        return ENXIO;
-
-    for (port = &ports[0]; *port; port++) {
-        ushort ioaddr = *port;
-
-        if (check_region(ioaddr, ETHERCARD_TOTAL_SIZE))
-            continue;
-        if (inb(ioaddr + E21_SAPROM + 0) == 0x00
-			&& inb(ioaddr + E21_SAPROM + 1) == 0x00
-			&& inb(ioaddr + E21_SAPROM + 2) == 0x1d
-            && e21_probe1(dev, ioaddr) == 0)
-            return 0;
-    }
-    return -ENODEV;
+	if (base_addr > 0x1ff)		/* Check a single specified location. */
+		return e21_probe1(dev, base_addr);
+	else if (base_addr != 0)	/* Don't probe at all. */
+		return ENXIO;
+
+	for (port = e21_probe_list; *port; port++) {
+		if (check_region(*port, E21_IO_EXTENT))
+			continue;
+		if (e21_probe1(dev, *port) == 0)
+			return 0;
+	}
+
+	return ENODEV;
 }
 
 int e21_probe1(struct device *dev, int ioaddr)
@@ -149,29 +134,30 @@
 	int i, status;
 	unsigned char *station_addr = dev->dev_addr;
 
-	/* We've already checked the station address prefix, now verify by making
-	   certain that there is a 8390 at the expected location. */
+	/* First check the station address for the Ctron prefix. */
+	if (inb(ioaddr + E21_SAPROM + 0) != 0x00
+		|| inb(ioaddr + E21_SAPROM + 1) != 0x00
+		|| inb(ioaddr + E21_SAPROM + 2) != 0x1d)
+		return ENODEV;
+
+	/* Verify by making certain that there is a 8390 at there. */
 	outb(E8390_NODMA + E8390_STOP, ioaddr);
 	SLOW_DOWN_IO;
 	status = inb(ioaddr);
 	if (status != 0x21 && status != 0x23)
-		return -ENODEV;
+		return ENODEV;
 
-#ifdef testing_only
-	printk("%s: E21xx at %#3x (PAXI backwards): ", dev->name, ioaddr);
-	for (i = 0; i < 16; i++)
-		printk(" %02X", inb(ioaddr + 0x1f - i));
-	printk("\n");
-#endif
+	/* Grab the region so we can find a different board if IRQ select fails. */
+	snarf_region(ioaddr, E21_IO_EXTENT);
 
 	/* Read the station address PROM.  */
 	for (i = 0; i < 6; i++)
 		station_addr[i] = inb(ioaddr + E21_SAPROM + i);
 
-	/* Grab the region so we can find another board if needed . */
-	snarf_region(ioaddr, ETHERCARD_TOTAL_SIZE);
+	inb(ioaddr + E21_MEDIA); 		/* Point to media selection. */
+	outb(0, ioaddr + E21_ASIC); 	/* and disable the secondary interface. */
 
-	printk("%s: E21xx at %#3x, ", dev->name, ioaddr);
+	printk("%s: E21** at %#3x,", dev->name, ioaddr);
 	for (i = 0; i < 6; i++)
 		printk(" %02X", station_addr[i]);
 
@@ -182,15 +168,13 @@
 				dev->irq = irqlist[i];
 				break;
 			}
-	} else if (dev->irq == 2)     /* Fixup bogosity: IRQ2 is really IRQ9 */
+		if (i >= 8) {
+			printk(" unable to get IRQ %d.\n", dev->irq);
+			return EAGAIN;
+		}
+	} else if (dev->irq == 2)	/* Fixup luser bogosity: IRQ2 is really IRQ9 */
 		dev->irq = 9;
 
-	/* Snarf the interrupt now. */
-	if (irqaction (dev->irq, &ei_sigaction)) {
-		printk (" unable to get IRQ %d.\n", dev->irq);
-		return -EBUSY;
-	}
-
 	/* The 8390 is at the base address. */
 	dev->base_addr = ioaddr;
 
@@ -201,6 +185,7 @@
 	ei_status.tx_start_page = E21_TX_START_PG;
 	ei_status.rx_start_page = E21_RX_START_PG;
 	ei_status.stop_page = E21_RX_STOP_PG;
+    ei_status.saved_irq = dev->irq;
 
 	/* Check the media port used.  The port can be passed in on the
 	   low mem_end bits. */
@@ -208,10 +193,12 @@
 		dev->if_port = dev->mem_end & 7;
 	else {
 		dev->if_port = 0;
-		inb_p(ioaddr + E21_IRQ_HIGH); 	/* Select if_port detect. */
+		inb(ioaddr + E21_MEDIA); 	/* Turn automatic media detection on. */
 		for(i = 0; i < 6; i++)
-			if (station_addr[i] != inb(ioaddr + E21_SAPROM))
+			if (station_addr[i] != inb(ioaddr + E21_SAPROM + 8 + i)) {
 				dev->if_port = 1;
+				break;
+			}
 	}
 
 	/* Never map in the E21 shared memory unless you are actively using it.
@@ -227,9 +214,8 @@
 	dev->mem_end = dev->rmem_end = dev->mem_start + 2*1024;
 #endif
 
-	printk(" IRQ %d, %s interface,  memory at %#x-%#x.\n", dev->irq,
-		   dev->if_port ? "secondary" : "primary", dev->mem_start,
-		   dev->mem_start + 2*1024 - 1);
+	printk(", IRQ %d, %s media, memory @ %#lx.\n", dev->irq,
+		   dev->if_port ? "secondary" : "primary", dev->mem_start);
 
 	if (ei_debug > 0)
 		printk(version);
@@ -247,16 +233,21 @@
 static int
 e21_open(struct device *dev)
 {
-    short ioaddr = dev->base_addr;
+	short ioaddr = dev->base_addr;
+
+	if (irqaction (dev->irq, &ei_sigaction)) {
+		return EBUSY;
+	}
+	irq2dev_map[dev->irq] = dev;
 
 	/* Set the interrupt line and memory base on the hardware. */
-	inb_p(ioaddr + E21_IRQ_LOW);
-	outb_p(0, ioaddr + E21_ASIC + (dev->irq & 7));
-	inb_p(ioaddr + E21_IRQ_HIGH); 			/* High IRQ bit, and if_port. */
-	outb_p(0, ioaddr + E21_ASIC + (dev->irq > 7 ? 1:0)
+	inb(ioaddr + E21_IRQ_LOW);
+	outb(0, ioaddr + E21_ASIC + (dev->irq & 7));
+	inb(ioaddr + E21_IRQ_HIGH); 			/* High IRQ bit, and if_port. */
+	outb(0, ioaddr + E21_ASIC + (dev->irq > 7 ? 1:0)
 		   + (dev->if_port ? E21_ALT_IFPORT : 0));
-	inb_p(ioaddr + E21_MEM_BASE);
-	outb_p(0, ioaddr + E21_ASIC + ((dev->mem_start >> 17) & 7));
+	inb(ioaddr + E21_MEM_BASE);
+	outb(0, ioaddr + E21_ASIC + ((dev->mem_start >> 17) & 7));
 
 	return ei_open(dev);
 }
@@ -264,47 +255,47 @@
 static void
 e21_reset_8390(struct device *dev)
 {
-    short ioaddr = dev->base_addr;
+	short ioaddr = dev->base_addr;
 
-    outb(0x01, ioaddr);
-    if (ei_debug > 1) printk("resetting the E2180x3 t=%d...", jiffies);
-    ei_status.txing = 0;
+	outb(0x01, ioaddr);
+	if (ei_debug > 1) printk("resetting the E2180x3 t=%ld...", jiffies);
+	ei_status.txing = 0;
 
-    /* Set up the ASIC registers, just in case something changed them. */
+	/* Set up the ASIC registers, just in case something changed them. */
 
-    if (ei_debug > 1) printk("reset done\n");
-    return;
+	if (ei_debug > 1) printk("reset done\n");
+	return;
 }
 
-/* Block input and output are easy on shared memory ethercards.  The E21xx makes
-   block_input() especially easy by wrapping the top ring buffer to the bottom
-   automatically. */
+/*  Block input and output are easy on shared memory ethercards.
+	The E21xx makes block_input() especially easy by wrapping the top
+	ring buffer to the bottom automatically. */
 static int
 e21_block_input(struct device *dev, int count, char *buf, int ring_offset)
 {
-    short ioaddr = dev->base_addr;
+	short ioaddr = dev->base_addr;
 	char *shared_mem = (char *)dev->mem_start;
 	int start_page = (ring_offset>>8);
 
 	mem_on(ioaddr, shared_mem, start_page);
 
-    /* We'll always get a 4 byte header read first. */
-    if (count == 4)
-        ((int*)buf)[0] = ((int*)shared_mem)[0];
-    else
-        memcpy(buf, shared_mem + (ring_offset & 0xff), count);
+	/* We'll always get a 4 byte header read first. */
+	if (count == 4)
+		((int*)buf)[0] = ((int*)shared_mem)[0];
+	else
+		memcpy(buf, shared_mem + (ring_offset & 0xff), count);
 
-    /* Turn off memory access: we would need to reprogram the window anyway. */
+	/* Turn off memory access: we would need to reprogram the window anyway. */
 	mem_off(ioaddr);
 
-    return 0;
+	return 0;
 }
 
 static void
 e21_block_output(struct device *dev, int count, const unsigned char *buf,
-                int start_page)
+				 int start_page)
 {
-    short ioaddr = dev->base_addr;
+	short ioaddr = dev->base_addr;
 	volatile char *shared_mem = (char *)dev->mem_start;
 
 	/* Set the shared memory window start by doing a read, with the low address
@@ -319,18 +310,37 @@
 static int
 e21_close(struct device *dev)
 {
-    short ioaddr = dev->base_addr;
+	short ioaddr = dev->base_addr;
+
+	if (ei_debug > 1)
+		printk("%s: Shutting down ethercard.\n", dev->name);
+
+    free_irq(dev->irq);
+    dev->irq = ei_status.saved_irq;
+
+	/* Shut off the interrupt line and secondary interface. */
+	inb(ioaddr + E21_IRQ_LOW);
+	outb(0, ioaddr + E21_ASIC);
+	inb(ioaddr + E21_IRQ_HIGH); 			/* High IRQ bit, and if_port. */
+	outb(0, ioaddr + E21_ASIC);
+
+    irq2dev_map[dev->irq] = NULL;
 
-    if (ei_debug > 1)
-        printk("%s: Shutting down ethercard.\n", dev->name);
-    NS8390_init(dev, 0);
+	NS8390_init(dev, 0);
 
+	/* Double-check that the memory has been turned off, because really
+	   really bad things happen if it isn't. */
 	mem_off(ioaddr);
 
-    return 0;
+	return 0;
 }
-
 
+#ifdef HAVE_DEVLIST
+struct netdev_entry e21_drv =
+{"e21", e21_probe1, E21_IO_EXTENT, e21_probe_list};
+#endif
+
+
 /*
  * Local variables:
  *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c e2100.c"
diff -u --recursive v1.1.33/linux/drivers/net/plip.c linux/drivers/net/plip.c
--- v1.1.33/linux/drivers/net/plip.c	Wed Jun 22 14:57:09 1994
+++ linux/drivers/net/plip.c	Fri Jul 22 12:44:39 1994
@@ -941,8 +941,8 @@
 
 static int plip_ioctl(struct device *dev, struct ifreq *rq)
 {
-	struct net_local *nl=(struct net_local *)dev->priv;
-	struct plipconf *pc=(struct plipconf *)rq->ifr_data;
+	struct net_local *nl = (struct net_local *) dev->priv;
+	struct plipconf *pc = (struct plipconf *) &rq->ifr_data;
 	
 	switch(pc->pcmd)
 	{
diff -u --recursive v1.1.33/linux/fs/buffer.c linux/fs/buffer.c
--- v1.1.33/linux/fs/buffer.c	Tue Jul 19 10:19:12 1994
+++ linux/fs/buffer.c	Sat Jul 23 00:43:38 1994
@@ -1113,14 +1113,14 @@
  * etc. This also allows us to optimize memory usage by sharing code pages
  * and filesystem buffers..
  */
-unsigned long bread_page(unsigned long address, dev_t dev, int b[], int size, int share)
+unsigned long bread_page(unsigned long address, dev_t dev, int b[], int size, int no_share)
 {
 	struct buffer_head * bh[8];
 	unsigned long where;
 	int i, j;
 
-	if (share) {
-		where = try_to_share_buffers(address,dev,b,size);
+	if (!no_share) {
+		where = try_to_share_buffers(address, dev, b, size);
 		if (where)
 			return where;
 	}
@@ -1132,14 +1132,14 @@
 	}
 	read_buffers(bh,i);
 	where = address;
- 	for (i=0, j=0; j<PAGE_SIZE ; i++, j += size,address += size) {
+ 	for (i=0, j=0; j<PAGE_SIZE ; i++, j += size, where += size) {
 		if (bh[i]) {
 			if (bh[i]->b_uptodate)
-				COPYBLK(size, (unsigned long) bh[i]->b_data,address);
+				COPYBLK(size, (unsigned long) bh[i]->b_data, where);
 			brelse(bh[i]);
 		}
 	}
-	return where;
+	return address;
 }
 
 /*
diff -u --recursive v1.1.33/linux/fs/nfs/mmap.c linux/fs/nfs/mmap.c
--- v1.1.33/linux/fs/nfs/mmap.c	Fri Jul 22 16:41:02 1994
+++ linux/fs/nfs/mmap.c	Sat Jul 23 00:43:38 1994
@@ -27,7 +27,7 @@
  * Fill in the supplied page for mmap
  */
 static unsigned long nfs_file_mmap_nopage(struct vm_area_struct * area,
-	unsigned long address, unsigned long page, int error_code)
+	unsigned long address, unsigned long page, int no_share)
 {
 	struct inode * inode = area->vm_inode;
 	unsigned int clear;
diff -u --recursive v1.1.33/linux/include/linux/fs.h linux/include/linux/fs.h
--- v1.1.33/linux/include/linux/fs.h	Tue Jul 19 10:19:14 1994
+++ linux/include/linux/fs.h	Sat Jul 23 00:43:38 1994
@@ -444,7 +444,7 @@
 extern void brelse(struct buffer_head * buf);
 extern void set_blocksize(dev_t dev, int size);
 extern struct buffer_head * bread(dev_t dev, int block, int size);
-extern unsigned long bread_page(unsigned long addr,dev_t dev,int b[],int size,int share);
+extern unsigned long bread_page(unsigned long addr,dev_t dev,int b[],int size,int no_share);
 extern struct buffer_head * breada(dev_t dev,int block, int size, 
 				   unsigned int pos, unsigned int filesize);
 extern void put_super(dev_t dev);
diff -u --recursive v1.1.33/linux/include/linux/mm.h linux/include/linux/mm.h
--- v1.1.33/linux/include/linux/mm.h	Fri Jul 22 16:41:02 1994
+++ linux/include/linux/mm.h	Fri Jul 22 16:40:43 1994
@@ -228,9 +228,14 @@
 /* swap cache stuff (in swap.c) */
 extern unsigned long * swap_cache;
 
-extern inline unsigned long in_swap_cache (unsigned long addr)
+extern inline unsigned long in_swap_cache(unsigned long addr)
 {
 	return swap_cache[addr >> PAGE_SHIFT]; 
+}
+
+extern inline void swap_cache_invalidate(unsigned long addr)
+{
+	swap_cache[addr >> PAGE_SHIFT] = 0;
 }
 
 #endif
diff -u --recursive v1.1.33/linux/kernel/ptrace.c linux/kernel/ptrace.c
--- v1.1.33/linux/kernel/ptrace.c	Thu Jul 21 08:18:20 1994
+++ linux/kernel/ptrace.c	Fri Jul 22 12:53:39 1994
@@ -157,7 +157,7 @@
 	struct vm_area_struct * vma;
 
 	addr &= PAGE_MASK;
-	for (vma = current->mm->mmap ; ; vma = vma->vm_next) {
+	for (vma = tsk->mm->mmap ; ; vma = vma->vm_next) {
 		if (!vma)
 			return NULL;
 		if (vma->vm_end > addr)
diff -u --recursive v1.1.33/linux/mm/memory.c linux/mm/memory.c
--- v1.1.33/linux/mm/memory.c	Fri Jul 22 16:41:03 1994
+++ linux/mm/memory.c	Sat Jul 23 00:43:38 1994
@@ -263,11 +263,17 @@
 				*new_page_table = swap_duplicate(pg);
 				continue;
 			}
-			if ((pg & (PAGE_RW | PAGE_COW)) == (PAGE_RW | PAGE_COW))
+			if (pg > high_memory || (mem_map[MAP_NR(pg)] & MAP_PAGE_RESERVED)) {
+				*new_page_table = pg;
+				continue;
+			}
+			if (pg & PAGE_COW)
 				pg &= ~PAGE_RW;
+			if (in_swap_cache(pg)) {
+				swap_cache_invalidate(pg);
+				pg |= PAGE_DIRTY;
+			}
 			*new_page_table = pg;
-			if (mem_map[MAP_NR(pg)] & MAP_PAGE_RESERVED)
-				continue;
 			*old_page_table = pg;
 			mem_map[MAP_NR(pg)]++;
 		}
@@ -730,9 +736,6 @@
 /* if it is private, it must be clean to be shared */
 	if ((from_area->vm_page_prot & PAGE_COW) && (from & PAGE_DIRTY))
 		return 0;
-/* the swap caching doesn't really handle shared pages.. */
-	if (in_swap_cache(from))
-		return 0;
 /* is the page reasonable at all? */
 	if (from >= high_memory)
 		return 0;
@@ -748,14 +751,26 @@
 		return 0;
 /* do we copy? */
 	if (newpage) {
+		if (in_swap_cache(from)) { /* implies PAGE_DIRTY */
+			if (from_area->vm_page_prot & PAGE_COW)
+				return 0;
+		}
 		copy_page((from & PAGE_MASK), newpage);
 		*(unsigned long *) to_page = newpage | to_area->vm_page_prot;
 		return 1;
 	}
-/* just share them.. */
+/* do a final swap-cache test before sharing them.. */
+	if (in_swap_cache(from)) {
+		if (from_area->vm_page_prot & PAGE_COW)
+			return 0;
+		from |= PAGE_DIRTY;
+		*(unsigned long *) from_page = from;
+		swap_cache_invalidate(from);
+		invalidate();
+	}
 	mem_map[MAP_NR(from)]++;
 /* fill in the 'to' field, checking for COW-stuff */
-	to = (from & PAGE_MASK) | to_area->vm_page_prot;
+	to = (from & (PAGE_MASK | PAGE_DIRTY)) | to_area->vm_page_prot;
 	if (to & PAGE_COW)
 		to &= ~PAGE_RW;
 	*(unsigned long *) to_page = to;
@@ -764,7 +779,7 @@
 		return 1;
 	if (!(from_area->vm_page_prot & PAGE_COW))
 		return 1;
-/* ok, need to mark it read-only, so invalidate aany possible old TB entry */
+/* ok, need to mark it read-only, so invalidate any possible old TB entry */
 	from &= ~PAGE_RW;
 	*(unsigned long *) from_page = from;
 	invalidate();
@@ -923,13 +938,24 @@
 	}
 	++vma->vm_task->mm->maj_flt;
 	++vma->vm_task->mm->rss;
-	page = vma->vm_ops->nopage(vma, address, page, error_code);
+	prot = vma->vm_page_prot;
+	/*
+	 * The fourth argument is "no_share", which tells the low-level code
+	 * to copy, not share the page even if sharing is possible.  It's
+	 * essentially an early COW detection ("moo at 5 AM").
+	 */
+	page = vma->vm_ops->nopage(vma, address, page, (error_code & PAGE_RW) && (prot & PAGE_COW));
 	if (share_page(vma, address, error_code, 0)) {
 		free_page(page);
 		return;
 	}
-	prot = vma->vm_page_prot;
-	if ((prot & PAGE_COW) && mem_map[MAP_NR(page)] > 1)
+	/*
+	 * This silly early PAGE_DIRTY setting removes a race
+	 * due to the bad i386 page protection.
+	 */
+	if (error_code & PAGE_RW) {
+		prot |= PAGE_DIRTY;	/* can't be COW-shared: see "no_share" above */
+	} else if ((prot & PAGE_COW) && mem_map[MAP_NR(page)] > 1)
 		prot &= ~PAGE_RW;
 	if (put_page(vma->vm_task, page, address, prot))
 		return;
@@ -1251,25 +1277,29 @@
 }
 
 
-/* This handles a generic mmap of a disk file */
+/*
+ * This handles a generic mmap of a disk file.
+ */
 static unsigned long file_mmap_nopage(struct vm_area_struct * area, unsigned long address,
-	unsigned long page, int error_code)
+	unsigned long page, int no_share)
 {
 	struct inode * inode = area->vm_inode;
 	unsigned int block;
 	int nr[8];
-	int i, j;
-	int prot = area->vm_page_prot;
+	int i, *p;
 
 	address &= PAGE_MASK;
 	block = address - area->vm_start + area->vm_offset;
 	block >>= inode->i_sb->s_blocksize_bits;
-
-	for (i=0, j=0; i< PAGE_SIZE ; j++, block++, i += inode->i_sb->s_blocksize)
-		nr[j] = bmap(inode,block);
-	if (error_code & PAGE_RW)
-		prot |= PAGE_RW | PAGE_DIRTY;
-	return bread_page(page, inode->i_dev, nr, inode->i_sb->s_blocksize, !(error_code & PAGE_RW));
+	i = PAGE_SIZE >> inode->i_sb->s_blocksize_bits;
+	p = nr;
+	do {
+		*p = bmap(inode,block);
+		i--;
+		block++;
+		p++;
+	} while (i > 0);
+	return bread_page(page, inode->i_dev, nr, inode->i_sb->s_blocksize, no_share);
 }
 
 struct vm_operations_struct file_mmap = {
diff -u --recursive v1.1.33/linux/mm/swap.c linux/mm/swap.c
--- v1.1.33/linux/mm/swap.c	Fri Jul 22 16:41:04 1994
+++ linux/mm/swap.c	Fri Jul 22 16:16:49 1994
@@ -344,21 +344,13 @@
 	}
 
         if ((entry = find_in_swap_cache(page)))  {
-		*table_ptr |= PAGE_DIRTY;
 		if (mem_map[MAP_NR(page)] != 1) {
+			*table_ptr |= PAGE_DIRTY;
+			printk("Aiee.. duplicated cached swap-cache entry\n");
 			return 0;
 		}
-		if (!entry)  {
-			if (!(entry = get_swap_page()))  {
-				return 0;
-			}
-			*table_ptr = entry;
-			invalidate();
-			write_swap_page(entry, (char *) (page & PAGE_MASK));
-		} else  {
-			*table_ptr = entry;
-			invalidate();
-		}
+		*table_ptr = entry;
+		invalidate();
 		free_page(page & PAGE_MASK);
 		return 1;
 	} 
@@ -901,12 +893,14 @@
 	error = namei(specialfile,&swap_inode);
 	if (error)
 		goto bad_swap;
+	p->swap_file = swap_inode;
 	error = -EBUSY;
 	if (swap_inode->i_count != 1)
 		goto bad_swap;
 	error = -EINVAL;
 	if (S_ISBLK(swap_inode->i_mode)) {
 		p->swap_device = swap_inode->i_rdev;
+		p->swap_file = NULL;
 		iput(swap_inode);
 		error = -ENODEV;
 		if (!p->swap_device)
@@ -918,9 +912,7 @@
 			if (p->swap_device == swap_info[i].swap_device)
 				goto bad_swap;
 		}
-	} else if (S_ISREG(swap_inode->i_mode))
-		p->swap_file = swap_inode;
-	else
+	} else if (!S_ISREG(swap_inode->i_mode))
 		goto bad_swap;
 	p->swap_lockmap = (unsigned char *) get_free_page(GFP_USER);
 	if (!p->swap_lockmap) {
diff -u --recursive v1.1.33/linux/tools/build.c linux/tools/build.c
--- v1.1.33/linux/tools/build.c	Wed Dec 29 06:50:28 1993
+++ linux/tools/build.c	Fri Jul 22 13:35:23 1994
@@ -32,8 +32,10 @@
 #include <linux/a.out.h>
 
 #define MINIX_HEADER 32
-#define GCC_HEADER 1024
 
+#define N_MAGIC_OFFSET 1024
+static int GCC_HEADER = sizeof(struct exec);
+
 #define SYS_SIZE DEF_SYSSIZE
 
 #define DEFAULT_MAJOR_ROOT 0
@@ -188,7 +190,10 @@
 		die("Unable to open 'system'");
 	if (read(id,buf,GCC_HEADER) != GCC_HEADER)
 		die("Unable to read header of 'system'");
-	if (N_MAGIC(*ex) != ZMAGIC)
+	if (N_MAGIC(*ex) == ZMAGIC) {
+		GCC_HEADER = N_MAGIC_OFFSET;
+		lseek(id, GCC_HEADER, SEEK_SET);
+	} else if (N_MAGIC(*ex) != QMAGIC)
 		die("Non-GCC header of 'system'");
 	fprintf(stderr,"System is %d kB (%d kB code, %d kB data and %d kB bss)\n",
 		(ex->a_text+ex->a_data+ex->a_bss)/1024,
diff -u --recursive v1.1.33/linux/zBoot/Makefile linux/zBoot/Makefile
--- v1.1.33/linux/zBoot/Makefile	Wed Mar  9 11:11:16 1994
+++ linux/zBoot/Makefile	Fri Jul 22 12:49:28 1994
@@ -11,14 +11,14 @@
 .c.s:
 	$(CC) $(CFLAGS) -S -o $*.s $<
 .s.o:
-	$(AS) -c -o $*.o $<
+	$(AS) -o $*.o $<
 .c.o:
 	$(CC) $(CFLAGS) -c -o $*.o $<
 
 all:	zSystem
 
 zSystem:	piggy.o $(zOBJECTS)
-		$(LD) $(LDFLAGS) -o zSystem -Ttext 1000 $(zOBJECTS) piggy.o
+		$(LD) $(LOWLDFLAGS) -o zSystem $(zOBJECTS) piggy.o
 
 head.o:	head.s
 
diff -u --recursive v1.1.33/linux/zBoot/xtract.c linux/zBoot/xtract.c
--- v1.1.33/linux/zBoot/xtract.c	Wed Dec  1 14:44:15 1993
+++ linux/zBoot/xtract.c	Fri Jul 22 13:34:18 1994
@@ -18,8 +18,10 @@
 #include <a.out.h>
 #include <linux/config.h>
 
-#define GCC_HEADER 1024
+#define N_MAGIC_OFFSET 1024
 
+static int GCC_HEADER = sizeof(struct exec);
+
 #define STRINGIFY(x) #x
 
 void die(char * str)
@@ -49,7 +51,10 @@
 		die("Unable to open 'system'");
 	if (read(id,buf,GCC_HEADER) != GCC_HEADER)
 		die("Unable to read header of 'system'");
-	if (N_MAGIC(*ex) != ZMAGIC)
+	if (N_MAGIC(*ex) == ZMAGIC) {
+		GCC_HEADER = N_MAGIC_OFFSET;
+		lseek(id, GCC_HEADER, SEEK_SET);
+	} else if (N_MAGIC(*ex) != QMAGIC)
 		die("Non-GCC header of 'system'");
 
 	sz = N_SYMOFF(*ex) - GCC_HEADER + 4;	/* +4 to get the same result than tools/build */
