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

📄 main.c,v

📁 powerpc内核mpc8241linux系统下init驱动程序
💻 C,V
📖 第 1 页 / 共 3 页
字号:
static int __init checksetup(char *line){	int i, ints[11];#ifdef CONFIG_BLK_DEV_IDE	/* ide driver needs the basic string, rather than pre-processed values */	if (!strncmp(line,"ide",3) || (!strncmp(line,"hd",2) && line[2] != '=')) {		ide_setup(line);		return 1;	}#endif	for (i=0; raw_params[i].str; i++) {		int n = strlen(raw_params[i].str);		if (!strncmp(line,raw_params[i].str,n)) {			raw_params[i].setup_func(line+n, NULL);			return 1;		}	}	for (i=0; cooked_params[i].str; i++) {		int n = strlen(cooked_params[i].str);		if (!strncmp(line,cooked_params[i].str,n)) {			cooked_params[i].setup_func(get_options(line+n, ints), ints);			return 1;		}	}	return 0;}/* this should be approx 2 Bo*oMips to start (note initial shift), and will   still work even if initially too large, it will just take slightly longer */unsigned long loops_per_sec = (1<<12);/* This is the number of bits of precision for the loops_per_second.  Each   bit takes on average 1.5/HZ seconds.  This (like the original) is a little   better than 1% */#define LPS_PREC 8void __init calibrate_delay(void){	unsigned long ticks, 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("%lu.%02lu BogoMIPS\n",		(loops_per_sec+2500)/500000,		((loops_per_sec+2500)/5000) % 100);}/* * 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 __init 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 (!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;			/* In case LILO is going to boot us with default command line,			 * it prepends "auto" before the whole cmdline which makes			 * the shell think it should execute a script with such name.			 * So we ignore all arguments entered _before_ init=... [MJ]			 */			args = 0;			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 *);#ifndef __SMP__/* *	Uniprocessor idle thread */ int cpu_idle(void *unused){	for(;;)		idle();}#define smp_init()	do { } while (0)#else/* *	Multiprocessor idle thread is in arch/... */ extern int cpu_idle(void * unused);/* Called by boot processor to activate the rest. */static void __init smp_init(void){	/* Get other processors into their bootup holding patterns. */	smp_boot_cpus();	smp_threads_ready=1;	smp_commence();}		#endifextern void initialize_secondary(void);/* *	Activate the first processor. */ asmlinkage void __init start_kernel(void){	char * command_line;#ifdef __SMP__	static int boot_cpu = 1;	/* "current" has been set up, we need to load it now */	if (!boot_cpu)		initialize_secondary();	boot_cpu = 0;#endif/* * Interrupts are still disabled. Do necessary setups, then * enable them */	printk(linux_banner);	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);	/*	 * HACK ALERT! This is early. We're enabling the console before	 * we've done PCI setups etc, and console_init() must be aware of	 * this. But we do want output early, in case something goes wrong.	 */	memory_start = console_init(memory_start,memory_end);#ifdef CONFIG_MODULES	init_modules();#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 = kmem_cache_init(memory_start, memory_end);	sti(); 	calibrate_delay(); #ifdef CONFIG_BLK_DEV_INITRD	if (initrd_start && !initrd_below_start_ok && 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);	kmem_cache_sizes_init();#ifdef CONFIG_PROC_FS	proc_root_init();#endif	uidcache_init();	filescache_init();	dcache_init();	vma_init();	buffer_init();	signals_init();	inode_init();	file_table_init();#if defined(CONFIG_SYSVIPC)	ipc_init();#endif#if defined(CONFIG_QUOTA)	dquot_init_hash();#endif	check_bugs();	printk("POSIX conformance testing by UNIFIX\n");	/* 	 *	We count on the initial thread going ok 	 *	Like idlers init is an unlocked kernel thread, which will	 *	make syscalls (and thus be locked).	 */	smp_init();	kernel_thread(init, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);	current->need_resched = 1; 	cpu_idle(NULL);}#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/console",O_RDWR,0);	(void) dup(0);	(void) dup(0);	return execve(shell, argv, envp_init);}static void __init no_initrd(char *s,int *ints){	mount_initrd = 0;}#endifstruct task_struct *child_reaper = &init_task;/* * Ok, the machine is now initialized. None of the devices * have been touched yet, but the CPU subsystem is up and * running, and memory and process management works. * * Now we can finally start doing some real work.. */static void __init do_basic_setup(void){#ifdef CONFIG_BLK_DEV_INITRD	int real_root_mountflags;#endif	/*	 * Tell the world that we're going to be the grim	 * reaper of innocent orphaned children.	 *	 * We don't want people to have to make incorrect	 * assumptions about where in the task array this	 * can be found.	 */	child_reaper = current;#if defined(CONFIG_MTRR)	/* Do this after SMP initialization *//* * We should probably create some architecture-dependent "fixup after * everything is up" style function where this would belong better * than in init/main.c.. */	mtrr_init();#endif#ifdef CONFIG_SYSCTL	sysctl_init();#endif	/*	 * Ok, at this point all CPU's should be initialized, so	 * we can start looking into devices..	 */#ifdef CONFIG_PCI	pci_init();#endif#ifdef CONFIG_USB    usb_init();#endif#ifdef CONFIG_SBUS	sbus_init();#endif#if defined(CONFIG_PPC)	powermac_init();#endif#ifdef CONFIG_MCA	mca_init();#endif#ifdef CONFIG_ARCH_ACORN	ecard_init();#endif#ifdef CONFIG_ZORRO	zorro_init();#endif#ifdef CONFIG_DIO	dio_init();#endif	/* Networking initialization needs a process context */ 	sock_init();	/* Launch bdflush from here, instead of the old syscall way. */	kernel_thread(bdflush, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);	/* Start the background pageout daemon. */	kswapd_setup();	kernel_thread(kpiod, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);	kernel_thread(kswapd, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);#if CONFIG_AP1000	/* Start the async paging daemon. */	{	  extern int asyncd(void *);	 	  kernel_thread(asyncd, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);	}#endif#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	/* Set up devices .. */	device_setup();	/* .. executable formats .. */	binfmt_setup();	/* .. filesystems .. */	filesystem_setup();	/* Mount the root filesystem.. */	mount_root();#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->i_sb->s_root;			current->fs->pwd  = pseudo_root->i_sb->s_root;		}	}#endif#ifdef CONFIG_BLK_DEV_INITRD	root_mountflags = real_root_mountflags;	if (mount_initrd && ROOT_DEV != real_root_dev	    && MAJOR(ROOT_DEV) == RAMDISK_MAJOR && MINOR(ROOT_DEV) == 0) {		int error;		int i, pid;		pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);		if (pid>0)			while (pid != wait(&i));		if (MAJOR(real_root_dev) != RAMDISK_MAJOR		     || MINOR(real_root_dev) != 0) {			error = change_root(real_root_dev,"/initrd");			if (error)				printk(KERN_ERR "Change root to /initrd: "				    "error %d\n",error);		}	}#endif}static int init(void * unused){	lock_kernel();	do_basic_setup();	/*	 * Ok, we have completed the initial bootup, and	 * we're essentially up and running. Get rid of the	 * initmem segments and start the user-mode stuff..	 *//* 	free_initmem();  */	unlock_kernel();	if (open("/dev/console", O_RDWR, 0) < 0)		printk("Warning: unable to open an initial console.\n");	(void) dup(0);	(void) dup(0);		/*	 * We try each of these until one succeeds.	 *	 * The Bourne shell can be used instead of init if we are 	 * trying to recover a really broken machine.	 */	if (execute_command)		execve(execute_command,argv_init,envp_init);	execve("/sbin/init",argv_init,envp_init);	execve("/etc/init",argv_init,envp_init);	execve("/bin/init",argv_init,envp_init);	execve("/bin/sh",argv_init,envp_init);	panic("No init found.  Try passing init= option to kernel.");}@

⌨️ 快捷键说明

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