⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 misc.c

📁 linux1.1源代码
💻 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 + -