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

📄 main.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 2 页
字号:
void calibrate_delay(void){	int ticks;	int loopbit;	int lps_precision = LPS_PREC;	loops_per_sec = (1<<12);	printk("Calibrating delay loop.. ");	while (loops_per_sec <<= 1) {		/* wait for "start of" clock tick */		ticks = jiffies;		while (ticks == jiffies)			/* nothing */;		/* Go .. */		ticks = jiffies;		__delay(loops_per_sec);		ticks = jiffies - ticks;		if (ticks)			break;		}/* Do a binary approximation to get loops_per_second set to equal one clock   (up to lps_precision bits) */	loops_per_sec >>= 1;	loopbit = loops_per_sec;	while ( lps_precision-- && (loopbit >>= 1) ) {		loops_per_sec |= loopbit;		ticks = jiffies;		while (ticks == jiffies);		ticks = jiffies;		__delay(loops_per_sec);		if (jiffies != ticks)	/* longer than 1 tick */			loops_per_sec &= ~loopbit;	}/* finally, adjust loops per second in terms of seconds instead of clocks */		loops_per_sec *= HZ;/* Round the value and print it */		printk("ok - %lu.%02lu BogoMIPS\n",		(loops_per_sec+2500)/500000,		((loops_per_sec+2500)/5000) % 100);#if defined(__SMP__) && defined(__i386__)	smp_loops_per_tick = loops_per_sec / 400;#endif}static void parse_root_dev(char * line){	int base = 0;	static struct dev_name_struct {		const char *name;		const int num;	} devices[] = {		{ "nfs",     0x00ff },		{ "loop",    0x0700 },		{ "hda",     0x0300 },		{ "hdb",     0x0340 },		{ "hdc",     0x1600 },		{ "hdd",     0x1640 },		{ "hde",     0x2100 },		{ "hdf",     0x2140 },		{ "hdg",     0x2200 },		{ "hdh",     0x2240 },		{ "sda",     0x0800 },		{ "sdb",     0x0810 },		{ "sdc",     0x0820 },		{ "sdd",     0x0830 },		{ "sde",     0x0840 },		{ "sdf",     0x0850 },		{ "sdg",     0x0860 },		{ "sdh",     0x0870 },		{ "sdi",     0x0880 },		{ "sdj",     0x0890 },		{ "sdk",     0x08a0 },		{ "sdl",     0x08b0 },		{ "sdm",     0x08c0 },		{ "sdn",     0x08d0 },		{ "sdo",     0x08e0 },		{ "sdp",     0x08f0 },		{ "fd",      0x0200 },		{ "xda",     0x0d00 },		{ "xdb",     0x0d40 },		{ "ram",     0x0100 },		{ "scd",     0x0b00 },		{ "mcd",     0x1700 },		{ "cdu535",  0x1800 },		{ "aztcd",   0x1d00 },		{ "cm206cd", 0x2000 },		{ "gscd",    0x1000 },		{ "sbpcd",   0x1900 },		{ "sonycd",  0x1800 },#ifdef CONFIG_PARIDE_PD       		{ "pda",     0x2d00 },       		{ "pdb",     0x2d10 },       		{ "pdc",     0x2d20 },       		{ "pdd",     0x2d30 },#endif#ifdef CONFIG_PARIDE_PCD     	  	{ "pcd",     0x2e00 },#endif#ifdef CONFIG_PARIDE_PF	       	{ "pf",      0x2f00 },#endif		{ NULL, 0 }	};	if (strncmp(line,"/dev/",5) == 0) {		struct dev_name_struct *dev = devices;		line += 5;		do {			int len = strlen(dev->name);			if (strncmp(line,dev->name,len) == 0) {				line += len;				base = dev->num;				break;			}			dev++;		} while (dev->name);	}	ROOT_DEV = to_kdev_t(base + simple_strtoul(line,NULL,base?10:16));}/* * This is a simple kernel command line parsing function: it parses * the command line, and fills in the arguments/environment to init * as appropriate. Any cmd-line option is taken to be an environment * variable if it contains the character '='. * * * This routine also checks for options meant for the kernel. * These options are not given to init - they are for internal kernel use only. */static void parse_options(char *line){	char *next;	int args, envs;	if (!*line)		return;	args = 0;	envs = 1;	/* TERM is set to 'linux' by default */	next = line;	while ((line = next) != NULL) {		if ((next = strchr(line,' ')) != NULL)			*next++ = 0;		/*		 * check for kernel options first..		 */		if (!strncmp(line,"root=",5)) {			parse_root_dev(line+5);			continue;		}#ifdef CONFIG_ROOT_NFS		if (!strncmp(line, "nfsroot=", 8)) {			int n;			line += 8;			ROOT_DEV = MKDEV(UNNAMED_MAJOR, 255);			if (line[0] == '/' || line[0] == ',' || (line[0] >= '0' && line[0] <= '9')) {				strncpy(nfs_root_name, line, sizeof(nfs_root_name));				nfs_root_name[sizeof(nfs_root_name)-1] = '\0';				continue;			}			n = strlen(line) + strlen(NFS_ROOT);			if (n >= sizeof(nfs_root_name))				line[sizeof(nfs_root_name) - strlen(NFS_ROOT) - 1] = '\0';			sprintf(nfs_root_name, NFS_ROOT, line);			continue;		}		if (!strncmp(line, "nfsaddrs=", 9)) {			line += 9;			strncpy(nfs_root_addrs, line, sizeof(nfs_root_addrs));			nfs_root_addrs[sizeof(nfs_root_addrs)-1] = '\0';			continue;		}#endif		if (!strcmp(line,"ro")) {			root_mountflags |= MS_RDONLY;			continue;		}		if (!strcmp(line,"rw")) {			root_mountflags &= ~MS_RDONLY;			continue;		}		if (!strcmp(line,"debug")) {			console_loglevel = 10;			continue;		}		if (!strncmp(line,"init=",5)) {			line += 5;			execute_command = line;			continue;		}		if (checksetup(line))			continue;		/*		 * Then check if it's an environment variable or		 * an option.		 */		if (strchr(line,'=')) {			if (envs >= MAX_INIT_ENVS)				break;			envp_init[++envs] = line;		} else {			if (args >= MAX_INIT_ARGS)				break;			argv_init[++args] = line;		}	}	argv_init[args+1] = NULL;	envp_init[envs+1] = NULL;}extern void setup_arch(char **, unsigned long *, unsigned long *);extern void arch_syms_export(void);#ifndef __SMP__/* *	Uniprocessor idle thread */ int cpu_idle(void *unused){	for(;;)		idle();}#else/* *	Multiprocessor idle thread is in arch/... */ extern int cpu_idle(void * unused);/* *	Activate a secondary processor. */ asmlinkage void start_secondary(void){	trap_init();	init_IRQ();	smp_callin();	cpu_idle(NULL);}/* *	Called by CPU#0 to activate the rest. */ static void smp_init(void){	int i, j;	smp_boot_cpus();		/*	 *	Create the slave init tasks as sharing pid 0.	 *	 *	This should only happen if we have virtual CPU numbers	 *	higher than 0.	 */	for (i=1; i<smp_num_cpus; i++)	{		struct task_struct *n, *p;		j = cpu_logical_map[i];		/*		 *	We use kernel_thread for the idlers which are		 *	unlocked tasks running in kernel space.		 */		kernel_thread(cpu_idle, NULL, CLONE_PID);		/*		 *	Don't assume linear processor numbering		 */		current_set[j]=task[i];		current_set[j]->processor=j;		cli();		n = task[i]->next_run;		p = task[i]->prev_run;		nr_running--;		n->prev_run = p;		p->next_run = n;		task[i]->next_run = task[i]->prev_run = task[i];		sti();	}}		/* *	The autoprobe routines assume CPU#0 on the i386 *	so we don't actually set the game in motion until *	they are finished. */ static void smp_begin(void){	smp_threads_ready=1;	smp_commence();}	#endif/* *	Activate the first processor. */ asmlinkage void start_kernel(void){	char * command_line;/* *	This little check will move. */#ifdef __SMP__	static int first_cpu=1;		if(!first_cpu)		start_secondary();	first_cpu=0;	#endif	/* * Interrupts are still disabled. Do necessary setups, then * enable them */	setup_arch(&command_line, &memory_start, &memory_end);	memory_start = paging_init(memory_start,memory_end);	trap_init();	init_IRQ();	sched_init();	time_init();	parse_options(command_line);#ifdef CONFIG_MODULES	init_modules();#endif#ifdef CONFIG_PROFILE	if (!prof_shift)#ifdef CONFIG_PROFILE_SHIFT		prof_shift = CONFIG_PROFILE_SHIFT;#else		prof_shift = 2;#endif#endif	if (prof_shift) {		prof_buffer = (unsigned int *) memory_start;		/* only text is profiled */		prof_len = (unsigned long) &_etext - (unsigned long) &_stext;		prof_len >>= prof_shift;		memory_start += prof_len * sizeof(unsigned int);		memset(prof_buffer, 0, prof_len * sizeof(unsigned int));	}	memory_start = console_init(memory_start,memory_end);#ifdef CONFIG_PCI	memory_start = pci_init(memory_start,memory_end);#endif	memory_start = kmalloc_init(memory_start,memory_end);	sti();	calibrate_delay();	memory_start = inode_init(memory_start,memory_end);	memory_start = file_table_init(memory_start,memory_end);	memory_start = name_cache_init(memory_start,memory_end);#ifdef CONFIG_BLK_DEV_INITRD	if (initrd_start && initrd_start < memory_start) {		printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "		    "disabling it.\n",initrd_start,memory_start);		initrd_start = 0;	}#endif	mem_init(memory_start,memory_end);	buffer_init();	sock_init();#if defined(CONFIG_SYSVIPC) || defined(CONFIG_KERNELD)	ipc_init();#endif	dquot_init();	arch_syms_export();	sti();	check_bugs();#if defined(CONFIG_MTRR) && defined(__SMP__)	init_mtrr_config();#endif	printk(linux_banner);#ifdef __SMP__	smp_init();#endif	sysctl_init();	/* 	 *	We count on the initial thread going ok 	 *	Like idlers init is an unlocked kernel thread, which will	 *	make syscalls (and thus be locked).	 */	kernel_thread(init, NULL, 0);/* * task[0] is meant to be used as an "idle" task: it may not sleep, but * it might do some general things like count free pages or it could be * used to implement a reasonable LRU algorithm for the paging routines: * anything that can be useful, but shouldn't take time from the real * processes. * * Right now task[0] just does a infinite idle loop. */ 	cpu_idle(NULL);}static int printf(const char *fmt, ...){	va_list args;	int i;	va_start(args, fmt);	write(1,printbuf,i=vsprintf(printbuf, fmt, args));	va_end(args);	return i;}static int do_rc(void * rc){	close(0);	if (open(rc,O_RDONLY,0))		return -1;	return execve("/bin/sh", argv_rc, envp_rc);}static int do_shell(void * shell){	close(0);close(1);close(2);	setsid();	(void) open("/dev/tty1",O_RDWR,0);	(void) dup(0);	(void) dup(0);	return execve(shell, argv, envp);}#ifdef CONFIG_BLK_DEV_INITRDstatic int do_linuxrc(void * shell){	static char *argv[] = { "linuxrc", NULL, };	close(0);close(1);close(2);	setsid();	(void) open("/dev/tty1",O_RDWR,0);	(void) dup(0);	(void) dup(0);	return execve(shell, argv, envp_init);}static void no_initrd(char *s,int *ints){	mount_initrd = 0;}#endifstatic int init(void * unused){	int pid,i;#ifdef CONFIG_BLK_DEV_INITRD	int real_root_mountflags;#endif	/* Launch bdflush from here, instead of the old syscall way. */	kernel_thread(bdflush, NULL, 0);	/* Start the background pageout daemon. */	kswapd_setup();	kernel_thread(kswapd, NULL, 0);#ifdef CONFIG_BLK_DEV_INITRD	real_root_dev = ROOT_DEV;	real_root_mountflags = root_mountflags;	if (initrd_start && mount_initrd) root_mountflags &= ~MS_RDONLY;	else mount_initrd =0;#endif	setup();#ifdef __SMP__	/*	 *	With the devices probed and setup we can	 *	now enter SMP mode.	 */		smp_begin();#endif		#ifdef CONFIG_UMSDOS_FS	{		/*			When mounting a umsdos fs as root, we detect			the pseudo_root (/linux) and initialise it here.			pseudo_root is defined in fs/umsdos/inode.c		*/		extern struct inode *pseudo_root;		if (pseudo_root != NULL){			current->fs->root = pseudo_root;			current->fs->pwd  = pseudo_root;		}	}	#endif#ifdef CONFIG_BLK_DEV_INITRD	root_mountflags = real_root_mountflags;	if (mount_initrd && ROOT_DEV != real_root_dev && ROOT_DEV == MKDEV(RAMDISK_MAJOR,0)) {		int error;		pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);		if (pid>0)			while (pid != wait(&i));		if (real_root_dev != MKDEV(RAMDISK_MAJOR, 0)) {			error = change_root(real_root_dev,"/initrd");			if (error)				printk(KERN_ERR "Change root to /initrd: "				    "error %d\n",error);		}	}#endif		/*	 *	This keeps serial console MUCH cleaner, but does assume	 *	the console driver checks there really is a video device	 *	attached (Sparc effectively does).	 */	if ((open("/dev/tty1",O_RDWR,0) < 0) &&	    (open("/dev/ttyS0",O_RDWR,0) < 0))		printk("Unable to open an initial console.\n");				(void) dup(0);	(void) dup(0);	if (!execute_command) {		execve("/etc/init",argv_init,envp_init);		execve("/bin/init",argv_init,envp_init);		execve("/sbin/init",argv_init,envp_init);		/* if this fails, fall through to original stuff */		pid = kernel_thread(do_rc, "/etc/rc", SIGCHLD);		if (pid>0)			while (pid != wait(&i))				/* nothing */;	}	while (1) {		pid = kernel_thread(do_shell,			execute_command ? execute_command : "/bin/sh",			SIGCHLD);		if (pid < 0) {			printf("Fork failed in init\n\r");			continue;		}		while (1)			if (pid == wait(&i))				break;		printf("\n\rchild %d died with code %04x\n\r",pid,i);		sync();	}	return -1;}

⌨️ 快捷键说明

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