* 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.