* Compressed kernel image
@ 2002-09-16 14:16 Johannes Stezenbach
0 siblings, 0 replies; only message in thread
From: Johannes Stezenbach @ 2002-09-16 14:16 UTC (permalink / raw)
To: linux-mips
[-- Attachment #1: Type: text/plain, Size: 1161 bytes --]
Hi,
for the embedded Linux project I'm working on I needed the
ability to boot a compressed kernel image from ROM, i.e.
uncompress it to RAM and jump to the kernel entry.
So I took some parts from arch/i386/boot/compressed,
and some from linux-mips.sf.net/arch/mips/zboot/ and
hacked up something which works for me.
The appended patch is incomplete as I removed anything
specific to my platform. To use it for a different platform
you would need:
- A head.S which works for your board. Depending on what
your bootloader does, you probably don't need the
cache flushing stuff.
- For debug output, you need a putc() implementation; maybe
the included uart16550.c works for you. If you think you don't
need to debug anything ;-), you could use a dummy putc().
- Set some configuration variables in the Makefile. I tested
both booting from ROM and loading the zImage to RAM, then
uncompressing to some different area in RAM.
Note: For my platform I allocate a 2MB frame buffer at
0x80002000 in unified memory, so reuse this space
for uncompressing the zImage.
I hope the patch is of use to someone. Comments are welcome.
Regards,
Johannes
[-- Attachment #2: linux-oss-zimage.patch --]
[-- Type: text/plain, Size: 17351 bytes --]
diff -urN linux-oss.orig/arch/mips/Makefile linux-oss/arch/mips/Makefile
--- linux-oss.orig/arch/mips/Makefile 2002-09-09 21:30:11.000000000 +0200
+++ linux-oss/arch/mips/Makefile 2002-09-16 14:55:40.000000000 +0200
@@ -475,6 +475,11 @@
endif
MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+MAKEZBOOT = $(MAKE) -C arch/$(ARCH)/boot/compressed
+
+BOOT_TARGETS = zImage
+$(BOOT_TARGETS): vmlinux
+ @$(MAKEZBOOT) $@
vmlinux.ecoff: vmlinux
@$(MAKEBOOT) $@
@@ -484,6 +489,7 @@
rm -f arch/$(ARCH)/ld.script
$(MAKE) -C arch/$(ARCH)/tools clean
$(MAKE) -C arch/mips/baget clean
+ $(MAKE) -C arch/$(ARCH)/boot/compressed clean
archmrproper:
@$(MAKEBOOT) mrproper
diff -urN linux-oss.orig/arch/mips/boot/compressed/Makefile linux-oss/arch/mips/boot/compressed/Makefile
--- linux-oss.orig/arch/mips/boot/compressed/Makefile 1970-01-01 01:00:00.000000000 +0100
+++ linux-oss/arch/mips/boot/compressed/Makefile 2002-09-16 15:01:13.000000000 +0200
@@ -0,0 +1,74 @@
+#
+# linux/arch/mips/boot/compressed/Makefile
+#
+# create a compressed zImage from the original vmlinux
+#
+
+HEAD = head.o
+SYSTEM = $(TOPDIR)/vmlinux
+
+ZLDFLAGS = -e zstartup -T $(TOPDIR)/arch/mips/ld.script
+
+all: $(TOPDIR)/zImage
+
+##################################################################
+# board configuration
+##################################################################
+
+ifdef CONFIG_FOOBAR // board specific
+
+# ZIMAGE_OFFSET is the load offset of the compression loader
+ifdef BOOT_FROM_ROM
+# zImage in ROM after boot code
+ZIMAGE_OFFSET := 0x9fc20000
+ZBSS := -Tbss 0x80002000
+else
+# for loading in RAM
+ZIMAGE_OFFSET := 0x81000000
+endif
+
+# *MUST* match LOADADDR from arch/mips/Makefile
+LOADADDR := 0x80202000
+KERNEL_ENTRY = $(shell $(OBJDUMP) -f $(SYSTEM) | sed -n -e 's/^start address //p')
+# working space for gunzip:
+FREE_RAM := 0x80080000
+END_RAM := 0x80200000
+# putc config
+PUTC_IMPL := uart16550.o
+uart16550.o: uart16550.c Makefile
+ $(CC) $(CFLAGS) -DBASE=0xb2001000 -DMAX_BAUD=1152000 -DREG_OFFSET=0x10 -c uart16550.c
+endif
+
+##################################################################
+
+OBJECTS = $(HEAD) misc.o $(PUTC_IMPL)
+
+ZLINKFLAGS = -Ttext $(ZIMAGE_OFFSET) $(ZBSS) $(ZLDFLAGS)
+
+.PHONY: zImage
+zImage: $(TOPDIR)/zImage
+
+$(TOPDIR)/zImage: piggy.o $(OBJECTS)
+ $(LD) $(ZLINKFLAGS) -o $(TOPDIR)/zImage $(OBJECTS) piggy.o
+
+head.o: head.S Makefile $(SYSTEM)
+ $(CC) $(AFLAGS) -DKERNEL_ENTRY=$(KERNEL_ENTRY) -c head.S
+
+comma := ,
+
+misc.o: misc.c Makefile
+ $(CC) $(CFLAGS) -DLOADADDR=$(LOADADDR) \
+ -DFREE_RAM=$(FREE_RAM) -DEND_RAM=$(END_RAM) \
+ -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -c misc.c
+
+piggy.o: $(SYSTEM)
+ tmppiggy=_tmp_$$$$piggy; \
+ rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk; \
+ $(OBJCOPY) -S -O binary -R .note -R .comment $(SYSTEM) $$tmppiggy; \
+ gzip -f -9 < $$tmppiggy > $$tmppiggy.gz; \
+ echo "SECTIONS { .data : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) input_data_end = .; }}" > $$tmppiggy.lnk; \
+ $(LD) -r -o piggy.o -b binary $$tmppiggy.gz -b elf32-tradbigmips -T $$tmppiggy.lnk; \
+ rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk
+
+clean:
+ rm -f $(TOPDIR)/zImage _tmp_* *.o
diff -urN linux-oss.orig/arch/mips/boot/compressed/head.S linux-oss/arch/mips/boot/compressed/head.S
--- linux-oss.orig/arch/mips/boot/compressed/head.S 1970-01-01 01:00:00.000000000 +0100
+++ linux-oss/arch/mips/boot/compressed/head.S 2002-09-16 15:11:48.000000000 +0200
@@ -0,0 +1,100 @@
+/*
+ * arch/mips/boot/compressed/head.S
+ *
+ * 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, 1995 Waldorf Electronics
+ * Written by Ralf Baechle and Andreas Busse
+ * Copyright (C) 1995 - 1999 Ralf Baechle
+ * Copyright (C) 1996 Paul M. Antoine
+ * Modified for DECStation and hence R3000 support by Paul M. Antoine
+ * Further modifications by David S. Miller and Harald Koerfgen
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ *
+ * Head.S contains the MIPS exception handler and startup code.
+ *
+ **************************************************************************
+ * 9 Nov, 2000.
+ * Added Cache Error exception handler and SBDDP EJTAG debug exception.
+ *
+ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ **************************************************************************
+ * 08/2002 modified for zImage boot from ROM
+ * Johannes Stezenbach <js@convergence.de>
+ */
+
+
+#include <linux/config.h>
+#include <linux/threads.h>
+
+#include <asm/asm.h>
+#include <asm/cacheops.h>
+#include <asm/mipsregs.h>
+#include <asm/offset.h>
+#include <asm/cachectl.h>
+#include <asm/regdef.h>
+
+#define IndexInvalidate_I 0x00
+
+ .set noreorder
+ .cprestore
+ LEAF(zstartup)
+zstartup:
+
+ la sp, .stack
+ move s0, a0
+ move s1, a1
+ move s2, a2
+ move s3, a3
+
+ /* Clear BSS */
+ /* Note: when zImage is in ROM, _edata and _bss point to
+ * ROM space even when using -Tbss on the linker command line;
+ * maybe ld.script needs to be corrected.
+ */
+ la a0, .stack
+ la a2, _end
+1: sw zero, 0(a0)
+ bne a2, a0, 1b
+ addu a0, 4
+
+ /* flush the I-Cache */
+ li k0, 0x80000000 # start address
+ li k1, 0x80004000 # end address (16KB I-Cache)
+ subu k1, 128
+
+2:
+ .set mips3
+ cache IndexInvalidate_I, 0(k0)
+ cache IndexInvalidate_I, 32(k0)
+ cache IndexInvalidate_I, 64(k0)
+ cache IndexInvalidate_I, 96(k0)
+ .set mips0
+
+ bne k0, k1, 2b
+ addu k0, k0, 128
+ /* done */
+
+ la ra, 3f
+ la k0, decompress_kernel
+ jr k0
+ nop
+3:
+
+ move a0, s0
+ move a1, s1
+ move a2, s2
+ move a3, s3
+ li k0, KERNEL_ENTRY
+ jr k0
+ nop
+4:
+ b 4b
+ END(zstartup)
+
+ .bss
+ .fill 0x2000
+ EXPORT(.stack)
diff -urN linux-oss.orig/arch/mips/boot/compressed/misc.c linux-oss/arch/mips/boot/compressed/misc.c
--- linux-oss.orig/arch/mips/boot/compressed/misc.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-oss/arch/mips/boot/compressed/misc.c 2002-08-06 19:19:11.000000000 +0200
@@ -0,0 +1,311 @@
+/*
+ * arch/mips/boot/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
+ * puts by Nick Holloway 1993, better puts by Martin Mares 1995
+ * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
+ *
+ * Modified by RidgeRun Inc.
+ *
+ * 08/2002 modified for booting zImage from ROM
+ * Johannes Stezenbach <js@convergence.de>
+ * (All statically initialized data is read only, all data which needs to be
+ * in RAM must not be statically initialized.)
+ */
+
+#define ZDEBUG 1
+
+#include <linux/types.h>
+
+/*
+ * gzip declarations
+ */
+#define OF(args) args
+#define STATIC static
+#define memzero(s, n) memset ((s), 0, (n))
+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[WSIZE]; /* Sliding window 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 */
+
+
+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 */
+
+void variable_init(void);
+static void puts(const char *);
+extern void putc_init(void);
+extern void putc(unsigned char c);
+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 **);
+
+extern char input_data[];
+extern int input_len;
+
+
+void int2hex(unsigned long val)
+{
+ unsigned char buf[10];
+ int i;
+ for (i = 7; i >= 0; i--)
+ {
+ buf[i] = "0123456789ABCDEF"[val & 0x0F];
+ val >>= 4;
+ }
+ buf[8] = '\0';
+ puts(buf);
+}
+
+static unsigned long byte_count;
+
+int get_byte(void)
+{
+#if ZDEBUG > 1
+ static int printCnt;
+#endif
+ unsigned char c = (inptr < insize ? inbuf[inptr++] : fill_inbuf());
+ byte_count++;
+
+#if ZDEBUG > 1
+ if (printCnt++ < 32)
+ {
+ puts("byte count = ");
+ int2hex(byte_count);
+ puts(" byte val = ");
+ int2hex(c);
+ puts("\n");
+ }
+#endif
+ return c;
+}
+
+/* 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
+
+/*
+ * This is set up by the setup-routine at boot-time
+ */
+
+static long bytes_out;
+static uch *output_data;
+static unsigned long output_ptr;
+
+
+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 **);
+
+static unsigned long free_mem_ptr;
+static unsigned long free_mem_end_ptr;
+
+#include "../../../../lib/inflate.c"
+
+static void *malloc(int size)
+{
+ void *p;
+
+ if (size < 0)
+ error("Malloc error\n");
+ if (free_mem_ptr <= 0) error("Memory error\n");
+
+ free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
+
+ p = (void *) free_mem_ptr;
+ free_mem_ptr += size;
+
+ if (free_mem_ptr >= free_mem_end_ptr)
+ error("\nOut of memory\n");
+
+ return p;
+}
+
+static void free(void *where)
+{ /* Don't care */
+}
+
+static void gzip_mark(void **ptr)
+{
+ *ptr = (void *) free_mem_ptr;
+}
+
+static void gzip_release(void **ptr)
+{
+ free_mem_ptr = (long) *ptr;
+}
+
+static void puts(const char *s)
+{
+ while (*s) {
+ if (*s == 10)
+ putc(13);
+ putc(*s++);
+ }
+}
+
+void *memset(void *s, int c, size_t n)
+{
+ int i;
+ char *ss = (char *) s;
+
+ for (i = 0; i < n; i++)
+ ss[i] = c;
+ return s;
+}
+
+void *memcpy(void *__dest, __const void *__src, size_t __n)
+{
+ int i;
+ char *d = (char *) __dest, *s = (char *) __src;
+
+ for (i = 0; i < __n; i++)
+ d[i] = s[i];
+ return __dest;
+}
+
+/* ===========================================================================
+ * Fill the input buffer. This is called only when the buffer is empty
+ * and at least one byte is really needed.
+ */
+static int fill_inbuf(void)
+{
+ if (insize != 0) {
+ error("ran out of input data\n");
+ }
+
+ inbuf = input_data;
+ insize = input_len;
+ 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.)
+ */
+static void flush_window(void)
+{
+ ulg c = crc; /* temporary variable */
+ 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;
+}
+
+void check_mem(void)
+{
+ int i;
+
+ puts("\ncplens = ");
+ for (i = 0; i < 10; i++) {
+ int2hex(cplens[i]);
+ puts(" ");
+ }
+ puts("\ncplext = ");
+ for (i = 0; i < 10; i++) {
+ int2hex(cplext[i]);
+ puts(" ");
+ }
+ puts("\nborder = ");
+ for (i = 0; i < 10; i++) {
+ int2hex(border[i]);
+ puts(" ");
+ }
+ puts("\n");
+}
+
+static void error(char *x)
+{
+ check_mem();
+ puts("\n\n");
+ puts(x);
+ puts("byte_count = ");
+ int2hex(byte_count);
+ puts("\n");
+ puts("\n\n -- System halted");
+ while (1); /* Halt */
+}
+
+void variable_init(void)
+{
+ byte_count = 0;
+ output_data = (char *) LOADADDR;
+ free_mem_ptr = FREE_RAM;
+ free_mem_end_ptr = END_RAM;
+#if ZDEBUG
+ puts("variable_init:\n");
+ int2hex((unsigned long)output_data); puts("\n");
+ int2hex(free_mem_ptr); puts("\n");
+ int2hex(free_mem_end_ptr); puts("\n");
+ int2hex((unsigned long)input_data); puts("\n");
+ int2hex(input_len); puts("\n");
+#endif
+}
+
+int decompress_kernel(void)
+{
+#if ZDEBUG
+ //check_mem();
+ unsigned long *p = (unsigned long *)LOADADDR;
+#endif
+
+ putc_init();
+ variable_init();
+
+ makecrc();
+ puts("Uncompressing Linux... \n");
+ gunzip(); // ...see inflate.c
+ puts("Ok, booting the kernel.\n");
+
+#if ZDEBUG
+ int2hex(p[0]); puts("\n");
+ int2hex(p[1]); puts("\n");
+ int2hex(p[2]); puts("\n");
+ int2hex(p[3]); puts("\n");
+#endif
+
+ return 0;
+}
diff -urN linux-oss.orig/arch/mips/boot/compressed/uart16550.c linux-oss/arch/mips/boot/compressed/uart16550.c
--- linux-oss.orig/arch/mips/boot/compressed/uart16550.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-oss/arch/mips/boot/compressed/uart16550.c 2002-09-16 15:16:38.000000000 +0200
@@ -0,0 +1,141 @@
+/*
+ * 16550 uart routines.
+ * based on something similar to arch/mips/vr4181/osprey/dbg_io.c
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ */
+#include <linux/config.h>
+#include <asm/io.h>
+
+/* === CONFIG === */
+
+/*
+ * #define BASE 0xb2001000
+ * #define MAX_BAUD 1152000
+ * #define REG_OFFSET 0x10
+ */
+#if (!defined(BASE) || !defined(MAX_BAUD) || !defined(REG_OFFSET))
+#error You must define BASE, MAX_BAUD and REG_OFFSET in the Makefile.
+#endif
+
+#ifndef INIT_SERIAL_PORT
+#define INIT_SERIAL_PORT 1
+#endif
+
+#ifndef DEFAULT_BAUD
+#define DEFAULT_BAUD UART16550_BAUD_115200
+#endif
+#ifndef DEFAULT_PARITY
+#define DEFAULT_PARITY UART16550_PARITY_NONE
+#endif
+#ifndef DEFAULT_DATA
+#define DEFAULT_DATA UART16550_DATA_8BIT
+#endif
+#ifndef DEFAULT_STOP
+#define DEFAULT_STOP UART16550_STOP_1BIT
+#endif
+
+/* === END OF CONFIG === */
+
+typedef unsigned char uint8;
+typedef unsigned int uint32;
+
+#define UART16550_BAUD_2400 2400
+#define UART16550_BAUD_4800 4800
+#define UART16550_BAUD_9600 9600
+#define UART16550_BAUD_19200 19200
+#define UART16550_BAUD_38400 38400
+#define UART16550_BAUD_57600 57600
+#define UART16550_BAUD_115200 115200
+
+#define UART16550_PARITY_NONE 0
+#define UART16550_PARITY_ODD 0x08
+#define UART16550_PARITY_EVEN 0x18
+#define UART16550_PARITY_MARK 0x28
+#define UART16550_PARITY_SPACE 0x38
+
+#define UART16550_DATA_5BIT 0x0
+#define UART16550_DATA_6BIT 0x1
+#define UART16550_DATA_7BIT 0x2
+#define UART16550_DATA_8BIT 0x3
+
+#define UART16550_STOP_1BIT 0x0
+#define UART16550_STOP_2BIT 0x4
+
+/* register offset */
+#define OFS_RCV_BUFFER (0*REG_OFFSET)
+#define OFS_TRANS_HOLD (0*REG_OFFSET)
+#define OFS_SEND_BUFFER (0*REG_OFFSET)
+#define OFS_INTR_ENABLE (1*REG_OFFSET)
+#define OFS_INTR_ID (2*REG_OFFSET)
+#define OFS_DATA_FORMAT (3*REG_OFFSET)
+#define OFS_LINE_CONTROL (3*REG_OFFSET)
+#define OFS_MODEM_CONTROL (4*REG_OFFSET)
+#define OFS_RS232_OUTPUT (4*REG_OFFSET)
+#define OFS_LINE_STATUS (5*REG_OFFSET)
+#define OFS_MODEM_STATUS (6*REG_OFFSET)
+#define OFS_RS232_INPUT (6*REG_OFFSET)
+#define OFS_SCRATCH_PAD (7*REG_OFFSET)
+
+#define OFS_DIVISOR_LSB (0*REG_OFFSET)
+#define OFS_DIVISOR_MSB (1*REG_OFFSET)
+
+#define UART16550_READ(y) (*((volatile uint8*)(BASE + y)))
+#define UART16550_WRITE(y, z) ((*((volatile uint8*)(BASE + y))) = z)
+
+static void Uart16550Init(uint32 baud, uint8 data, uint8 parity, uint8 stop)
+{
+ /* disable interrupts */
+ UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
+ UART16550_WRITE(OFS_INTR_ENABLE, 0);
+
+ /* set up baud rate */
+ {
+ uint32 divisor;
+
+ /* set DIAB bit */
+ UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
+
+ /* set divisor */
+ divisor = MAX_BAUD / baud;
+ UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
+ UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00)>>8);
+
+ /* clear DIAB bit */
+ UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
+ }
+
+ /* set data format */
+ UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
+}
+
+
+void
+putc_init(void)
+{
+#if INIT_SERIAL_PORT
+ Uart16550Init(DEFAULT_BAUD, DEFAULT_DATA, DEFAULT_PARITY, DEFAULT_STOP);
+#endif
+}
+
+void
+putc(unsigned char c)
+{
+ while ((UART16550_READ(OFS_LINE_STATUS) &0x20) == 0);
+ UART16550_WRITE(OFS_SEND_BUFFER, c);
+}
+
+#if 0
+unsigned char
+getc(void)
+{
+ while((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
+ return UART16550_READ(OFS_RCV_BUFFER);
+}
+
+int
+tstc(void)
+{
+ return((UART16550_READ(OFS_LINE_STATUS) & 0x01) != 0);
+}
+#endif
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2002-09-16 14:16 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-09-16 14:16 Compressed kernel image Johannes Stezenbach
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox