[LinuxBIOS] [FEATURE] payload compression

Stefan Reinauer stepan at coresystems.de
Sat Apr 29 21:57:00 CEST 2006


Hi,

while I've been working on FILO and OpenBIOS lately I really wished
that they could be used as nrv2b compressed payload, like its possible
with etherboot.

Since etherboot is probably not going to be developed beyond v5.5 and
because the zelf support in etherboot is really ugly, I thought of an
alternative to support compressed payloads easily.

So I wrote a new stream which can be enabled by using
CONFIG_COMPRESSED_ROM_STREAM instead of CONFIG_ROM_STREAM.

When you enable CONFIG_COMPRESSED_ROM_STREAM, the payload you specify
will completely automatically be compressed during the build stage, so
you don't have to do anything except safe space with a few small
changes.

Stefan

-- 
coresystems GmbH • Brahmsstr. 16 • D-79104 Freiburg i. Br.
      Tel.: +49 761 7668825 • Fax: +49 761 7664613
Email: info at coresystems.dehttp://www.coresystems.de/
-------------- next part --------------
Index: src/stream/Config.lb
===================================================================
--- src/stream/Config.lb	(revision 2286)
+++ src/stream/Config.lb	(working copy)
@@ -1,3 +1,4 @@
+uses CONFIG_COMPRESSED_ROM_STREAM
 uses CONFIG_ROM_STREAM
 uses CONFIG_IDE_STREAM
 uses CONFIG_FS_STREAM
@@ -7,6 +8,10 @@
   object rom_stream.o
 end
 
+if CONFIG_COMPRESSED_ROM_STREAM
+  object zrom_stream.o
+end
+
 if CONFIG_IDE_STREAM
   default CONFIG_IDE=1
   object ide_stream.o
Index: src/stream/zrom_stream.c
===================================================================
--- src/stream/zrom_stream.c	(revision 0)
+++ src/stream/zrom_stream.c	(revision 0)
@@ -0,0 +1,133 @@
+#include <console/console.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stream/read_bytes.h>
+#include <string.h>
+
+#define GETBIT(bb, src, ilen) \
+    (bc > 0 ? ((bb>>--bc)&1) : (bc=31,\
+    bb=*(const uint32_t *)((src)+ilen),ilen+=4,(bb>>31)&1))
+
+static void unrv2b(uint8_t * src, uint8_t * dst)
+{
+	unsigned long ilen = 0, olen = 0, last_m_off = 1;
+	uint32_t bb = 0;
+	unsigned bc = 0;
+	const uint8_t *m_pos;
+
+	src += 4;
+
+	for (;;) {
+		unsigned int m_off, m_len;
+		while (GETBIT(bb, src, ilen)) {
+			dst[olen++] = src[ilen++];
+		}
+
+		m_off = 1;
+		do {
+			m_off = m_off * 2 + GETBIT(bb, src, ilen);
+		} while (!GETBIT(bb, src, ilen));
+		if (m_off == 2) {
+			m_off = last_m_off;
+		} else {
+			m_off = (m_off - 3) * 256 + src[ilen++];
+			if (m_off == 0xffffffffU)
+				break;
+			last_m_off = ++m_off;
+		}
+
+		m_len = GETBIT(bb, src, ilen);
+		m_len = m_len * 2 + GETBIT(bb, src, ilen);
+		if (m_len == 0) {
+			m_len++;
+			do {
+				m_len = m_len * 2 + GETBIT(bb, src, ilen);
+			} while (!GETBIT(bb, src, ilen));
+			m_len += 2;
+		}
+		m_len += (m_off > 0xd00);
+
+		m_pos = dst + olen - m_off;
+		dst[olen++] = *m_pos++;
+		do {
+			dst[olen++] = *m_pos++;
+		} while (--m_len > 0);
+	}
+
+}
+
+#ifndef CONFIG_ROM_STREAM_START
+#define CONFIG_ROM_STREAM_START 0xffff0000UL
+#endif
+
+unsigned char *rom_start = (unsigned char *)CONFIG_ROM_STREAM_START;
+unsigned char *rom_end = (unsigned char *)(CONFIG_ROM_STREAM_START + PAYLOAD_SIZE - 1);;
+
+extern unsigned char _heap, _eheap;
+
+static const unsigned char *rom;
+
+int stream_init(void)
+{
+	unsigned long compressed_rom_start=rom_start; 
+	unsigned long compressed_rom_end=rom_end; 
+	unsigned int len;
+	
+	len=*(unsigned int *)compressed_rom_start; // LE only for now
+
+	printk_debug (" compressed rom stream: 0x%08lx - 0x%08lx\n",
+				compressed_rom_start, compressed_rom_end);
+
+	rom_start = &_eheap;
+	rom_end = rom_start + len; // LE only for now
+#if 0
+	{
+	int i;
+	for (i=0; i<512; i++) {
+		if( i%16==0) printk_spew("\n%04x :", i);
+		printk_spew(" %02x", *(unsigned char *)(compressed_rom_start+i));
+	}
+	}
+#endif
+	printk_debug(" rom stream: 0x%08lx - 0x%08lx\n", (unsigned long) 
+			rom_start, (unsigned long) rom_end);
+
+	printk_debug("Uncompressing...");
+	unrv2b((uint8_t *) compressed_rom_start, (uint8_t *)rom_start);
+	printk_debug(" done.\n");
+	
+	rom = rom_start;
+
+	return 0;
+}
+
+void stream_fini(void)
+{
+	return;
+}
+
+byte_offset_t stream_skip(byte_offset_t count)
+{
+	byte_offset_t bytes;
+	bytes = count;
+	if ((rom + bytes) > rom_end) {
+		printk_warning(" overflowed source buffer\n");
+		bytes = 0;
+		if (rom <= rom_end) {
+			bytes = (rom_end - rom) + 1;
+		}
+	}
+	rom += bytes;
+	return bytes;
+}
+
+byte_offset_t stream_read(void *vdest, byte_offset_t count)
+{
+	unsigned char *dest = vdest;
+	const unsigned char *src = rom;
+	byte_offset_t bytes;
+
+	bytes = stream_skip(count);
+	memcpy(dest, src, bytes);
+	return bytes;
+}
Index: src/stream/rom_stream.c
===================================================================
--- src/stream/rom_stream.c	(revision 2286)
+++ src/stream/rom_stream.c	(working copy)
@@ -18,8 +18,8 @@
  */
 
 /*XXXXXXXXXXXXXX */
-/*static const */unsigned char *rom_start = (void *)CONFIG_ROM_STREAM_START;
-/*static const */unsigned char *rom_end   = (void *)(CONFIG_ROM_STREAM_START + PAYLOAD_SIZE - 1);
+/*static const */unsigned char *rom_start = (unsigned char *)CONFIG_ROM_STREAM_START;
+/*static const */unsigned char *rom_end   = (unsigned char *)(CONFIG_ROM_STREAM_START + PAYLOAD_SIZE - 1);
 /*XXXXXXXXXXXXXX */
 static const unsigned char *rom;
 
Index: src/config/Options.lb
===================================================================
--- src/config/Options.lb	(revision 2286)
+++ src/config/Options.lb	(working copy)
@@ -564,6 +564,11 @@
 	export always
 	comment "ROM stream start location"
 end
+define CONFIG_COMPRESSED_ROM_STREAM
+	default 0
+	export always
+	comment "compressed boot image is located in ROM" 
+end
 define CONFIG_FS_STREAM
 	default 0
 	export always
Index: src/arch/i386/Config.lb
===================================================================
--- src/arch/i386/Config.lb	(revision 2286)
+++ src/arch/i386/Config.lb	(working copy)
@@ -18,9 +18,22 @@
 	action	"$(HOSTCC) -O2 -DENCODE -DDECODE -DMAIN -DVERBOSE -DNDEBUG -DBITSIZE=32 -DENDIAN=0 $< -o $@"
 end
 
+makerule payload
+	depends "$(PAYLOAD)"
+	action  "cp $< $@"
+end
+
+makerule payload.nrv2b
+	depends "$(PAYLOAD) nrv2b"
+	action  "./nrv2b e $(PAYLOAD) $@"
+end
+
+makedefine PAYLOAD-1:=payload
+makedefine PAYLOAD-$(CONFIG_COMPRESSED_ROM_STREAM):=payload.nrv2b
+
 makerule linuxbios.rom 
-	depends	"linuxbios.strip buildrom" 
-	action "./buildrom $< $@ $(PAYLOAD) $(ROM_IMAGE_SIZE) $(ROM_SECTION_SIZE)"
+	depends	"linuxbios.strip buildrom $(PAYLOAD-1)" 
+	action "./buildrom $< $@ $(PAYLOAD-1) $(ROM_IMAGE_SIZE) $(ROM_SECTION_SIZE)"
 end
 
 makerule crt0.S


More information about the coreboot mailing list