1: /* 2: * Copyright (c) 1986 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: * 6: * @(#)init_main.c 2.5 (2.11BSD GTE) 1997/9/26 7: */ 8: 9: #include "param.h" 10: #include "../machine/seg.h" 11: 12: #include "user.h" 13: #include "fs.h" 14: #include "mount.h" 15: #include "map.h" 16: #include "proc.h" 17: #include "ioctl.h" 18: #include "inode.h" 19: #include "conf.h" 20: #include "buf.h" 21: #include "fcntl.h" 22: #include "vm.h" 23: #include "clist.h" 24: #include "uba.h" 25: #include "reboot.h" 26: #include "systm.h" 27: #include "kernel.h" 28: #include "namei.h" 29: #include "disklabel.h" 30: #include "stat.h" 31: #ifdef QUOTA 32: #include "quota.h" 33: #endif 34: 35: int netoff = 1; 36: int cmask = CMASK; 37: int securelevel; 38: 39: extern size_t physmem; 40: extern struct mapent _coremap[]; 41: 42: /* 43: * Initialization code. 44: * Called from cold start routine as 45: * soon as a stack and segmentation 46: * have been established. 47: * Functions: 48: * clear and free user core 49: * turn on clock 50: * hand craft 0th process 51: * call all initialization routines 52: * fork - process 0 to schedule 53: * - process 1 execute bootstrap 54: */ 55: main() 56: { 57: extern dev_t bootdev; 58: extern caddr_t bootcsr; 59: register struct proc *p; 60: register int i; 61: register struct fs *fs; 62: time_t toytime, toyclk(); 63: daddr_t swsize; 64: int (*ioctl)(); 65: struct partinfo dpart; 66: 67: startup(); 68: 69: /* 70: * set up system process 0 (swapper) 71: */ 72: p = &proc[0]; 73: p->p_addr = *ka6; 74: p->p_stat = SRUN; 75: p->p_flag |= SLOAD|SSYS; 76: p->p_nice = NZERO; 77: 78: u.u_procp = p; /* init user structure */ 79: u.u_ap = u.u_arg; 80: u.u_cmask = cmask; 81: u.u_lastfile = -1; 82: for (i = 1; i < NGROUPS; i++) 83: u.u_groups[i] = NOGROUP; 84: for (i = 0; i < sizeof(u.u_rlimit)/sizeof(u.u_rlimit[0]); i++) 85: u.u_rlimit[i].rlim_cur = u.u_rlimit[i].rlim_max = 86: RLIM_INFINITY; 87: bcopy("root", u.u_login, sizeof ("root")); 88: 89: /* Initialize signal state for process 0 */ 90: siginit(p); 91: 92: /* 93: * Initialize tables, protocols, and set up well-known inodes. 94: */ 95: cinit(); 96: pqinit(); 97: xinit(); 98: ihinit(); 99: bhinit(); 100: binit(); 101: ubinit(); 102: #ifdef QUOTA 103: QUOTAMAP(); 104: qtinit(); 105: u.u_quota = getquota(0, 0, Q_NDQ); 106: QUOTAUNMAP(); 107: #endif 108: nchinit(); 109: clkstart(); 110: 111: /* 112: * If the kernel is configured for the boot/load device AND the use of the 113: * compiled in 'bootdev' has not been overridden (by turning on RB_DFLTROOT, 114: * see conf/boot.c for details) THEN switch 'rootdev', 'swapdev' and 'pipedev' 115: * over to the boot/load device. Set 'pipedev' to be 'rootdev'. 116: * 117: * The &077 removes the controller number (bits 6 and 7) - those bits are 118: * passed thru from /boot but would only greatly confuse the rest of the kernel. 119: */ 120: i = major(bootdev); 121: if ((bdevsw[i].d_strategy != nodev) && !(boothowto & RB_DFLTROOT)) 122: { 123: rootdev = makedev(i, minor(bootdev) & 077); 124: swapdev = rootdev | 1; /* partition 'b' */ 125: pipedev = rootdev; 126: /* 127: * We check that the dump device is the same as the boot device. If it is 128: * different then it is likely that crashdumps go to a tape device rather than 129: * the swap area. In that case do not switch the dump device. 130: */ 131: if ((dumpdev != NODEV) && major(dumpdev) == i) 132: dumpdev = swapdev; 133: } 134: 135: /* 136: * Need to attach the root device. The CSR is passed thru because this 137: * may be a 2nd or 3rd controller rather than the 1st. NOTE: This poses 138: * a big problem if 'swapdev' is not on the same controller as 'rootdev' 139: * _or_ if 'swapdev' itself is on a 2nd or 3rd controller. Short of moving 140: * autconfigure back in to the kernel it is not known what can be done about 141: * this. 142: * 143: * One solution (for now) is to call swapdev's attach routine with a zero 144: * address. The MSCP driver treats the 0 as a signal to perform the 145: * old (fixed address) attach. Drivers (all the rest at this point) which 146: * do not support alternate controller booting always attach the first 147: * (primary) CSR and do not expect an argument to be passed. 148: */ 149: (void)(*bdevsw[major(bootdev)].d_root)(bootcsr); 150: (void)(*bdevsw[major(swapdev)].d_root)((caddr_t) 0); /* XXX */ 151: 152: /* 153: * Now we find out how much swap space is available. Since 'nswap' is 154: * a "u_int" we have to restrict the amount of swap to 65535 sectors (~32mb). 155: * Considering that 4mb is the maximum physical memory capacity of a pdp-11 156: * 32mb swap should be enough ;-) 157: * 158: * The initialization of the swap map was moved here from machdep2.c because 159: * 'nswap' was no longer statically defined and this is where the swap dev 160: * is opened/initialized. 161: * 162: * Also, we toss away/ignore .5kb (1 sector) of swap space (because a 0 value 163: * can not be placed in a resource map). 164: * 165: * 'swplo' was a hack which has _finally_ gone away! It was never anything 166: * but 0 and caused a number of double word adds in the kernel. 167: */ 168: (*bdevsw[major(swapdev)].d_open)(swapdev, FREAD|FWRITE, S_IFBLK); 169: swsize = (*bdevsw[major(swapdev)].d_psize)(swapdev); 170: if (swsize <= 0) 171: panic("swsiz"); /* don't want to panic, but what ? */ 172: 173: /* 174: * Next we make sure that we do not swap on a partition unless it is of 175: * type FS_SWAP. If the driver does not have an ioctl entry point or if 176: * retrieving the partition information fails then the driver does not 177: * support labels and we proceed normally, otherwise the partition must be 178: * a swap partition (so that we do not swap on top of a filesystem by mistake). 179: */ 180: ioctl = cdevsw[blktochr(swapdev)].d_ioctl; 181: if (ioctl && !(*ioctl)(swapdev, DIOCGPART, (caddr_t)&dpart, FREAD)) 182: { 183: if (dpart.part->p_fstype != FS_SWAP) 184: panic("swtyp"); 185: } 186: if (swsize > (daddr_t)65535) 187: swsize = 65535; 188: nswap = swsize; 189: mfree(swapmap, --nswap, 1); 190: 191: fs = mountfs(rootdev, boothowto & RB_RDONLY ? MNT_RDONLY : 0, 192: (struct inode *)0); 193: if (!fs) 194: panic("iinit"); 195: mount[0].m_inodp = (struct inode *)1; /* XXX */ 196: mount_updname(fs, "/", "root", 1, 4); 197: time.tv_sec = fs->fs_time; 198: if (toytime = toyclk()) 199: time.tv_sec = toytime; 200: boottime = time; 201: 202: /* kick off timeout driven events by calling first time */ 203: schedcpu(); 204: 205: /* set up the root file system */ 206: rootdir = iget(rootdev, &mount[0].m_filsys, (ino_t)ROOTINO); 207: iunlock(rootdir); 208: u.u_cdir = iget(rootdev, &mount[0].m_filsys, (ino_t)ROOTINO); 209: iunlock(u.u_cdir); 210: u.u_rdir = NULL; 211: 212: #ifdef INET 213: if (netoff = netinit()) 214: printf("netinit failed\n"); 215: else 216: { 217: NETSETHZ(); 218: NETSTART(); 219: } 220: #endif 221: 222: /* 223: * This came from pdp/machdep2.c because the memory available statements 224: * were being made _before_ memory for the networking code was allocated. 225: * A side effect of moving this code is that network "attach" and MSCP 226: * "online" messages can appear before the memory sizes. The (currently 227: * safe) assumption is made that no 'free' calls are made so that the 228: * size in the first entry of the core map is correct. 229: */ 230: printf("\nphys mem = %D\n", ctob((long)physmem)); 231: printf("avail mem = %D\n", ctob((long)_coremap[0].m_size)); 232: maxmem = MAXMEM; 233: printf("user mem = %D\n", ctob((long)MAXMEM)); 234: #if NRAM > 0 235: printf("ram disk = %D\n", ctob((long)ramsize)); 236: #endif 237: printf("\n"); 238: 239: /* 240: * make init process 241: */ 242: if (newproc(0)) { 243: expand((int)btoc(szicode), S_DATA); 244: expand((int)1, S_STACK); /* one click of stack */ 245: estabur((u_int)0, (u_int)btoc(szicode), (u_int)1, 0, RO); 246: copyout((caddr_t)icode, (caddr_t)0, szicode); 247: /* 248: * return goes to location 0 of user init code 249: * just copied out. 250: */ 251: return; 252: } 253: else 254: sched(); 255: } 256: 257: /* 258: * Initialize hash links for buffers. 259: */ 260: static 261: bhinit() 262: { 263: register int i; 264: register struct bufhd *bp; 265: 266: for (bp = bufhash, i = 0; i < BUFHSZ; i++, bp++) 267: bp->b_forw = bp->b_back = (struct buf *)bp; 268: } 269: 270: memaddr bpaddr; /* physical click-address of buffers */ 271: /* 272: * Initialize the buffer I/O system by freeing 273: * all buffers and setting all device buffer lists to empty. 274: */ 275: static 276: binit() 277: { 278: register struct buf *bp; 279: register int i; 280: long paddr; 281: 282: for (bp = bfreelist; bp < &bfreelist[BQUEUES]; bp++) 283: bp->b_forw = bp->b_back = bp->av_forw = bp->av_back = bp; 284: paddr = ((long)bpaddr) << 6; 285: for (i = 0; i < nbuf; i++, paddr += MAXBSIZE) { 286: bp = &buf[i]; 287: bp->b_dev = NODEV; 288: bp->b_bcount = 0; 289: bp->b_un.b_addr = (caddr_t)loint(paddr); 290: bp->b_xmem = hiint(paddr); 291: binshash(bp, &bfreelist[BQ_AGE]); 292: bp->b_flags = B_BUSY|B_INVAL; 293: brelse(bp); 294: } 295: } 296: 297: /* 298: * Initialize clist by freeing all character blocks, then count 299: * number of character devices. (Once-only routine) 300: */ 301: static 302: cinit() 303: { 304: register int ccp; 305: register struct cblock *cp; 306: 307: ccp = (int)cfree; 308: #ifdef UCB_CLIST 309: mapseg5(clststrt, clstdesc); /* don't save, we know it's normal */ 310: #else 311: ccp = (ccp + CROUND) & ~CROUND; 312: #endif 313: for (cp = (struct cblock *)ccp; cp <= &cfree[nclist - 1]; cp++) { 314: cp->c_next = cfreelist; 315: cfreelist = cp; 316: cfreecount += CBSIZE; 317: } 318: #ifdef UCB_CLIST 319: normalseg5(); 320: #endif 321: } 322: 323: #ifdef INET 324: memaddr netdata; /* click address of start of net data */ 325: 326: /* 327: * We are called here after all the other init routines (clist, inode, 328: * unibusmap, etc...) have been called. Open the 329: * file NETNIX and read the a.out header, based on that go allocate 330: * memory and read the text+data into the memory. Set up supervisor page 331: * registers, SDSA6 and SDSA7 have already been set up in mch_start.s. 332: */ 333: 334: static char NETNIX[] = "/netnix"; 335: 336: static 337: netinit() 338: { 339: register u_short *ap, *dp; 340: register int i; 341: struct exec ex; 342: struct inode *ip; 343: memaddr nettext; 344: long lsize; 345: off_t off; 346: int initdata, netdsize, nettsize, ret, err, resid; 347: char oneclick[ctob(1)]; 348: struct nameidata nd; 349: register struct nameidata *ndp = &nd; 350: 351: ret = 1; 352: NDINIT(ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, NETNIX); 353: if (!(ip = namei(ndp))) { 354: printf("%s not found\n", NETNIX); 355: goto leave; 356: } 357: if ((ip->i_mode & IFMT) != IFREG || !ip->i_size) { 358: printf("%s bad inode\n", NETNIX); 359: goto leave; 360: } 361: err = rdwri(UIO_READ, ip, &ex, sizeof (ex), (off_t)0, UIO_SYSSPACE, 362: IO_UNIT, &resid); 363: if (err || resid) { 364: printf("%s header %d\n", NETNIX, ret); 365: goto leave; 366: } 367: if (ex.a_magic != A_MAGIC3) { 368: printf("%s bad magic %o\n", NETNIX, ex.a_magic); 369: goto leave; 370: } 371: lsize = (long)ex.a_data + (long)ex.a_bss; 372: if (lsize > 48L * 1024L) { 373: printf("%s 2big %ld\n", NETNIX, lsize); 374: goto leave; 375: } 376: nettsize = btoc(ex.a_text); 377: nettext = (memaddr)malloc(coremap, nettsize); 378: netdsize = btoc(ex.a_data + ex.a_bss); 379: netdata = (memaddr)malloc(coremap, netdsize); 380: initdata = ex.a_data >> 6; 381: off = sizeof (ex); 382: for (i = 0; i < nettsize; i++) { 383: err = rdwri(UIO_READ, ip, oneclick, ctob(1), off, UIO_SYSSPACE, 384: IO_UNIT, &resid); 385: if (err || resid) 386: goto release; 387: mapseg5(nettext + i, 077406); 388: bcopy(oneclick, SEG5, ctob(1)); 389: off += ctob(1); 390: normalseg5(); 391: } 392: for (i = 0; i < initdata; i++) { 393: err = rdwri(UIO_READ, ip, oneclick, ctob(1), off, UIO_SYSSPACE, 394: IO_UNIT, &resid); 395: if (err || resid) 396: goto release; 397: mapseg5(netdata + i, 077406); 398: bcopy(oneclick, SEG5, ctob(1)); 399: normalseg5(); 400: off += ctob(1); 401: } 402: if (ex.a_data & 077) { 403: err = rdwri(UIO_READ, ip, oneclick, ex.a_data & 077, off, 404: UIO_SYSSPACE, IO_UNIT, &resid); 405: if (err || resid) { 406: release: printf("%s err %d\n", NETNIX, err); 407: mfree(coremap, nettsize, nettext); 408: mfree(coremap, netdsize, netdata); 409: nettsize = netdsize = 0; 410: netdata = nettext = 0; 411: goto leave; 412: } 413: mapseg5(netdata + i, 077406); /* i is set from above loop */ 414: bcopy(oneclick, SEG5, ex.a_data & 077); 415: normalseg5(); 416: } 417: for (i = 0, ap = SISA0, dp = SISD0; i < nettsize; i += stoc(1)) { 418: *ap++ = nettext + i; 419: *dp++ = ((stoc(1) - 1) << 8) | RO; 420: } 421: /* might have over run the length on the last one, patch it now */ 422: if (i > nettsize) 423: *--dp -= ((i - nettsize) << 8); 424: for (i = 0, ap = SDSA0, dp = SDSD0; i < netdsize; i += stoc(1)) { 425: *ap++ = netdata + i; 426: *dp++ = ((stoc(1) - 1) << 8) | RW; 427: } 428: if (i > netdsize) 429: *--dp -= ((i - netdsize) << 8); 430: ret = 0; 431: leave: if (ip) 432: iput(ip); 433: u.u_error = 0; 434: return(ret); 435: } 436: #endif