📄 misc.c
字号:
/* * misc.c * * This is a collection of several routines from gzip-1.0.3 * adapted for Linux. * * malloc by Hannu Savolainen 1993 * puts by Nick Holloway 1993 */#include "gzip.h"#include "lzw.h"#include <linux/segment.h>/* * These are set up by the setup-routine at boot-time: */struct screen_info { unsigned char orig_x; unsigned char orig_y; unsigned char unused1[2]; unsigned short orig_video_page; unsigned char orig_video_mode; unsigned char orig_video_cols; unsigned short orig_video_ega_ax; unsigned short orig_video_ega_bx; unsigned short orig_video_ega_cx; unsigned char orig_video_lines;};/* * This is set up by the setup-routine at boot-time */#define EXT_MEM_K (*(unsigned short *)0x90002)#define DRIVE_INFO (*(struct drive_info *)0x90080)#define SCREEN_INFO (*(struct screen_info *)0x90000)#define RAMDISK_SIZE (*(unsigned short *)0x901F8)#define ORIG_ROOT_DEV (*(unsigned short *)0x901FC)#define AUX_DEVICE_INFO (*(unsigned char *)0x901FF)#define EOF -1DECLARE(uch, inbuf, INBUFSIZ);DECLARE(uch, outbuf, OUTBUFSIZ+OUTBUF_EXTRA);DECLARE(uch, window, WSIZE);unsigned outcnt;unsigned insize;unsigned inptr;extern char input_data[];extern int input_len;int input_ptr;int method, exit_code, part_nb, last_member;int test = 0;int force = 0;int verbose = 1;long bytes_in, bytes_out;char *output_data;unsigned long output_ptr;extern int end;long free_mem_ptr = (long)&end;int to_stdout = 0;int hard_math = 0;void (*work)(int inf, int outf);void makecrc(void);local int get_method(int);char *vidmem = (char *)0xb8000;int lines, cols;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 > 0x90000) error("\nOut of memory\n"); if (p == NULL) error("malloc = NULL\n"); return p;}void free(void *where){ /* Don't care */}static void scroll(){ int i; memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 ); for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 ) vidmem[i] = ' ';}static void puts(char *s){ int x,y; 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;}__ptr_t memset(__ptr_t s, int c, size_t n){ int i; char *ss = (char*)s; for (i=0;i<n;i++) ss[i] = c;}__ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src, size_t __n){ int i; char *d = (char *)__dest, *s = (char *)__src; for (i=0;i<__n;i++) d[i] = s[i];}extern ulg crc_32_tab[]; /* crc table, defined below *//* =========================================================================== * Run a set of bytes through the crc shift register. If s is a NULL * pointer, then initialize the crc shift register contents instead. * Return the current crc in either case. */ulg updcrc(s, n) uch *s; /* pointer to bytes to pump through */ unsigned n; /* number of bytes in s[] */{ register ulg c; /* temporary variable */ static ulg crc = (ulg)0xffffffffL; /* shift register contents */ if (s == NULL) { c = 0xffffffffL; } else { c = crc; while (n--) { c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8); } } crc = c; return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */}/* =========================================================================== * Clear input and output buffers */void clear_bufs(){ outcnt = 0; insize = inptr = 0; bytes_in = bytes_out = 0L;}/* =========================================================================== * Fill the input buffer. This is called only when the buffer is empty * and at least one byte is really needed. */int fill_inbuf(){ int len, i; /* Read as much as possible */ insize = 0; do { len = INBUFSIZ-insize; if (len > (input_len-input_ptr+1)) len=input_len-input_ptr+1; if (len == 0 || len == EOF) break; for (i=0;i<len;i++) inbuf[insize+i] = input_data[input_ptr+i]; insize += len; input_ptr += len; } while (insize < INBUFSIZ); if (insize == 0) { error("unable to fill buffer\n"); } bytes_in += (ulg)insize; 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.) */void flush_window(){ if (outcnt == 0) return; updcrc(window, outcnt); memcpy(&output_data[output_ptr], (char *)window, outcnt); bytes_out += (ulg)outcnt; output_ptr += (ulg)outcnt; outcnt = 0;}/* * Code to compute the CRC-32 table. Borrowed from * gzip-1.0.3/makecrc.c. */ulg crc_32_tab[256];voidmakecrc(void){/* Not copyrighted 1990 Mark Adler */ unsigned long c; /* crc shift register */ unsigned long e; /* polynomial exclusive-or pattern */ int i; /* counter for all possible eight bit values */ int k; /* byte being shifted into crc apparatus */ /* terms of polynomial defining this crc (except x^32): */ static int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; /* Make exclusive-or pattern from polynomial */ e = 0; for (i = 0; i < sizeof(p)/sizeof(int); i++) e |= 1L << (31 - p[i]); crc_32_tab[0] = 0; for (i = 1; i < 256; i++) { c = 0; for (k = i | 256; k != 1; k >>= 1) { c = c & 1 ? (c >> 1) ^ e : c >> 1; if (k & 1) c ^= e; } crc_32_tab[i] = c; }}void error(char *x){ puts("\n\n"); puts(x); puts("\n\n -- System halted"); while(1); /* Halt */}#define STACK_SIZE (4096)long user_stack [STACK_SIZE];struct { long * a; short b; } stack_start = { & user_stack [STACK_SIZE] , KERNEL_DS };void decompress_kernel(){ if (SCREEN_INFO.orig_video_mode == 7) vidmem = (char *) 0xb0000; else vidmem = (char *) 0xb8000; lines = SCREEN_INFO.orig_video_lines; cols = SCREEN_INFO.orig_video_cols; if (EXT_MEM_K < 1024) error("<2M of mem\n"); output_data = (char *)1048576; /* Points to 1M */ output_ptr = 0; exit_code = 0; test = 0; input_ptr = 0; part_nb = 0; clear_bufs(); makecrc(); puts("Uncompressing Linux..."); method = get_method(0); work(0, 0); puts("done.\n"); puts("Now booting the kernel\n");}/* ======================================================================== * Check the magic number of the input file and update ofname if an * original name was given and to_stdout is not set. * Return the compression method, -1 for error, -2 for warning. * Set inptr to the offset of the next byte to be processed. * This function may be called repeatedly for an input file consisting * of several contiguous gzip'ed members. * IN assertions: there is at least one remaining compressed member. * If the member is a zip file, it must be the only one. */local int get_method(in) int in; /* input file descriptor */{ uch flags; char magic[2]; /* magic header */ magic[0] = (char)get_byte(); magic[1] = (char)get_byte(); method = -1; /* unknown yet */ part_nb++; /* number of parts in gzip file */ last_member = 0; /* assume multiple members in gzip file except for record oriented I/O */ if (memcmp(magic, GZIP_MAGIC, 2) == 0 || memcmp(magic, OLD_GZIP_MAGIC, 2) == 0) { work = unzip; method = (int)get_byte(); flags = (uch)get_byte(); if ((flags & ENCRYPTED) != 0) { error("Input is encrypted\n"); exit_code = ERROR; return -1; } if ((flags & CONTINUATION) != 0) { error("Multi part input\n"); exit_code = ERROR; if (force <= 1) return -1; } if ((flags & RESERVED) != 0) { error("Input has invalid flags\n"); exit_code = ERROR; if (force <= 1) return -1; } (ulg)get_byte(); /* Get timestamp */ ((ulg)get_byte()) << 8; ((ulg)get_byte()) << 16; ((ulg)get_byte()) << 24; (void)get_byte(); /* Ignore extra flags for the moment */ (void)get_byte(); /* Ignore OS type for the moment */ if ((flags & CONTINUATION) != 0) { unsigned part = (unsigned)get_byte(); part |= ((unsigned)get_byte())<<8; if (verbose) { error("Input is not part number 1\n"); } } if ((flags & EXTRA_FIELD) != 0) { unsigned len = (unsigned)get_byte(); len |= ((unsigned)get_byte())<<8; while (len--) (void)get_byte(); } /* Get original file name if it was truncated */ if ((flags & ORIG_NAME) != 0) { if (to_stdout || part_nb > 1) { /* Discard the old name */ while (get_byte() != 0) /* null */ ; } else { } /* to_stdout */ } /* orig_name */ /* Discard file comment if any */ if ((flags & COMMENT) != 0) { while (get_byte() != 0) /* null */ ; } } else if (memcmp(magic, PKZIP_MAGIC, 2) == 0 && inptr == 2 && memcmp(inbuf, PKZIP_MAGIC, 4) == 0) { /* To simplify the code, we support a zip file when alone only. * We are thus guaranteed that the entire local header fits in inbuf. */ inptr = 0; work = unzip; if (check_zipfile(in) == -1) return -1; /* check_zipfile may get ofname from the local header */ last_member = 1; } else if (memcmp(magic, PACK_MAGIC, 2) == 0) { error("packed input"); } else if (memcmp(magic, LZW_MAGIC, 2) == 0) { error("compressed input"); last_member = 1; } if (method == -1) { error("Corrupted input\n"); if (exit_code != ERROR) exit_code = part_nb == 1 ? ERROR : WARNING; return part_nb == 1 ? -1 : -2; } return method;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -