Exemplo n.º 1
0
Arquivo: main.c Projeto: nielh/dragon
void kmain(s64 magic, s64 info)
{
	//vga_clear(COLOR_BLACK);
    idt_init();
    isr_init();

    serial_init();
	set_debug_traps();
    BREAKPOINT();

	cpuid_print();
	multiboot(magic, info);
	kmem_map();
    page_init();
    kmalloc_init();
    //vesa_init();

    root_init();
    pci_init();
    vm_init();
    syscall_init();
    timer_init();
    kbd_init();
    //mouse_init();

    console_init();

 	create_kthread(NULL, idle_thread, THREAD_PRI_LOW, NULL, NULL);
 	create_kthread(NULL, init_thread, THREAD_PRI_NORMAL, NULL, NULL);

    thread_schedule();
}
Exemplo n.º 2
0
// When we enter, we're actually 1 MB high.
// Fortunately, memcpy is position independent, and it's all we need
uint32_t hi_multiboot(int multiboot_magic, struct multiboot_info *mi_orig)
{
    // Copy the multiboot info out of the way.
    // We can't bitch about the magic yet because printf won't work
    // because it contains an absolute location of putchar which
    // contains absolute locations to other things which eventually
    // makes a BIOS call from real mode which of course won't work
    // because we're stuck in extended memory at this point.
    struct multiboot_info *mi_p = copyMultibootInfo(multiboot_magic, mi_orig);

    // Get us in to low memory so we can run everything

    // We cannot possibly be more than 383.5k and copying extra won't really hurt anything
    // We use the address of the assembly entrypoint to get our starting location.
    memcpy(&boot2_sym, (char*)&boot2_sym + OFFSET_1MEG, 0x5fe00 /* 383.5k */);

    // This is a little assembler routine that returns to us in the correct selector
    // instead of the kernel selector we're running in now and at the correct
    // instruction pointer ( current minus 1 MB ).  It does not fix our return
    // address nor does it fix the return address of our caller.
    continue_at_low_address();

    // Now fix our return address.
    FIX_RETURN_ADDRESS_USING_FIRST_ARG(multiboot_magic);

    // We can now do just about anything, including return to our caller correctly.
    // However, our caller must fix his return address if he wishes to return to
    // his caller and so on and so forth.

    /*  Zero the BSS and initialize malloc */
    initialize_runtime();

    gMI = mi_p;

    /*  Set up a temporary bootArgs so we can call console output routines
        like printf that check the v_display.  Note that we purposefully
        do not initialize anything else at this early stage.

        We are reasonably sure we're already in text mode if GRUB booted us.
        This is the same assumption that initKernBootStruct makes.
        We could check the multiboot info I guess, but why bother?
     */
    boot_args temporaryBootArgsData;
    bzero(&temporaryBootArgsData, sizeof(boot_args));
    bootArgs = &temporaryBootArgsData;
    bootArgs->Video.v_display = VGA_TEXT_MODE;

    // Install ramdisk and extra driver hooks
    p_get_ramdisk_info = &multiboot_get_ramdisk_info;
    p_ramdiskReadBytes = &multibootRamdiskReadBytes;
    LoadExtraDrivers_p = &multiboot_LoadExtraDrivers;

    // Since we call multiboot ourselves, its return address will be correct.
    // That is unless it's inlined in which case it does not matter.
    uint32_t bootdevice = multiboot(multiboot_magic, mi_p);
    // We're about to exit and temporaryBootArgs will no longer be valid
    bootArgs = NULL;
    return bootdevice;
}
Exemplo n.º 3
0
void
x86_boot(struct multiboot_info *mbi)
{

	cons_init();
	bmk_printf("rump kernel bare metal bootstrap\n\n");

	cpu_init();
	bmk_sched_init();
	multiboot(mbi);

	spl0();

	bmk_sched_startmain(bmk_mainthread, multiboot_cmdline);
}
Exemplo n.º 4
0
Arquivo: main.c Projeto: 99years/plan9
void
main(u32int ax, u32int bx)
{
	vlong hz;

	memset(edata, 0, end - edata);

	/*
	 * ilock via i8250enable via i8250console
	 * needs m->machno, sys->machptr[] set, and
	 * also 'up' set to nil.
	 */
	cgapost(sizeof(uintptr)*8);
	memset(m, 0, sizeof(Mach));
	m->machno = 0;
	m->online = 1;
	m->nixtype = NIXTC;
	sys->machptr[m->machno] = &sys->mach;
	m->stack = PTR2UINT(sys->machstk);
	m->vsvm = sys->vsvmpage;
	up = nil;
	active.nonline = 1;
	active.exiting = 0;
	active.nbooting = 0;
	asminit();
	multiboot(ax, bx, 0);
	options(oargc, oargv);
	crapoptions();

	/*
	 * Need something for initial delays
	 * until a timebase is worked out.
	 */
	m->cpuhz = 2000000000ll;
	m->cpumhz = 2000;

	cgainit();
	i8250console("0");
	consputs = cgaconsputs;

	vsvminit(MACHSTKSZ, NIXTC);

	conf.nmach = 1;			

	fmtinit();
	print("\nNIX\n");
	if(vflag){
		print("&ax = %#p, ax = %#ux, bx = %#ux\n", &ax, ax, bx);
		multiboot(ax, bx, vflag);
	}

	m->perf.period = 1;
	if((hz = archhz()) != 0ll){
		m->cpuhz = hz;
		m->cyclefreq = hz;
		m->cpumhz = hz/1000000ll;
	}

	/*
	 * Mmuinit before meminit because it
	 * flushes the TLB via m->pml4->pa.
	 */
	mmuinit();

	ioinit();
	kbdinit();
	meminit();
	confinit();
	archinit();
	mallocinit();

	/*
	 * Acpiinit will cause the first malloc
	 * call to happen.
	 * If the system dies here it's probably due
	 * to malloc not being initialised
	 * correctly, or the data segment is misaligned
	 * (it's amazing how far you can get with
	 * things like that completely broken).
	 */
	acpiinit();
	
	umeminit();
	trapinit();
	printinit();

	/*
	 * This is necessary with GRUB and QEMU.
	 * Without it an interrupt can occur at a weird vector,
	 * because the vector base is likely different, causing
	 * havoc. Do it before any APIC initialisation.
	 */
	i8259init(32);


	procinit0();
	mpsinit(maxcores);
	apiconline();
	sipi();

	timersinit();
	kbdenable();
	fpuinit();
	psinit(conf.nproc);
	initimage();
	links();
	devtabreset();
	pageinit();
	swapinit();
	userinit();
	nixsquids();
testiccs();	
print("schedinit...\n");
	schedinit();
}
Exemplo n.º 5
0
// When we enter, we're actually 1 MB high.
// Fortunately, memcpy is position independent, and it's all we need
uint32_t hi_multiboot(int multiboot_magic, struct multiboot_info *mi_orig)
{
    // Copy the multiboot info out of the way.
    // We can't bitch about the magic yet because printf won't work
    // because it contains an absolute location of putchar which
    // contains absolute locations to other things which eventually
    // makes a BIOS call from real mode which of course won't work
    // because we're stuck in extended memory at this point.
    struct multiboot_info *mi_p = copyMultibootInfo(multiboot_magic, mi_orig);

    // Get us in to low memory so we can run everything

    // We cannot possibly be more than 447k and copying extra won't really hurt anything
    // We use the address of the assembly entrypoint to get our starting location.
    memcpy(&boot2_sym, (char*)&boot2_sym + OFFSET_1MEG, BOOT2_MAX_LENGTH /* 447k */);

    // This is a little assembler routine that returns to us in the correct selector
    // instead of the kernel selector we're running in now and at the correct
    // instruction pointer ( current minus 1 MB ).  It does not fix our return
    // address nor does it fix the return address of our caller.
    continue_at_low_address();

    // Now fix our return address.
	// JrCs: this macro should be rewritten because the code generated by XCode 4.x
	//       change the value of the argument passed as parameter (multiboot_magic)
    // FIX_RETURN_ADDRESS_USING_FIRST_ARG(multiboot_magic);

    // We can now do just about anything, including return to our caller correctly.
    // However, our caller must fix his return address if he wishes to return to
    // his caller and so on and so forth.

    /*  Zero the BSS and initialize malloc */
    initialize_runtime();

    gMI = mi_p;

    /*  Set up a temporary bootArgs so we can call console output routines
        like printf that check the v_display.  Note that we purposefully
        do not initialize anything else at this early stage.

        We are reasonably sure we're already in text mode if GRUB booted us.
        This is the same assumption that initKernBootStruct makes.
        We could check the multiboot info I guess, but why bother?
     */
    boot_args temporaryBootArgsData;
    bzero(&temporaryBootArgsData, sizeof(boot_args));
    bootArgs = &temporaryBootArgsData;
    bootArgs->Video.v_display = VGA_TEXT_MODE;

    // Install ramdisk and extra driver hooks
    p_get_ramdisk_info = &multiboot_get_ramdisk_info;
    p_ramdiskReadBytes = &multibootRamdiskReadBytes;
    LoadExtraDrivers_p = &multiboot_LoadExtraDrivers;

    // Since we call multiboot ourselves, its return address will be correct.
    // That is unless it's inlined in which case it does not matter.
    uint32_t bootdevice = multiboot(multiboot_magic, mi_p);

    if(bootdevice != BAD_BOOT_DEVICE)
    {
        // boot only returns to do a chain load.
        for(;;)
        {   // NOTE: boot only uses the last byte (the drive number)
            boot(bootdevice);
            if(chainbootflag)
                chainLoad();
            else
                waitThenReload();
        }
    }

    // Avoid returning to high-memory address which isn't valid in the segment
    // we are now in.
    // Calling sleep() ensures the user ought to be able to use Ctrl+Alt+Del
    // because the BIOS will have interrupts on.
    for(;;)
        sleep(10);
    // NOTE: *IF* we needed to return we'd have to fix up our return address to
    // be in low memory using the same trick as below.
    // However, there doesn't seem to be any point in returning to assembly
    // particularly when the remaining code merely halts the processor.

    // We're about to exit and temporaryBootArgs will no longer be valid
    bootArgs = NULL;
    return bootdevice;
}
Exemplo n.º 6
0
int
exec_multiboot(const char *file, char *args)
{
	struct multiboot_info *mbi;
	struct multiboot_module *mbm;
	struct bi_modulelist_entry *bim;
	int		i, len;
	u_long		marks[MARK_MAX];
	u_long		extmem;
	u_long		basemem;
	char		*cmdline;

	mbi = alloc(sizeof(struct multiboot_info));
	mbi->mi_flags = MULTIBOOT_INFO_HAS_MEMORY;

	if (common_load_kernel(file, &basemem, &extmem, 0, 0, marks))
		goto out;

	mbi->mi_mem_upper = extmem;
	mbi->mi_mem_lower = basemem;

	if (args) {
		mbi->mi_flags |= MULTIBOOT_INFO_HAS_CMDLINE;
		len = strlen(file) + 1 + strlen(args) + 1;
		cmdline = alloc(len);
		snprintf(cmdline, len, "%s %s", file, args);
		mbi->mi_cmdline = (char *) vtophys(cmdline);
	}

	/* pull in any modules if necessary */
	if (boot_modules_enabled) {
		module_init(file);
		if (btinfo_modulelist) {
			mbm = alloc(sizeof(struct multiboot_module) *
					   btinfo_modulelist->num);

			bim = (struct bi_modulelist_entry *)
			  (((char *) btinfo_modulelist) +
			   sizeof(struct btinfo_modulelist));
			for (i = 0; i < btinfo_modulelist->num; i++) {
				mbm[i].mmo_start = bim->base;
				mbm[i].mmo_end = bim->base + bim->len;
				mbm[i].mmo_string = (char *)vtophys(bim->path);
				mbm[i].mmo_reserved = 0;
				bim++;
			}
			mbi->mi_flags |= MULTIBOOT_INFO_HAS_MODS;
			mbi->mi_mods_count = btinfo_modulelist->num;
			mbi->mi_mods_addr = vtophys(mbm);
		}
	}

#ifdef DEBUG
	printf("Start @ 0x%lx [%ld=0x%lx-0x%lx]...\n", marks[MARK_ENTRY],
	    marks[MARK_NSYM], marks[MARK_SYM], marks[MARK_END]);
#endif


#if 0
	if (btinfo_symtab.nsym) {
		mbi->mi_flags |= MULTIBOOT_INFO_HAS_ELF_SYMS;
		mbi->mi_elfshdr_addr = marks[MARK_SYM];
	btinfo_symtab.nsym = marks[MARK_NSYM];
	btinfo_symtab.ssym = marks[MARK_SYM];
	btinfo_symtab.esym = marks[MARK_END];
#endif

	multiboot(marks[MARK_ENTRY], vtophys(mbi),
		  x86_trunc_page(mbi->mi_mem_lower*1024));
	panic("exec returned");

out:
        dealloc(mbi, 0);
	return -1;
}

void
x86_progress(const char *fmt, ...)
{
	va_list ap;

	if ((howto & AB_SILENT) != 0)
		return;
	va_start(ap, fmt);
	vprintf(fmt, ap);
	va_end(ap);
}
Exemplo n.º 7
0
void
main(uint32_t mbmagic, uint32_t mbaddress)
{
	Mach *m = entrym;
	/* when we get here, entrym is set to core0 mach. */
	sys->machptr[m->machno] = m;
	// Very special case for BSP only. Too many things
	// assume this is set.
	wrmsr(GSbase, PTR2UINT(&sys->machptr[m->machno]));
	if (machp() != m)
		panic("m and machp() are different!!\n");
	assert(sizeof(Mach) <= PGSZ);

	/*
	 * Check that our data is on the right boundaries.
	 * This works because the immediate value is in code.
	 */
	if (x != 0x123456) 
		panic("Data is not set up correctly\n");
	memset(edata, 0, end - edata);

	m = (void *) (KZERO + 1048576 + 11*4096);
	sys = (void *) (KZERO + 1048576);

	/*
	 * ilock via i8250enable via i8250console
	 * needs m->machno, sys->machptr[] set, and
	 * also 'up' set to nil.
	 */
	cgapost(sizeof(uintptr_t)*8);
	memset(m, 0, sizeof(Mach));

	m->machno = 0;
	m->online = 1;
	m->nixtype = NIXTC;
	sys->machptr[m->machno] = &sys->mach;
	m->stack = PTR2UINT(sys->machstk);
	*(uintptr_t*)m->stack = STACKGUARD;
	m->vsvm = sys->vsvmpage;
	m->externup = (void *)0;
	active.nonline = 1;
	active.exiting = 0;
	active.nbooting = 0;

	asminit();
	multiboot(mbmagic, mbaddress, 0);
	options(oargc, oargv);

	/*
	 * Need something for initial delays
	 * until a timebase is worked out.
	 */
	m->cpuhz = 2000000000ll;
	m->cpumhz = 2000;

	cgainit();
	i8250console("0");
	
	consputs = cgaconsputs;

	/* It all ends here. */
	vsvminit(MACHSTKSZ, NIXTC, m);
	if (machp() != m)
		panic("After vsvminit, m and machp() are different");

	sys->nmach = 1;	
	
	fmtinit();
	print("\nHarvey\n");

	if(vflag){
		multiboot(mbmagic, mbaddress, vflag);
	}

	m->perf.period = 1;
	if((hz = archhz()) != 0ll){
		m->cpuhz = hz;
		m->cyclefreq = hz;
		m->cpumhz = hz/1000000ll;
	}
	//iprint("archhz returns 0x%lld\n", hz);
	//iprint("NOTE: if cpuidhz runs too fast, we get die early with a NULL pointer\n");
	//iprint("So, until that's fixed, we bring up AP cores slowly. Sorry!\n");

	/*
	 * Mmuinit before meminit because it
	 * flushes the TLB via m->pml4->pa.
	 */
	mmuinit();

	ioinit();
	meminit();
	confinit();
	archinit();
	mallocinit();

	/* test malloc. It's easier to find out it's broken here, 
	 * not deep in some call chain.
	 * See next note. 
	 *
	void *v = malloc(1234);
	hi("v "); put64((uint64_t)v); hi("\n");
	free(v);
	hi("free ok\n");
	 */

	/*
	 * Acpiinit will cause the first malloc
	 * call to happen.
	 * If the system dies here it's probably due
	 * to malloc not being initialised
	 * correctly, or the data segment is misaligned
	 * (it's amazing how far you can get with
	 * things like that completely broken).
	 */
if (0){	acpiinit(); hi("	acpiinit();\n");}
	
	umeminit();
	trapinit();

	/*
	 * This is necessary with GRUB and QEMU.
	 * Without it an interrupt can occur at a weird vector,
	 * because the vector base is likely different, causing
	 * havoc. Do it before any APIC initialisation.
	 */
	i8259init(32);


	procinit0();
	mpsinit(maxcores);
	apiconline();
	/* Forcing to single core if desired */
	if(!nosmp) {
		sipi();
	}
	teardownidmap(m);
	timersinit();
	fpuinit();
	psinit(conf.nproc);
	initimage();
	links();

	keybinit();
	keybenable();
	mouseenable();

	devtabreset();
	pageinit();
	swapinit();
	userinit();
	/* Forcing to single core if desired */
	if(!nosmp) {
		nixsquids();
		testiccs();
	}

	print("CPU Freq. %dMHz\n", m->cpumhz);

	print("schedinit...\n");
	schedinit();
}