123364Smckusick /* 237610Smckusick * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 339480Smckusick * All rights reserved. The Berkeley software License Agreement 439480Smckusick * specifies the terms and conditions for redistribution. 523364Smckusick * 6*45724Smckusick * @(#)init_main.c 7.30 (Berkeley) 12/05/90 723364Smckusick */ 826Sbill 917087Sbloom #include "param.h" 1017087Sbloom #include "systm.h" 1117087Sbloom #include "user.h" 1217087Sbloom #include "kernel.h" 1317087Sbloom #include "mount.h" 1417087Sbloom #include "map.h" 1517087Sbloom #include "proc.h" 1637610Smckusick #include "vnode.h" 1717087Sbloom #include "seg.h" 1817087Sbloom #include "conf.h" 1917087Sbloom #include "buf.h" 2017087Sbloom #include "clist.h" 2137611Smckusick #include "malloc.h" 2217087Sbloom #include "protosw.h" 2330570Skarels #include "reboot.h" 2437610Smckusick #include "../ufs/quota.h" 2526Sbill 2637522Smckusick #include "machine/reg.h" 2737522Smckusick #include "machine/cpu.h" 2837522Smckusick 29*45724Smckusick #include "../vm/vm_param.h" 30*45724Smckusick #include "../vm/vm_map.h" 31*45724Smckusick 3216807Skarels int cmask = CMASK; 33*45724Smckusick extern caddr_t proc0paddr; 3437610Smckusick extern int (*mountroot)(); 3526Sbill /* 3626Sbill * Initialization code. 3726Sbill * Called from cold start routine as 3826Sbill * soon as a stack and segmentation 3926Sbill * have been established. 4026Sbill * Functions: 4126Sbill * clear and free user core 4226Sbill * turn on clock 4326Sbill * hand craft 0th process 4426Sbill * call all initialization routines 4526Sbill * fork - process 0 to schedule 4621103Skarels * - process 1 execute bootstrap 4726Sbill * - process 2 to page out 4826Sbill */ 4926Sbill main(firstaddr) 508969Sroot int firstaddr; 5126Sbill { 52361Sbill register int i; 532451Swnj register struct proc *p; 5437611Smckusick register struct pgrp *pg; 559156Ssam int s; 5626Sbill 5726Sbill rqinit(); 58*45724Smckusick #if defined(hp300) && defined(DEBUG) 59*45724Smckusick /* 60*45724Smckusick * Assumes mapping is really on 61*45724Smckusick */ 62*45724Smckusick find_devs(); 63*45724Smckusick cninit(); 64*45724Smckusick #endif 65*45724Smckusick vm_mem_init(); 66*45724Smckusick kmeminit(); 6726Sbill startup(firstaddr); 6826Sbill 6926Sbill /* 7026Sbill * set up system process 0 (swapper) 7126Sbill */ 722451Swnj p = &proc[0]; 7340806Smarc bcopy("swapper", p->p_comm, sizeof ("swapper")); 742451Swnj p->p_stat = SRUN; 752451Swnj p->p_flag |= SLOAD|SSYS; 762451Swnj p->p_nice = NZERO; 77*45724Smckusick /* 78*45724Smckusick * Allocate a prototype map so we have something to fork 79*45724Smckusick */ 80*45724Smckusick p->p_map = vm_map_create(pmap_create(0), 81*45724Smckusick round_page(VM_MIN_ADDRESS), 82*45724Smckusick trunc_page(VM_MAX_ADDRESS), TRUE); 83*45724Smckusick p->p_addr = proc0paddr; 842451Swnj u.u_procp = p; 8537611Smckusick MALLOC(pgrphash[0], struct pgrp *, sizeof (struct pgrp), 8637611Smckusick M_PGRP, M_NOWAIT); 8737611Smckusick if ((pg = pgrphash[0]) == NULL) 8837611Smckusick panic("no space to craft zero'th process group"); 8937611Smckusick pg->pg_id = 0; 9037611Smckusick pg->pg_hforw = 0; 9137611Smckusick pg->pg_mem = p; 9237611Smckusick pg->pg_jobc = 0; 9337611Smckusick p->p_pgrp = pg; 9437611Smckusick p->p_pgrpnxt = 0; 9537611Smckusick MALLOC(pg->pg_session, struct session *, sizeof (struct session), 9637611Smckusick M_SESSION, M_NOWAIT); 9737611Smckusick if (pg->pg_session == NULL) 9837611Smckusick panic("no space to craft zero'th session"); 9937611Smckusick pg->pg_session->s_count = 1; 10039559Smarc pg->pg_session->s_leader = NULL; 10139559Smarc pg->pg_session->s_ttyvp = NULL; 10239559Smarc pg->pg_session->s_ttyp = NULL; 10337611Smckusick #ifdef KTRACE 10437611Smckusick p->p_tracep = NULL; 10537611Smckusick p->p_traceflag = 0; 10637611Smckusick #endif 10716690Smckusick /* 10818278Smckusick * These assume that the u. area is always mapped 10918278Smckusick * to the same virtual address. Otherwise must be 11016690Smckusick * handled when copying the u. area in newproc(). 11116690Smckusick */ 11238264Smckusick ndinit(&u.u_nd); 11329946Skarels 11416807Skarels u.u_cmask = cmask; 11521103Skarels u.u_lastfile = -1; 1168027Sroot for (i = 0; i < sizeof(u.u_rlimit)/sizeof(u.u_rlimit[0]); i++) 1178027Sroot u.u_rlimit[i].rlim_cur = u.u_rlimit[i].rlim_max = 1188027Sroot RLIM_INFINITY; 11918278Smckusick /* 12023534Skarels * configure virtual memory system, 12123534Skarels * set vm rlimits 12218278Smckusick */ 12318278Smckusick vminit(); 12423534Skarels 12537610Smckusick /* 12639431Smckusick * Initialize the file systems. 12739431Smckusick * 12837610Smckusick * Get vnodes for swapdev, argdev, and rootdev. 12937610Smckusick */ 13039431Smckusick vfsinit(); 13137610Smckusick if (bdevvp(swapdev, &swapdev_vp) || 13237610Smckusick bdevvp(argdev, &argdev_vp) || 13337610Smckusick bdevvp(rootdev, &rootvp)) 13437610Smckusick panic("can't setup bdevvp's"); 13537610Smckusick 13637610Smckusick /* 13737610Smckusick * Setup credentials 13837610Smckusick */ 13937610Smckusick u.u_cred = crget(); 14041513Smckusick u.u_cred->cr_ngroups = 1; 14137610Smckusick 14230256Ssam startrtclock(); 14329946Skarels #if defined(vax) 14412823Ssam #include "kg.h" 14512823Ssam #if NKG > 0 14611356Smckusick startkgclock(); 14711356Smckusick #endif 14829946Skarels #endif 14926Sbill 15026Sbill /* 1514821Swnj * Initialize tables, protocols, and set up well-known inodes. 15226Sbill */ 1534821Swnj mbinit(); 15421103Skarels cinit(); 15541565Smckusick #ifdef SYSVSHM 15641565Smckusick shminit(); 15741565Smckusick #endif 15826137Skarels #include "sl.h" 15926137Skarels #if NSL > 0 16026137Skarels slattach(); /* XXX */ 16126137Skarels #endif 16241565Smckusick #include "loop.h" 1635855Swnj #if NLOOP > 0 1645855Swnj loattach(); /* XXX */ 1655855Swnj #endif 1669156Ssam /* 1679156Ssam * Block reception of incoming packets 1689156Ssam * until protocols have been initialized. 1699156Ssam */ 1709156Ssam s = splimp(); 1715227Swnj ifinit(); 1728969Sroot domaininit(); 1739156Ssam splx(s); 17416526Skarels pqinit(); 17530531Skarels swapinit(); 1767419Sroot #ifdef GPROF 1777419Sroot kmstartup(); 1787419Sroot #endif 1797189Sroot 1808096Sroot /* kick off timeout driven events by calling first time */ 1818096Sroot roundrobin(); 1828096Sroot schedcpu(); 1838096Sroot 1848096Sroot /* set up the root file system */ 18537610Smckusick if ((*mountroot)()) 18637610Smckusick panic("cannot mount root"); 18737610Smckusick /* 18837610Smckusick * Get vnode for '/'. 18937610Smckusick * Setup rootdir and u.u_cdir to point to it. 19037610Smckusick */ 19137610Smckusick if (VFS_ROOT(rootfs, &rootdir)) 19237610Smckusick panic("cannot find root vnode"); 19337610Smckusick u.u_cdir = rootdir; 19438347Smckusick VREF(u.u_cdir); 19537726Smckusick VOP_UNLOCK(rootdir); 1968096Sroot u.u_rdir = NULL; 19742303Smarc boottime = u.u_start = time; 19826Sbill 19930256Ssam enablertclock(); /* enable realtime clock interrupts */ 20026Sbill /* 20116807Skarels * make init process 20216807Skarels */ 20316807Skarels 20438927Skarels siginit(&proc[0]); 20516807Skarels if (newproc(0)) { 206*45724Smckusick vm_offset_t addr = 0; 207*45724Smckusick 208*45724Smckusick (void) vm_allocate(u.u_procp->p_map, 209*45724Smckusick &addr, round_page(szicode), FALSE); 210*45724Smckusick if (addr != 0) 211*45724Smckusick panic("init: couldn't allocate at zero"); 212*45724Smckusick 213*45724Smckusick /* need just enough stack to exec from */ 214*45724Smckusick addr = trunc_page(VM_MAX_ADDRESS - PAGE_SIZE); 215*45724Smckusick (void) vm_allocate(u.u_procp->p_map, &addr, PAGE_SIZE, FALSE); 216*45724Smckusick u.u_maxsaddr = (caddr_t)addr; 21716807Skarels (void) copyout((caddr_t)icode, (caddr_t)0, (unsigned)szicode); 21816807Skarels /* 21916807Skarels * Return goes to loc. 0 of user init 22016807Skarels * code just copied out. 22116807Skarels */ 22216807Skarels return; 22316807Skarels } 22416807Skarels /* 225*45724Smckusick * Start up pageout daemon (process 2). 22626Sbill */ 22726Sbill if (newproc(0)) { 22826Sbill proc[2].p_flag |= SLOAD|SSYS; 22940806Smarc bcopy("pagedaemon", proc[2].p_comm, sizeof ("pagedaemon")); 230*45724Smckusick vm_pageout(); 2319025Sroot /*NOTREACHED*/ 23226Sbill } 23326Sbill 23426Sbill /* 23526Sbill * enter scheduling loop 23626Sbill */ 23726Sbill sched(); 23826Sbill } 23926Sbill 24026Sbill /* 2417001Smckusick * Initialize hash links for buffers. 2427001Smckusick */ 2437001Smckusick bhinit() 2447001Smckusick { 2457001Smckusick register int i; 2467001Smckusick register struct bufhd *bp; 2477001Smckusick 2487001Smckusick for (bp = bufhash, i = 0; i < BUFHSZ; i++, bp++) 2497001Smckusick bp->b_forw = bp->b_back = (struct buf *)bp; 2507001Smckusick } 2517001Smckusick 2527001Smckusick /* 25326Sbill * Initialize the buffer I/O system by freeing 25426Sbill * all buffers and setting all device buffer lists to empty. 25526Sbill */ 25626Sbill binit() 25726Sbill { 2588554Sroot register struct buf *bp, *dp; 25926Sbill register int i; 26010336Smckusick int base, residual; 26126Sbill 2622322Swnj for (dp = bfreelist; dp < &bfreelist[BQUEUES]; dp++) { 2632322Swnj dp->b_forw = dp->b_back = dp->av_forw = dp->av_back = dp; 2642322Swnj dp->b_flags = B_HEAD; 2652322Swnj } 26610336Smckusick base = bufpages / nbuf; 26710336Smckusick residual = bufpages % nbuf; 2686570Smckusic for (i = 0; i < nbuf; i++) { 26926Sbill bp = &buf[i]; 27026Sbill bp->b_dev = NODEV; 2719156Ssam bp->b_bcount = 0; 27238774Smckusick bp->b_rcred = NOCRED; 27338774Smckusick bp->b_wcred = NOCRED; 27438774Smckusick bp->b_dirtyoff = 0; 27538774Smckusick bp->b_dirtyend = 0; 2766570Smckusic bp->b_un.b_addr = buffers + i * MAXBSIZE; 27710336Smckusick if (i < residual) 27810336Smckusick bp->b_bufsize = (base + 1) * CLBYTES; 27910336Smckusick else 28010336Smckusick bp->b_bufsize = base * CLBYTES; 2819750Ssam binshash(bp, &bfreelist[BQ_AGE]); 2822322Swnj bp->b_flags = B_BUSY|B_INVAL; 28326Sbill brelse(bp); 28426Sbill } 28530531Skarels } 28630531Skarels 28730531Skarels /* 28830531Skarels * Set up swap devices. 28930531Skarels * Initialize linked list of free swap 29030531Skarels * headers. These do not actually point 29130531Skarels * to buffers, but rather to pages that 29230531Skarels * are being swapped in and out. 29330531Skarels */ 29430531Skarels swapinit() 29530531Skarels { 29630531Skarels register int i; 29730531Skarels register struct buf *sp = swbuf; 29830531Skarels struct swdevt *swp; 29937611Smckusick int error; 30030531Skarels 301306Sbill /* 302306Sbill * Count swap devices, and adjust total swap space available. 30330531Skarels * Some of this space will not be available until a swapon() 304306Sbill * system is issued, usually when the system goes multi-user. 305306Sbill */ 306306Sbill nswdev = 0; 30712489Ssam nswap = 0; 30812489Ssam for (swp = swdevt; swp->sw_dev; swp++) { 309306Sbill nswdev++; 31012489Ssam if (swp->sw_nblks > nswap) 31112489Ssam nswap = swp->sw_nblks; 31212489Ssam } 313306Sbill if (nswdev == 0) 31430531Skarels panic("swapinit"); 3154132Secc if (nswdev > 1) 31612489Ssam nswap = ((nswap + dmmax - 1) / dmmax) * dmmax; 317306Sbill nswap *= nswdev; 31837610Smckusick if (bdevvp(swdevt[0].sw_dev, &swdevt[0].sw_vp)) 31937610Smckusick panic("swapvp"); 32037611Smckusick if (error = swfree(0)) { 32137611Smckusick printf("swfree errno %d\n", error); /* XXX */ 32237611Smckusick panic("swapinit swfree 0"); 32337611Smckusick } 32426Sbill 32530531Skarels /* 32630531Skarels * Now set up swap buffer headers. 32730531Skarels */ 3282753Swnj bswlist.av_forw = sp; 3292769Swnj for (i=0; i<nswbuf-1; i++, sp++) 3302753Swnj sp->av_forw = sp+1; 3312753Swnj sp->av_forw = NULL; 33226Sbill } 3332746Swnj 3342746Swnj /* 3352746Swnj * Initialize clist by freeing all character blocks, then count 3362746Swnj * number of character devices. (Once-only routine) 3372746Swnj */ 3382746Swnj cinit() 3392746Swnj { 3402746Swnj register int ccp; 3412746Swnj register struct cblock *cp; 3422746Swnj 3432746Swnj ccp = (int)cfree; 3442746Swnj ccp = (ccp+CROUND) & ~CROUND; 3452746Swnj for(cp=(struct cblock *)ccp; cp < &cfree[nclist-1]; cp++) { 3462746Swnj cp->c_next = cfreelist; 3472746Swnj cfreelist = cp; 3482746Swnj cfreecount += CBSIZE; 3492746Swnj } 3502746Swnj } 351