intrusive_ref_ptr<DevFs> //return value is a pointer to DevFs
#else //WITH_DEVFS
void                     //return value is void
#endif //WITH_DEVFS
basicFilesystemSetup(intrusive_ref_ptr<Device> dev)
{
    bootlog("Mounting MountpointFs as / ... ");
    FilesystemManager& fsm=FilesystemManager::instance();
    intrusive_ref_ptr<FilesystemBase> rootFs(new MountpointFs);
    bootlog(fsm.kmount("/",rootFs)==0 ? "Ok\n" : "Failed\n");
    
    #ifdef WITH_DEVFS
    bootlog("Mounting DevFs as /dev ... ");
    StringPart sp("dev");
    int r1=rootFs->mkdir(sp,0755); 
    intrusive_ref_ptr<DevFs> devfs(new DevFs);
    int r2=fsm.kmount("/dev",devfs);
    bool devFsOk=(r1==0 && r2==0);
    bootlog(devFsOk ? "Ok\n" : "Failed\n");
    if(!devFsOk) return devfs;
    fsm.setDevFs(devfs);
    #endif //WITH_DEVFS
    
    bootlog("Mounting Fat32Fs as /sd ... ");
    bool fat32failed=false;
    intrusive_ref_ptr<FileBase> disk;
    #ifdef WITH_DEVFS
    if(dev) devfs->addDevice("sda",dev);
    StringPart sda("sda");
    if(devfs->open(disk,sda,O_RDWR,0)<0) fat32failed=true;
    #else //WITH_DEVFS
    if(dev && dev->open(disk,intrusive_ref_ptr<FilesystemBase>(0),O_RDWR,0)<0)
        fat32failed=true;
    #endif //WITH_DEVFS
    
    intrusive_ref_ptr<Fat32Fs> fat32;
    if(fat32failed==false)
    {
        fat32=new Fat32Fs(disk);
        if(fat32->mountFailed()) fat32failed=true;
    }
    if(fat32failed==false)
    {
        StringPart sd("sd");
        fat32failed=rootFs->mkdir(sd,0755)!=0;
        fat32failed=fsm.kmount("/sd",fat32)!=0;
    }
    bootlog(fat32failed==0 ? "Ok\n" : "Failed\n");
    
    #ifdef WITH_DEVFS
    return devfs;
    #endif //WITH_DEVFS
}
Beispiel #2
0
void
boot(int drive)
{
	int 		addr;
	int 		top;
	int 		kern_entry;
	int 		boot_start;
	int 		boot_region_desc;
	int 		boot_thread_state;
	unsigned 	int size;
	int 		env_start;
	int 		env_size = 0;
	char 		*p;
	char 		*env = 0;
	char		*defaults = 0;
	int		defaults_size = 0;
	int 		i;
	int		idt[2];

	delayprompt = 10;	/* default to 10s at the prompt */

	switch(drive) {
	    case BIOS_DEV_FLOPPY:
		dev = DEV_FLOPPY;
		break;
	    case BIOS_FAKE_WD:
		dev = DEV_WD;
		break;
	    case BIOS_DEV_WIN:
	    default:
		dev = DEV_HD;
		break;
	}
	cnvmem = memsize(0);
	extmem = memsize(1);

	printf("\n>> Secondary Mach boot %s\n>> %d/%dk (? for help, ^C for intr)\n",
	       VERSIONDATE, cnvmem, extmem);
#ifdef	DEBUG
	printf("end x%x data 0x%x\n",end,edata);
#endif
	/* sanity check: */
	if ((int)end > KALLOC_OFFSET || (int)end > (BOOTSTACK-0x300)) {
		printf("Size problem: 0x%x > 0x%x\n",end,
		       ((int)end > KALLOC_OFFSET)?KALLOC_OFFSET:BOOTSTACK-0x300);
	}

#if	DEBUG
	if (debug) {
		printf("dev = %x\n", dev);
		printf("unit = %x\n", unit);
		printf("part = %x\n", part);
	}
#endif
#if 0
	dev = DEV_HD;
	unit = 0;
	part = 0;
#endif

	reset_pic(); 		/* Lilo breaks PIC, BIOS disk ints fail */

	calibrate_delay();	/* adjust delay for i/o operation */

	gateA20();
	if (dev == DEV_FLOPPY && devfs()) {
		printf("No fd FS, using hd\n");
		dev = DEV_HD;
		part = 0;
	}


	bcopy(MACH_KERNEL, kern_prog.name, sizeof(MACH_KERNEL));
	bcopy(BOOTSTRAP, boot_prog.name, sizeof(BOOTSTRAP));
	bcopy(MACH_BOOT_ENV, env_prog.name, sizeof(MACH_BOOT_ENV));

reload_env_file:
	if (openrd(env_prog.name, NULL) == 0 && fsize() != 0) {
		const char 	*value;
		/*
		 * Read mach_boot environment file if exists
		 */
		printf("Reading defaults from %s:\n",env_prog.name);
		defaults_size = fsize()+1;
		if (defaults != (char *)0)
			free(defaults);
		defaults = (char *)malloc(defaults_size);
		read(defaults, defaults_size-1);
		*(defaults+defaults_size-1) = 0;
		printf("%s", defaults);
		for (p = defaults; p < defaults + defaults_size; p++)
			if (*p == '\n')
				*p = '\0';
		value = get_env("CONSOLE", defaults, defaults_size);
		if (strcmp(value, "vga") == 0 || strcmp(value, "VGA") == 0)
			com_enabled = 0;
		/* WARNING: do not enable the remote console based
		 * on the latter argument in an environment file, since
		 * now, remote console enabling is decided by the primary
		 * boot ONLY and passed along through secondary's.
		 */
		if (*get_env("PROMPT", defaults, defaults_size) == '1')
			prompt = 1;
		if (com_enabled &&
		    (value = get_env("COM1_SETUP", defaults, defaults_size)))
			com_setup(value);
		if (value = get_env("DELAYPROMPT", defaults, defaults_size)) {
			delayprompt = atoi(value);
			/* don't allow stupid values */
			if (delayprompt < 3)
				delayprompt = 3;			
		}
	}
	for (;;) {
	    	if ((!getbootline(kern_prog.name, boot_prog.name)) && defaults ) {
		  	/*
			 * Get defaults from /mach_boot.env if any.
			 */
			const char 	*value;

			if (value = get_env("KERNEL_NAME",
					    defaults, defaults_size)) {
				strcpy(kern_prog.name, (char *)value);
				strcpy(kern_prog.args, (char *)value);
				kern_prog.args_size = strlen(value)+1;
			}
			if (value = get_env("KERNEL_ARGS",
					    defaults, defaults_size)) {
			  	char *args;
				args = kern_prog.args + kern_prog.args_size;
				while (*value)
					value = copyargs((char *)value, &args);
				kern_prog.args_size = args - kern_prog.args;
			}
			if (value = get_env("BOOTSTRAP_NAME",
					    defaults, defaults_size)) {
				strcpy(boot_prog.name, (char *)value);
				strcpy(boot_prog.args, (char *)value);
				boot_prog.args_size = strlen(value)+1;
			}
			if (value = get_env("BOOTSTRAP_ARGS",
					    defaults, defaults_size)) {
			  	char *args;
				args = boot_prog.args + boot_prog.args_size;
				while (*value)
					value = copyargs((char *)value, &args);
				boot_prog.args_size = args - boot_prog.args;
			}
	        }
		if (cons_is_com) {
			printf("console is COM1\n");
			/* check if we already enabled remote console? */
			p = kern_prog.args + kern_prog.args_size;
			*p++ = '-';
			*p++ = 'r';
			*p++ = 0;
			kern_prog.args_size += 3;
	        }

		addr = KERNEL_BOOT_ADDR;
		if (loadtext(&addr, &kern_prog)) {
			strcpy(env_prog.name, kern_prog.name);
			goto reload_env_file;
		} else if (loadprog(&addr, &kern_prog)) {
			printf("Can't load %s\n", kern_prog.name);
			usage();
			continue;
		}
		kern_entry = entry;

		if (dev == DEV_WD)
			net_get_root_device();
		env_start = addr;
		if (openrd("/mach_servers/environment", NULL) == 0 &&
		    fsize() != 0) {
			unsigned int total = fsize()+1;

			printf("Loading environment from /mach_servers/environment\n");
			env = (char *)malloc(total);
			read(env, total-1);
			*(env+total-1) = 0;
			for (p = env; p < env + total; p++)
				if (*p == '\n')
					*p = '\0';
			pcpy(env, (void *)addr, total);
			addr += total;
			env_size += total;
			free(env);
		} 
		env = (char *)malloc(BOOT_LINE_LENGTH);
#if	BOOT_ENV_COMPAT
		/* should go away when all kernels are converted 
		   to use BOOT_DEVICE */
		p = env;
		strcpy(p, "BOOTOFFSET=");
		p = itoa(p + strlen(p), boff) + 1;
		strcpy(p, "BOOTDEV=hd");
		p += strlen(p)+1;
		*(p-3) = dev;
		strcpy(p, "BOOTUNIT=");
		p = itoa(p + strlen(p), unit) + 1;
		strcpy(p, "BOOTPART=");
		p = itoa(p + strlen(p), part) + 1;
		size = p - env;
		pcpy(env, (void *)addr, size);
		addr += size;
		env_size += size;
#endif	/* BOOT_ENV_COMPAT */

		p = env;
		strcpy(p, "BOOT_DEVICE=hd");
		p += strlen(p);
		*(p-2) = dev;
		p = itoa(p, unit);
		*p++ = 'a'+part;

		size = p - env;
		pcpy(env, (void *)addr, size);
		addr += size;
		env_size += size;
		free(env);

		if (strncmp("none",boot_prog.name,sizeof("none"))==0
		    ||strncmp("null",boot_prog.name,sizeof("null"))==0) {
			boot_start = 0;
			boot_region_desc = 0;
			boot_prog.sym_start = 0;
			boot_prog.sym_size = 0;
			boot_prog.args_start = 0;
			boot_prog.args_size = 0;
			region_count = 0;
			boot_thread_state = 0;
		        top = page_align(addr);
			goto boot_kernel_only;
		}
		boot_start = addr = page_align(addr);
		if (loadprog(&addr, &boot_prog)) {
			printf("Can't load %s\n", boot_prog.name);
			usage();
			continue;
		}

		boot_region_desc = addr;
		addr = boot_region_desc + (region_count * sizeof(regions[0]));
		pcpy(regions, (void *) boot_region_desc,
		     addr - boot_region_desc);
		boot_thread_state = addr;
		addr += sizeof(thread_state);
		pcpy(&thread_state, (void *) boot_thread_state,
		     addr - boot_thread_state);

		top = page_align(addr);
boot_kernel_only:
#ifdef DEBUG
		if (debug) {
			printf("startprog(\n");
			printf("    entry 0x%x,\n", kern_entry);
			printf("    -1,\n");
			printf("    extmem 0x%x,\n", extmem);
			printf("    cnvmem 0x%x,\n", cnvmem);
			printf("    kern_sym_start 0x%x,\n",
			       kern_prog.sym_start);
			printf("    kern_sym_size 0x%x,\n",
			       kern_prog.sym_size);
			printf("    kern_args_start 0x%x,\n",
			       kern_prog.args_start);
			printf("    kern_args_size 0x%x,\n",
			       kern_prog.args_size);
			for (p = kern_prog.args;
			     p < &kern_prog.args[kern_prog.args_size];
			     p += strlen(p)+1)
				printf("<%s>", p);
			printf("\n");
			printf("    boot_sym_start 0x%x,\n",
			       boot_prog.sym_start);
			printf("    boot_sym_size 0x%x,\n",
			       boot_prog.sym_size);
			printf("    boot_args_start 0x%x,\n",
			       boot_prog.args_start);
			printf("    boot_args_size 0x%x,\n",
			       boot_prog.args_size);
			for (p = boot_prog.args;
			     p < &boot_prog.args[boot_prog.args_size];
			     p += strlen(p)+1)
				printf("<%s>", p);
			printf("\n");
			printf("    boot_start 0x%x,\n", boot_start);
			printf("    boot_size 0x%x,\n",
			       boot_prog.sym_start - boot_start);
			printf("    boot_region_desc 0x%x,\n",
			       boot_region_desc);
			printf("    boot_region_count 0x%x,\n", region_count);
			printf("    boot_thread_state_flavor %d,\n",
			       THREAD_SYSCALL_STATE);
			printf("    boot_thread_state 0x%x (eip 0x%x, esp 0x%x),\n",
			       boot_thread_state,
			       thread_state.eip, thread_state.esp);
			printf("    boot_thread_state_count %d,\n",
			       (int) i386_THREAD_SYSCALL_STATE_COUNT);
			printf("    env_start 0x%x,\n", env_start);
			printf("    env_size 0x%x,\n", env_size);
			printf("    top 0x%x)\n", (int) top);
getchar();
			continue;
		}
#endif /* DEBUG */

/*
 * New calling convention
 *
 * %esp ->	-1
 *		size of extended memory (K)
 *		size of conventional memory (K)
 *		kern_sym_start
 *		kern_sym_size
 *		kern_args_start
 *		kern_args_size
 *		boot_sym_start
 *		boot_sym_size
 *		boot_args_start
 *		boot_args_size
 *		boot_start
 *		boot_size
 *		boot_region_desc
 *		boot_region_count
 *		boot_thread_state_flavor
 *		boot_thread_state
 *		boot_thread_state_count
 *		env_start
 *		env_size
 *		top of loaded memory
 */
		startprog(
			  kern_entry,
			  -1,
			  extmem, cnvmem,
			  kern_prog.sym_start, kern_prog.sym_size,
			  kern_prog.args_start, kern_prog.args_size,
			  boot_prog.sym_start, boot_prog.sym_size,
			  boot_prog.args_start, boot_prog.args_size,
			  boot_start, boot_prog.sym_start - boot_start,
			  boot_region_desc, region_count,
			  THREAD_SYSCALL_STATE, boot_thread_state,
			  i386_THREAD_SYSCALL_STATE_COUNT,
			  env_start, env_size,
			  top);
	}
}