Esempio n. 1
0
void init_kspace(int membottom)
{
	uint32 *raw;
	
    /* there's an existing aspace at vaddr 0x803FD000 that was initialized
       by the 2nd stage loader */
	raw = (uint32 *) 0x803FD000;
    flat = &_flat;
	flat->pdir = raw;
	flat->ptab = &raw[1024];
	flat->high = &raw[2048];
	memtotal = memsize;
	
    memsize -= 3; /* three pages already in use */
    
    memory_init(membottom, memsize);

	
    toppage = (char *) kgetpages(3); /* kernel startup stack */
    gdt = (char *) kgetpages(1);
    rsrc_init(kgetpages(6),4096*6);
    

	kernel = (task_t *) kmalloc(task_t);
	ktss = (TSS *) kgetpages(1);
    kernel->flags = tKERNEL;
	kernel->rsrc.id = 0;
	kernel->rsrc.owner = NULL;
	list_init(&kernel->rsrc.rights);
	list_init(&kernel->rsrc.queue);
    current = kernel;

    init_idt(idt = kgetpages(1));              /* init the new idt, save the old */
    gdt2 = (void *) i386sgdt(&gdt2len);        /* save the old gdt */

    i386SetSegment(gdt + SEL_KCODE,      /* #01 - 32bit DPL0 CODE */
                   0, 0xFFFFF,
                   i386rPRESENT | i386rDPL0 | i386rCODE,
                   i386g4K | i386g32BIT);

    i386SetSegment(gdt + SEL_KDATA,      /* #02 - 32bit DPL0 DATA */
                   0, 0xFFFFF,
                   i386rPRESENT | i386rDPL0 | i386rDATA,
                   i386g4K | i386g32BIT);

    i386SetSegment(gdt + SEL_KDATA2,        /* #02 - 32bit DPL0 DATA */
                   0, 0xFFFFF,
                   i386rPRESENT | i386rDPL0 | i386rDATA,
                   i386g4K | i386g32BIT);

    i386SetSegment(gdt + SEL_UCODE,        /* #03 - 32bit DPL3 CODE */
                   0, 0xFFFFF,
                   i386rPRESENT | i386rDPL3 | i386rCODE,
                   i386g4K | i386g32BIT);

    i386SetSegment(gdt + SEL_UDATA,        /* #04 - 32bit DPL3 DATA */
                   0, 0xFFFFF,
                   i386rPRESENT | i386rDPL3 | i386rDATA,
                   i386g4K | i386g32BIT);

    i386SetSegment(gdt + SEL_KTSS,        /* #05 - DPL0 TSS (Kernel) */
                   (uint32) ktss, 104,
                   i386rPRESENT | i386rDPL0 | i386rTSS,
                   0);
    
    i386lgdt((uint32) gdt, 1024/8);

    asm("mov %%cr3, %0":"=r" (_cr3));
    
        /* setup the kernel TSS to insure that it's happy */
    ktss->cs = SEL_KCODE;
    ktss->ds = ktss->es = ktss->ss = ktss->fs = ktss->gs = SEL_KDATA; 
    ktss->ldts = ktss->debugtrap = ktss->iomapbase = 0;
    ktss->cr3 = _cr3;
	ktss->ss0 = SEL_KDATA;
    ktss->esp1 = ktss->esp2 = ktss->ss1 = ktss->ss2 = 0;
    i386ltr(SEL_KTSS);
}
Esempio n. 2
0
/*
 * VERY simple elf loader.
 *
 * Make stupid assumptions like linear allocation of segments, in order
 */
void elf_load(void *base, size_t size) {
	elf_file_header_t *f;
	elf_program_header_t *ph;
	void *alloc_to = (void *)0;
	int i;

	f = base;
	if (f->magic != ELF_MAGIC) { kprint("Bad ELF magic found"); return; }
	if (f->type != ELF_TYPE_EXEC && f->type != ELF_TYPE_DYN_EXEC) { 
		kprintf("Unknown ELF executable type (%x)\n", f->type); 
		return;
	}

	for (i=0; i<(f->ph_entry_count); i++) {
		ph = base + f->program_head_offset + (f->ph_entry_size * i);

		if (ph->segment_type == ELF_PROG_SEG_LOAD) {
			int pages_needed = ((ph->mem_size) / PAGE_SIZE) + 1;
			void * pages[pages_needed];
			void *abase = ph->virtual_addr;
			int i;

			/* Show what we are loading if debugging */
			if (ph->flags & ELF_PS_READ) kprint("R");
			if (ph->flags & ELF_PS_WRITE) kprint("W");
			if (ph->flags & ELF_PS_EXEC) kprint("X");
			kprintf("elf:\t0x%x(0x%x), mem 0x%x, dsk 0x%x, aln 0x%x\n",
				ph->phys_addr, ph->virtual_addr, ph->mem_size, 
				ph->file_size, ph->alignment);

			/* Don't double allocate pages, no matter how 
			 * stupid and broken the ELF header is */
			while (abase < alloc_to) {
				pages_needed--;
				abase += PAGE_SIZE;
			}
			alloc_to = abase + (PAGE_SIZE * pages_needed) - 1;
			kgetpages(pages_needed, pages);
			for (i = 0; i < pages_needed; i++) {
		                paging_add_to_dir(kernel_page_dir, abase, pages[i]);
	       		        abase += PAGE_SIZE;
		        }


			kmemcpy(ph->virtual_addr, base+(ph->offset), 
					ph->file_size);

			if (ph->file_size < ph->mem_size) {
				kmemset((ph->virtual_addr)+(ph->file_size),
					0, (ph->mem_size - ph->file_size));
			}
		}
	}
	
	#if 0
	/* 2008-07-15: THIS IS BAD!
	 * tempstack should NOT be used by things outside of inth.S or mem.S!
	 * even that is going to be phased out...
	 *
	 * new_kthread is a much more sane way to be doing this even to bootstrap
	 * usermode...
	 */

	/* Splinter, but give the tempstack, so we have to yield to make
	 * sure that it is freed again before we are called again in this
	 * thread */
	splinter(f->entry, tempstack+PAGE_SIZE);
	yield();
	#endif
	new_kthread(f->entry);
}