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

📄 main.c

📁 开放源码的Boot
💻 C
字号:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/fcntl.h>#include <errno.h>#include <unistd.h>#include "y.tab.h"#include "nodes.h"#include "x_malloc.h"#define MAP 0#define LIST 1extern char *version;extern char *date;char *boot_dev = DEFBOOT;static char *root_dir = NULL;static char *config_file = CONFIGFILE;int verbose = 0;extern int yyparse (void);extern FILE *yyin;int xwrite (int fild, void *p, int size){	int written = 0, i;	do	{		i = write (fild, (char *)p + written, size - written);		if (i == -1) {			if (errno == EINTR)				continue;			return i;		}		written += i;	}	while (written < size);	return written;}/* * Structure of kernel block written to buffer: *  0	0		type (0 = riscos, 1 = linux) *  1	4		name offset in file	[null terminated] *  2	8		args offset in file	[null terminated] *  3	12		bmap offset in file	[null entry terminated] *  4	16		password offset in file [null terminated] *  5	20		kernels idea of root fs *  6	24		ramdisk size *  7	28		flags *  8   32		initrd offset in file	[null terminated] *  9   36		rd start */ /* * Calculate the positions of the various parts of the file * and write the actual file, keeping a backup of the old */void create_config_file (void){	int blocksize = 40;	int current_offset = (num_cnodes + 1) * blocksize;	struct compressed_node *node;	int fild;	unsigned long buffer[16];	for (node = cnode; node; node = node->next)	{		if (node->name) {			node->file_name_offset = current_offset;			current_offset += strlen (node->name) + 1;		} else			node->file_name_offset = 0;		if (node->passwd) {			node->file_passwd_offset = current_offset;			current_offset += strlen (node->passwd) + 1;		} else			node->file_passwd_offset = 0;		if (node->args) {			node->file_args_offset = current_offset;			current_offset += strlen (node->args) + 1;		} else			node->file_args_offset = 0;		if (node->bmap) {			current_offset = (current_offset + 3) & ~3; 			node->file_bmap_offset = current_offset;			current_offset += node->bmap_size;		} else			node->file_bmap_offset = 0;		if (node->initrd) {			current_offset = (current_offset + 3) & ~3;			node->file_initrd_offset = current_offset;			current_offset += node->initrd_size;		} else			node->file_initrd_offset = 0;	}	memset (buffer, 0, sizeof (buffer));	buffer[0] = 0xC35AE183;			/* magic             */	buffer[1] = 0x17089700 + blocksize;	/* date + entry size */	buffer[2] = num_cnodes;			/* number of entries */	rename ("/boot/boot.map", "/boot/boot.map.old");	fild = open ("/boot/boot.map", O_CREAT|O_RDWR, 0400);	if (fild < 0) {		perror ("cfg: open: /boot/boot.map");		exit (1);	}	if (xwrite (fild, buffer, blocksize) < 0) {		perror ("write: prefix");		close (fild);		remove("/boot/boot.map");		rename("/boot/boot.map.old", "/boot/boot.map");		exit (1);	}	for (node = cnode; node; node = node->next) {		buffer[0] = node->type == KERNEL? 1 : 0;		buffer[1] = node->file_name_offset;		buffer[2] = node->file_args_offset;		buffer[3] = node->file_bmap_offset;		buffer[4] = node->file_passwd_offset;		buffer[5] = node->root;		buffer[6] = node->ramdisk_size;		buffer[7] = node->flags;		buffer[8] = node->file_initrd_offset;		buffer[9] = node->rdstart;		if (xwrite (fild, buffer, blocksize) < 0) {			perror ("write: kernel image");			close (fild);			remove("/boot/boot.map");			rename("/boot/boot.map.old", "/boot/boot.map");			exit (1);		}	}	for (node = cnode; node; node = node->next) {		int i = 0;		if (node->file_name_offset)			i = xwrite (fild, node->name, strlen (node->name) + 1);		if (node->file_passwd_offset && i >= 0)			i = xwrite (fild, node->passwd, strlen (node->passwd) + 1);		if (node->file_args_offset && i >= 0)			i = xwrite (fild, node->args, strlen (node->args) + 1);		if (node->file_bmap_offset && i >= 0) {			lseek (fild, node->file_bmap_offset, SEEK_SET);			i = xwrite (fild, node->bmap, node->bmap_size);		}		if (node->file_initrd_offset && i >= 0) {			lseek (fild, node->file_initrd_offset, SEEK_SET);			i = xwrite (fild, node->initrd, node->initrd_size);		}		if (i < 0) {			perror ("write: kernel image info");			close (fild);			remove("/boot/boot.map");			rename("/boot/boot.map.old", "/boot/boot.map");			exit (1);		}	}	close (fild);}void write_map_header (void){	unsigned long *addr, *addr2;	char sector[512]; /* only one sector */	char old_sector[512];	char bkname[32];	int filp, bkfilp, len;	addr2 = (unsigned long *)&sector[0];	memset(sector, 0, sizeof (sector));	len = map_file ("/boot/boot.map", &addr);	if (len < 0)		exit (1);	addr2[0] = 0xc53a4b2d;	addr2[1] = addr[1];	for (filp = 2; filp < len / sizeof (unsigned long); filp++)		addr2[filp] = addr[filp];	filp = open (boot_dev, O_RDWR);	if (filp < 0) {		perror ("open boot device");		exit (1);	}		sprintf (bkname, "/boot/bsect.%04X", get_boot_dev ());	if (access (bkname, F_OK) == -1 && errno == ENOENT) {		if (verbose)			printf ("Backing up boot sector information to %s\n", bkname);		bkfilp = open (bkname, O_RDWR|O_CREAT, 0600);		if (bkfilp < 0) {			perror ("open backup file");			close (filp);			exit (1);		}		if (lseek (filp, 0, SEEK_SET) < 0) {			perror ("lseek root device");			close (filp);			close (bkfilp);			remove (bkname);			exit (1);		}		if (read (filp, old_sector, 512) != 512) {			perror ("read root device");			close (filp);			close (bkfilp);			remove (bkname);			exit (1);		}		if (write (bkfilp, old_sector, 512) != 512) {			perror ("write backup file");			close (filp);			close (bkfilp);			remove (bkname);			exit (1);		}		close (bkfilp);	}	if (verbose)		printf ("Writing boot sector\n");	if (lseek (filp, 0, SEEK_SET) < 0) {		perror ("lseek root device");		close (filp);		exit (1);	}	if (write (filp, sector, 512) != 512) {		perror ("write root device");		close (filp);		exit (1);	}	close (filp);}	void usage (FILE *out, int exitstatus){	fprintf (out, "Usage: loadmap [OPTIONS]\n\n");	fprintf (out, " -r, --root ROOT\tSpecify the root of directories to use\n");	fprintf (out, " -R, --rdev ROOTDEV\tSpecify the root device to write to\n");	fprintf (out, " -C, --config CONFIG\tSpecify the configuration file\n");	fprintf (out, " -l, --list\t\tList the currently bootable images\n");	fprintf (out, " -v, --verbose\t\tBe verbose\n");	fprintf (out, " -V, --version\t\tPrint version and exit\n");	fprintf (out, " -h, --help\t\tPrint this help and exit\n");	exit (exitstatus);}int main (int argc, char *argv[]){	int i;	int todo = MAP;	for (i = 1; i < argc; i++) {		if (strcmp (argv[i], "--root") == 0 || strcmp (argv[i], "-r") == 0) {			if (i + 1 > argc)				goto needs_arg;			root_dir = argv[++i];			continue;		}		if (strcmp (argv[i], "--rdev") == 0 || strcmp (argv[i], "-R") == 0) {			if (i + 1 > argc)				goto needs_arg;			boot_dev = argv[++i];			continue;		}		if (strcmp (argv[i], "--config") == 0 || strcmp (argv[i], "-C") == 0) {			if (i + 1 > argc)				goto needs_arg;			config_file = argv[++i];			continue;		}		if (strcmp (argv[i], "--list") == 0 || strcmp (argv[i], "-l") == 0) {			todo = LIST;			continue;		}		if (strcmp (argv[i], "--verbose") == 0 || strcmp (argv[i], "-v") == 0) {			verbose = 1;			continue;		}		if (strcmp (argv[i], "--help") == 0 || strcmp (argv[i], "-h") == 0)			usage (stdout, 0);		if (strcmp (argv[i], "--version") == 0 || strcmp (argv[i], "-V") == 0) {			fprintf (stderr, "loadmap version %s (%s)\n", version, date);			exit (0);		}		fprintf (stderr, "Invalid option '%s'\n", argv[i]);		usage (stderr, 1);needs_arg:		fprintf (stderr, "Option '%s' requires an argument\n", argv[i]);		usage (stderr, 1);	}	if (root_dir)		chroot (root_dir);        if (todo == MAP) {                yyin = fopen (config_file, "rt");                if (!yyin) {                        fprintf (stderr, "Can't open '%s'\n", config_file);                        exit (1);                }        }	if (todo == MAP) {		yyparse ();		if (compress_nodes ())			exit (1);		if (verbose)			dump_cnode (cnode);		create_config_file ();		write_map_header ();	} else {	}	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -