patch-1.3.73 linux/arch/i386/boot/compressed/misc.c
Next file: linux/arch/i386/boot/setup.S
Previous file: linux/arch/i386/boot/compressed/head.S
Back to the patch index
Back to the overall index
- Lines: 143
- Date:
Sat Mar 9 13:31:43 1996
- Orig file:
v1.3.72/linux/arch/i386/boot/compressed/misc.c
- Orig date:
Sun Jan 14 16:30:09 1996
diff -u --recursive --new-file v1.3.72/linux/arch/i386/boot/compressed/misc.c linux/arch/i386/boot/compressed/misc.c
@@ -6,6 +6,7 @@
*
* 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
*/
#include <string.h>
@@ -104,6 +105,7 @@
static long bytes_out = 0;
static uch *output_data;
static unsigned long output_ptr = 0;
+
static void *malloc(int size);
static void free(void *where);
@@ -116,6 +118,15 @@
extern int end;
static long free_mem_ptr = (long)&end;
+static long free_mem_end_ptr = 0x90000;
+
+#define INPLACE_MOVE_ROUTINE 0x1000
+#define LOW_BUFFER_START 0x2000
+#define LOW_BUFFER_END 0x90000
+#define LOW_BUFFER_SIZE ( LOW_BUFFER_END - LOW_BUFFER_START )
+#define HEAP_SIZE 0x2000
+static int high_loaded =0;
+static uch *high_buffer_start /* = (uch *)(((ulg)&end) + HEAP_SIZE)*/;
static char *vidmem = (char *)0xb8000;
static int vidport;
@@ -135,7 +146,7 @@
p = (void *)free_mem_ptr;
free_mem_ptr += size;
- if (free_mem_ptr >= 0x90000)
+ if (free_mem_ptr >= free_mem_end_ptr)
error("\nOut of memory\n");
return p;
@@ -239,7 +250,7 @@
* Write the output window window[0..outcnt-1] and update crc and bytes_out.
* (Used for the decompressed data only.)
*/
-static void flush_window()
+static void flush_window_low()
{
ulg c = crc; /* temporary variable */
unsigned n;
@@ -257,6 +268,28 @@
outcnt = 0;
}
+static void flush_window_high()
+{
+ ulg c = crc; /* temporary variable */
+ unsigned n;
+ uch *in, ch;
+ in = window;
+ for (n = 0; n < outcnt; n++) {
+ ch = *output_data++ = *in++;
+ if ((ulg)output_data == LOW_BUFFER_END) output_data=high_buffer_start;
+ c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+ }
+ crc = c;
+ bytes_out += (ulg)outcnt;
+ outcnt = 0;
+}
+
+static void flush_window()
+{
+ if (high_loaded) flush_window_high();
+ else flush_window_low();
+}
+
static void error(char *x)
{
puts("\n\n");
@@ -303,7 +336,44 @@
#else
-void decompress_kernel()
+void setup_normal_output_buffer()
+{
+ if (EXT_MEM_K < 1024) error("Less than 2MB of memory.\n");
+ output_data = (char *)0x100000; /* Points to 1M */
+}
+
+struct moveparams {
+ uch *low_buffer_start; int lcount;
+ uch *high_buffer_start; int hcount;
+};
+
+void setup_output_buffer_if_we_run_high(struct moveparams *mv)
+{
+ high_buffer_start = (uch *)(((ulg)&end) + HEAP_SIZE);
+ if (EXT_MEM_K < (4*1024)) error("Less than 4MB of memory.\n");
+ mv->low_buffer_start = output_data = (char *)LOW_BUFFER_START;
+ high_loaded = 1;
+ free_mem_end_ptr = (long)high_buffer_start;
+ if ( (0x100000 + LOW_BUFFER_SIZE) > ((ulg)high_buffer_start)) {
+ high_buffer_start = (uch *)(0x100000 + LOW_BUFFER_SIZE);
+ mv->hcount = 0; /* say: we need not to move high_buffer */
+ }
+ else mv->hcount = -1;
+ mv->high_buffer_start = high_buffer_start;
+}
+
+void close_output_buffer_if_we_run_high(struct moveparams *mv)
+{
+ mv->lcount = bytes_out;
+ if (bytes_out > LOW_BUFFER_SIZE) {
+ mv->lcount = LOW_BUFFER_SIZE;
+ if (mv->hcount) mv->hcount = bytes_out - LOW_BUFFER_SIZE;
+ }
+ else mv->hcount = 0;
+}
+
+
+int decompress_kernel(struct moveparams *mv)
{
if (SCREEN_INFO.orig_video_mode == 7) {
vidmem = (char *) 0xb0000;
@@ -316,13 +386,15 @@
lines = SCREEN_INFO.orig_video_lines;
cols = SCREEN_INFO.orig_video_cols;
- if (EXT_MEM_K < 1024) error("Less than 2MB of memory.\n");
+ if (free_mem_ptr < 0x100000) setup_normal_output_buffer();
+ else setup_output_buffer_if_we_run_high(mv);
- output_data = (char *)0x100000; /* Points to 1M */
makecrc();
puts("Uncompressing Linux...");
gunzip();
puts("done.\nNow booting the kernel\n");
+ if (high_loaded) close_output_buffer_if_we_run_high(mv);
+ return high_loaded;
}
#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this