fine LOW_BUFFER_MAX 0x90000 内核低端解压片段的终止地址 #define HEAP_SIZE 0x3000 为解压低码保留的堆的尺寸,堆起始于BSS的结束 static unsigned int low_buffer_end, low_buffer_size; static int high_loaded =0; static uch *high_buffer_start ; static char *vidmem = (char *)0xb8000; static int vidport; static int lines, cols; #include "../../../../lib/inflate.c" static void *malloc(int size) { void *p; if (size if (free_mem_ptr free_mem_ptr = (free_mem_ptr + 3) ~3; 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) { } static void gzip_mark(void **ptr) { *ptr = (void *) free_mem_ptr; } static void gzip_release(void **ptr) { free_mem_ptr = (long) *ptr; } static void scroll(void) { int i; memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 ); for ( i = ( lines - 1 ) * cols * 2; i vidmem[ i ] = ' '; } static void puts(const char *s) { int x,y,pos; char c; x = SCREEN_INFO.orig_x; y = SCREEN_INFO.orig_y; while ( ( c = *s++ ) != '\0' ) { if ( c == '\n' ) { x = 0; if ( ++y >= lines ) { scroll(); y--; } } else { vidmem [ ( x + cols * y ) * 2 ] = c; if ( ++x >= cols ) { x = 0; if ( ++y >= lines ) { scroll(); y--; } } } } SCREEN_INFO.orig_x = x; SCREEN_INFO.orig_y = y; pos = (x + cols * y) * 2; outb_p(14, vidport); outb_p(0xff (pos >> 9), vidport+1); outb_p(15, vidport); outb_p(0xff (pos >> 1), vidport+1); } void* memset(void* s, int c, size_t n) { int i; char *ss = (char*)s; for (i=0;i 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 return __dest; } 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]; } static void flush_window_low(void) { ulg c = crc; unsigned n; uch *in, *out, ch; in = window; out = for (n = 0; 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; } static void flush_window_high(void) { ulg c = crc; unsigned n; uch *in, ch; in = window; for (n = 0; 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(void) { if (high_loaded) flush_window_high(); else flush_window_low(); } static void error(char *x) { puts("\n\n"); puts(x); puts("\n\n -- System halted"); while(1); } #define STACK_SIZE (4096) long user_stack [STACK_SIZE]; struct { long * a; short b; } stack_start = { user_stack [STACK_SIZE] , __KERNEL_DS }; void setup_normal_output_buffer(void) 对于zImage, 直接解压到1M { #ifdef STANDARD_MEMORY_BIOS_CALL if (EXT_MEM_K #else if ((ALT_MEM_K > EXT_MEM_K ALT_MEM_K : EXT_MEM_K) #endif output_data = (char *)0x100000; free_mem_end_ptr = (long)real_mode; } 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) + HEAP_SIZE);内核高端片段的最小起始地址 #ifdef STANDARD_MEMORY_BIOS_CALL if (EXT_MEM_K #else if ((ALT_MEM_K > EXT_MEM_K ALT_MEM_K : EXT_MEM_K) #endif mv->low_buffer_start = output_data = (char *)LOW_BUFFER_START; low_buffer_end = ((unsigned int)real_mode > LOW_BUFFER_MAX LOW_BUFFER_MAX : (unsigned int)real_mode) ~0xfff; low_buffer_size = low_buffer_end - LOW_BUFFER_START; high_loaded = 1; free_mem_end_ptr = (long)high_buffer_start; if ( (0x100000 + low_buffer_size) > ((u |