void nulluser(void) { sysinit(); kprintf("\n\r%s\n\n\r", VERSION); /* Output Xinu memory layout */ kprintf("%10d bytes physical memory.\n", (uint32)maxheap - (uint32)0); kprintf(" [0x%08X to 0x%08X]\r\n", (uint32)0, (uint32)maxheap - 1); kprintf("%10d bytes of Xinu code.\n", (uint32)&etext - (uint32)0); kprintf(" [0x%08X to 0x%08X]\n", (uint32)0, (uint32)&etext - 1); kprintf("%10d bytes of data.\n", (uint32)&end - (uint32)&etext); kprintf(" [0x%08X to 0x%08X]\n", (uint32)&etext, (uint32)&end - 1); if ( (char *)minheap < HOLESTART) { kprintf("%10d bytes of heap space below 640K.\n", (uint32)HOLESTART - (uint32)roundmb(minheap)); } if ( (char *)maxheap > HOLEEND ) { kprintf("%10d bytes of heap space above 1M.\n", (uint32)maxheap - (uint32)HOLEEND); kprintf(" [0x%08X to 0x%08X]\n", (uint32)HOLEEND, (uint32)truncmb(maxheap) - 1); } /* Enable interrupts */ enable(); /* Start the network */ resume(create((void *)netin, NETSTK, NETPRIO, "netin", 0)); /* Create a process to execute function main() */ resume ( create((void *)main, INITSTK, INITPRIO, "Main process", 2, 0, NULL)); /* Become the Null process (i.e., guarantee that the CPU has */ /* something to run when no other process is ready to execute) */ while (TRUE) { ; /* do nothing */ } }
/** * Intializes all Xinu data structures and devices. * @return OK if everything is initialized successfully */ static int sysinit(void) { int i; struct thrent *thrptr; /* thread control block pointer */ struct memblock *pmblock; /* memory block pointer */ /* Initialize system variables */ /* Count this NULLTHREAD as the first thread in the system. */ thrcount = 1; /* Initialize free memory list */ memheap = roundmb(memheap); platform.maxaddr = truncmb(platform.maxaddr); memlist.next = pmblock = (struct memblock *)memheap; memlist.length = (uint)(platform.maxaddr - memheap); pmblock->next = NULL; pmblock->length = (uint)(platform.maxaddr - memheap); /* Initialize thread table */ for (i = 0; i < NTHREAD; i++) { thrtab[i].state = THRFREE; } /* initialize null thread entry */ thrptr = &thrtab[NULLTHREAD]; thrptr->state = THRCURR; thrptr->prio = 0; strlcpy(thrptr->name, "prnull", TNMLEN); thrptr->stkbase = (void *)&_end; thrptr->stklen = (ulong)memheap - (ulong)&_end; thrptr->stkptr = 0; thrptr->memlist.next = NULL; thrptr->memlist.length = 0; thrcurrent = NULLTHREAD; /* Initialize semaphores */ for (i = 0; i < NSEM; i++) { semtab[i].state = SFREE; semtab[i].queue = queinit(); } /* Initialize monitors */ for (i = 0; i < NMON; i++) { montab[i].state = MFREE; } /* Initialize buffer pools */ for (i = 0; i < NPOOL; i++) { bfptab[i].state = BFPFREE; } /* initialize thread ready list */ readylist = queinit(); #if SB_BUS backplaneInit(NULL); #endif /* SB_BUS */ #if RTCLOCK /* initialize real time clock */ clkinit(); #endif /* RTCLOCK */ #ifdef UHEAP_SIZE /* Initialize user memory manager */ { void *userheap; /* pointer to user memory heap */ userheap = stkget(UHEAP_SIZE); if (SYSERR != (int)userheap) { userheap = (void *)((uint)userheap - UHEAP_SIZE + sizeof(int)); memRegionInit(userheap, UHEAP_SIZE); /* initialize memory protection */ safeInit(); /* initialize kernel page mappings */ safeKmapInit(); } } #endif #if USE_TLB /* initialize TLB */ tlbInit(); /* register system call handler */ exceptionVector[EXC_SYS] = syscall_entry; #endif /* USE_TLB */ #if NMAILBOX /* intialize mailboxes */ mailboxInit(); #endif #if NDEVS for (i = 0; i < NDEVS; i++) { devtab[i].init((device*)&devtab[i]); } #endif #ifdef WITH_USB usbinit(); #endif #if NVRAM nvramInit(); #endif #if NNETIF netInit(); #endif #if GPIO gpioLEDOn(GPIO_LED_CISCOWHT); #endif return OK; }
/*------------------------------------------------------------------------ * sysinit -- initialize all Xinu data structeres and devices *------------------------------------------------------------------------ */ LOCAL sysinit() { int i,j,len; struct pentry *pptr; /* null process entry */ struct sentry *sptr; struct mblock *volatile mptr; numproc = 0; /* initialize system variables */ nextproc = NPROC-1; nextsem = NSEM-1; nextqueue = NPROC; /* q[0..NPROC-1] are processes */ memlist.mnext = mptr = /* initialize free memory list */ (struct mblock *volatile) roundmb(__malloc_heap_start); mptr->mnext = (struct mblock *)NULL; mptr->mlen = len = (int) truncmb(RAMEND - NULLSTK - (unsigned)&__bss_end); __malloc_heap_start = (char *)mptr; __malloc_heap_end = __malloc_heap_start + len; kprintf_P(PSTR("Heap: %p of length %d\n"), mptr, len); for (i=0 ; i<NPROC ; i++) /* initialize process table */ proctab[i].pstate = PRFREE; /* initialize null process entry */ pptr = &proctab[NULLPROC]; pptr->pstate = PRCURR; for (j=0; j<6; j++) pptr->pname[j] = "nullp"[j]; pptr->plimit = (unsigned char *)(RAMEND + 1) - NULLSTK; pptr->pbase = (unsigned char *) RAMEND; *pptr->pbase = (unsigned char)MAGIC; /* clobbers return, but proc 0 doesn't return */ pptr->paddr = (int *) main; pptr->pargs = 0; pptr->pprio = 0; pptr->pregs[SSP_L] = lobyte((unsigned int)pptr->plimit); /* for error checking */ pptr->pregs[SSP_H] = hibyte((unsigned int)pptr->plimit); /* for error checking */ currpid = NULLPROC; for (i=0 ; i<NSEM ; i++) { /* initialize semaphores */ (sptr = &semaph[i])->sstate = SFREE; sptr->sqtail = 1 + (sptr->sqhead = newqueue()); } rdytail = 1 + (rdyhead=newqueue()); /* initialize ready list */ #ifdef MEMMARK kprintf("Memory marking\n"); _mkinit(); /* initialize memory marking */ #else kprintf("Pool init\n"); poolinit(); /* explicitly */ pinit(MAXMSGS); #endif #ifdef RTCLOCK kprintf("init RTC\n"); clkinit(); /* initialize r.t.clock */ #endif #ifdef NDEVS for ( i=0 ; i<NDEVS ; i++ ) { if (i>0) kprintf("init dev %d\n", i); init(i); } #endif #ifdef NNETS // kprintf("net init\n"); netinit(); #endif return (OK); }
/*------------------------------------------------------------------------ * meminit - initialize memory bounds and the free memory list *------------------------------------------------------------------------ */ void meminit(void) { struct memblk *memptr; /* Ptr to memory block */ struct mbmregion *mmap_addr; /* Ptr to mmap entries */ struct mbmregion *mmap_addrend; /* Ptr to end of mmap region */ struct memblk *next_memptr; /* Ptr to next memory block */ uint32 next_block_length; /* Size of next memory block */ mmap_addr = (struct mbmregion*)NULL; mmap_addrend = (struct mbmregion*)NULL; /* Initialize the free list */ memptr = &memlist; memptr->mnext = (struct memblk *)NULL; memptr->mlength = 0; /* Initialize the memory counters */ /* Heap starts at the end of Xinu image */ minheap = (void*)&end; maxheap = minheap; /* Check if Xinu was loaded using the multiboot specification */ /* and a memory map was included */ if(bootsign != MULTIBOOT_SIGNATURE) { panic("could not find multiboot signature"); } if(!(bootinfo->flags & MULTIBOOT_BOOTINFO_MMAP)) { panic("no mmap found in boot info"); } /* Get base address of mmap region (passed by GRUB) */ mmap_addr = (struct mbmregion*)bootinfo->mmap_addr; /* Calculate address that follows the mmap block */ mmap_addrend = (struct mbmregion*)((uint8*)mmap_addr + bootinfo->mmap_length); /* Read mmap blocks and initialize the Xinu free memory list */ while(mmap_addr < mmap_addrend) { /* If block is not usable, skip to next block */ if(mmap_addr->type != MULTIBOOT_MMAP_TYPE_USABLE) { mmap_addr = (struct mbmregion*)((uint8*)mmap_addr + mmap_addr->size + 4); continue; } if((uint32)maxheap < ((uint32)mmap_addr->base_addr + (uint32)mmap_addr->length)) { maxheap = (void*)((uint32)mmap_addr->base_addr + (uint32)mmap_addr->length); } /* Ignore memory blocks within the Xinu image */ if((mmap_addr->base_addr + mmap_addr->length) < ((uint32)minheap)) { mmap_addr = (struct mbmregion*)((uint8*)mmap_addr + mmap_addr->size + 4); continue; } /* The block is usable, so add it to Xinu's memory list */ /* This block straddles the end of the Xinu image */ if((mmap_addr->base_addr <= (uint32)minheap) && ((mmap_addr->base_addr + mmap_addr->length) > (uint32)minheap)) { /* This is the first free block, base address is the minheap */ next_memptr = (struct memblk *)roundmb(minheap); /* Subtract Xinu image from length of block */ next_block_length = (uint32)truncmb(mmap_addr->base_addr + mmap_addr->length - (uint32)minheap); } else { /* Handle a free memory block other than the first one */ next_memptr = (struct memblk *)roundmb(mmap_addr->base_addr); /* Initialize the length of the block */ next_block_length = (uint32)truncmb(mmap_addr->length); } /* Add then new block to the free list */ memptr->mnext = next_memptr; memptr = memptr->mnext; memptr->mlength = next_block_length; memlist.mlength += next_block_length; /* Move to the next mmap block */ mmap_addr = (struct mbmregion*)((uint8*)mmap_addr + mmap_addr->size + 4); } /* End of all mmap blocks, and so end of Xinu free list */ if(memptr) { memptr->mnext = (struct memblk *)NULL; } }
/** * Intializes all Xinu data structures and devices. * @return OK if everything is initialized successfully */ static int sysinit(void) { int i; void *userheap; /* pointer to user memory heap */ struct thrent *thrptr; /* thread control block pointer */ device *devptr; /* device entry pointer */ struct sement *semptr; /* semaphore entry pointer */ struct memblock *pmblock; /* memory block pointer */ struct bfpentry *bfpptr; /* Initialize system variables */ /* Count this NULLTHREAD as the first thread in the system. */ thrcount = 1; kprintf("variable i in this function is at 0x%x\r\n", &i); kprintf("this function sysinit is at 0x%x\r\n", &sysinit); kprintf("_start is at 0x%x\r\n", _start); kprintf("_end is at (the end) at 0x%x\r\n", &_end); kprintf("readylist is at 0x%x\r\n", &readylist); kprintf("kputc is at 0x%x\r\n", &kputc); kprintf("NTHREAD is %d\r\n", NTHREAD); kprintf("memheap is 0x%x\r\n", memheap); /* Initialize free memory list */ memheap = roundmb(memheap); platform.maxaddr = truncmb(platform.maxaddr); kprintf("platform.maxaddr is 0x%x\r\n", platform.maxaddr); memlist.next = pmblock = (struct memblock *)memheap; memlist.length = (uint)(platform.maxaddr - memheap); pmblock->next = NULL; pmblock->length = (uint)(platform.maxaddr - memheap); /* Initialize thread table */ for (i = 0; i < NTHREAD; i++) { thrtab[i].state = THRFREE; } kprintf("thrtab is at 0x%x, size %d\r\n", thrtab, sizeof(thrtab)); /* initialize null thread entry */ thrptr = &thrtab[NULLTHREAD]; thrptr->state = THRCURR; thrptr->prio = 0; strncpy(thrptr->name, "prnull", 7); thrptr->stkbase = (void *)&_end; thrptr->stklen = (ulong)memheap - (ulong)&_end; thrptr->stkptr = 0; thrptr->memlist.next = NULL; thrptr->memlist.length = 0; thrcurrent = NULLTHREAD; kprintf("&_end is 0x%x\n", &_end); /* Initialize semaphores */ for (i = 0; i < NSEM; i++) { semptr = &semtab[i]; semptr->state = SFREE; semptr->count = 0; semptr->queue = queinit(); } kprintf("NPOOL is %d\n", NPOOL); /* Initialize buffer pools */ for (i = 0; i < NPOOL; i++) { bfpptr = &bfptab[i]; bfpptr->state = BFPFREE; } kprintf("calling queinit() for readylist\r\n"); /* initialize thread ready list */ readylist = queinit(); #if SB_BUS backplaneInit(NULL); #endif /* SB_BUS */ #if RTCLOCK /* initialize real time clock */ kprintf("Clock being initialized.\r\n" ); clkinit(); #endif /* RTCLOCK */ #ifdef UHEAP_SIZE /* Initialize user memory manager */ userheap = stkget(UHEAP_SIZE); if (SYSERR != (int)userheap) { userheap = (void *)((uint)userheap - UHEAP_SIZE + sizeof(int)); memRegionInit(userheap, UHEAP_SIZE); /* initialize memory protection */ safeInit(); /* initialize kernel page mappings */ safeKmapInit(); } #else userheap = NULL; #endif /* UHEAP_SIZE */ #if USE_TLB /* initialize TLB */ tlbInit(); /* register system call handler */ exceptionVector[EXC_SYS] = syscall_entry; #endif /* USE_TLB */ #if NMAILBOX /* intialize mailboxes */ mailboxInit(); #endif #if NDEVS for (i = 0; i < NDEVS; i++) { if (!isbaddev(i)) { devptr = (device *)&devtab[i]; (devptr->init) (devptr); } } #endif #if 0 #if NVRAM nvramInit(); #endif kprintf("SO MUCH MORE NOT done with sysinit()\r\n"); #if NNETIF netInit(); #endif kprintf("NOT done with sysinit()\r\n"); #if GPIO gpioLEDOn(GPIO_LED_CISCOWHT); #endif #endif kprintf("done with sysinit()\r\n"); return OK; }
static void sysinit(void) { int32 i; struct procent *prptr; /* ptr to process table entry */ struct dentry *devptr; /* ptr to device table entry */ struct sentry *semptr; /* prr to semaphore table entry */ struct memblk *memptr; /* ptr to memory block */ /* Initialize the interrupt vectors */ initevec(); /* Initialize system variables */ /* Count the Null process as the first process in the system */ prcount = 1; /* Scheduling is not currently blocked */ Defer.ndefers = 0; /* Initialize the free memory list */ /* Note: PC version has to pre-allocate 640K-1024K "hole" */ maxheap = (void *)MAXADDR; minheap = &end; memptr = memlist.mnext = (struct memblk *)roundmb(minheap); if ((char *)(maxheap+1) > HOLESTART) { /* create two blocks that straddle the hole */ memptr->mnext = (struct memblk *)HOLEEND; memptr->mlength = (int) truncmb((unsigned) HOLESTART - (unsigned)&end - 4); memptr = (struct memblk *) HOLEEND; memptr->mnext = (struct memblk *) NULL; memptr->mlength = (int) truncmb( (uint32)maxheap - (uint32)HOLEEND - NULLSTK); } else { /* initialize free memory list to one block */ memlist.mnext = memptr = (struct memblk *) roundmb(&end); memptr->mnext = (struct memblk *) NULL; memptr->mlength = (uint32) truncmb((uint32)maxheap - (uint32)&end - NULLSTK); } /* Initialize process table entries free */ for (i = 0; i < NPROC; i++) { prptr = &proctab[i]; prptr->prstate = PR_FREE; prptr->prname[0] = NULLCH; prptr->prstkbase = NULL; prptr->prprio = 0; } /* Initialize the Null process entry */ prptr = &proctab[NULLPROC]; prptr->prstate = PR_CURR; prptr->prprio = 0; strncpy(prptr->prname, "prnull", 7); prptr->prstkbase = getstk(NULLSTK); prptr->prstklen = NULLSTK; prptr->prstkptr = 0; currpid = NULLPROC; /* Initialize semaphores */ for (i = 0; i < NSEM; i++) { semptr = &semtab[i]; semptr->sstate = S_FREE; semptr->scount = 0; semptr->squeue = newqueue(); } /* Initialize buffer pools */ bufinit(); /* Create a ready list for processes */ readylist = newqueue(); /* Initialize the PCI bus */ pci_init(); /* Initialize the real time clock */ clkinit(); for (i = 0; i < NDEVS; i++) { if (! isbaddev(i)) { devptr = (struct dentry *) &devtab[i]; (devptr->dvinit) (devptr); } } return; }