code:main - ikarishinjieva/unixV6-code-analyze-chs GitHub Wiki
1531
1532 /*
1533 * Initialization code.
1534 * Called from m40.s or m45.s as
1535 * soon as a stack and segmentation
1536 * have been established.
1537 * Functions:
1538 * clear and free user core
1539 * find which clock is configured
1540 * hand craft 0th process
1541 * call all initialization routines
1542 * fork - process 0 to schedule
1543 * - process 1 execute bootstrap
1544 *
1545 * panic: no clock -- neither clock responds
1546 * loop at loc 6 in user mode -- /etc/init
1547 * cannot be executed
1548 */
1549
1550 main()
1551 {
1552 extern schar;
1553 register i, *p;
1554
1555 /*
1556 * zero and free all of core
1557 */
1558
1559 updlock = 0;
1560 i = *ka6 + USIZE;
1561 UISD->r[0] = 077406;
- i = 0#进程PPDA区后第一个块的块号
1562 for(;;) {
- 设置UISD[0],使其大小为8K字节,并且为可读写,参看页说明寄存器
1563 UISA->r[0] = i;
1564 if(fuibyte(0) < 0)
1565 break;
1566 clearseg(i);
1567 maxmem++;
1569 i++;
1570 }
1562 - 15691571 if(cputype == 70)
- 从0#进程PPDA区后的第一个块开始:
- 尝试读取每一个块的第一个字节,若能读取成功,表明该块为可用内存块
- 清该块内容
- 内存最大块数+1
- 将该块加入内存可用区表
- 继续取下一个内存块,直到该块读取出错为止,表明可用内存到此为止
1572 for(i=0; i<62; i=+2) {
1573 UBMAP->r[i] = i<<12;
1574 UBMAP->r[i+1] = 0;
1575 }
1576 printf("mem = %l \n", maxmem*5/16);
- 对于pdp11/40,上述部分不会执行
1577 printf("RESTRICTED RIGHTS \n \n");
1578 printf("Use, duplication or disclosure is subject to \n");
1579 printf("restrictions stated in Contract with Western \n");
1580 printf("Electric Company, Inc. \n");
1581
- 输出相关信息
1582 maxmem = min(maxmem, MAXMEM);
1583 mfree(swapmap, nswap, swplo);
- 计算单个进程能使用的最大内存空间
1584
1585 /*
1586 * set up system process
1587 */
1588
1589 proc[0].p_addr = *ka6;
1590 proc[0].p_size = USIZE;
1591 proc[0].p_stat = SRUN;
1592 proc[0].p_flag =| SLOAD|SSYS;
1594
- 对0#进程进行初始化参数设置
1595 /*
1596 * determine clock
1597 */
1598
1599 UISA->r[7] = ka6[1]; /* io segment */
1600 UISD->r[7] = 077406;
1601 lks = CLOCK1;
1602 if(fuiword(lks) == -1) {
1603 lks = CLOCK2;
1604 if(fuiword(lks) == -1)
1605 panic("no clock");
1606 }
1607 *lks = 0115;
1601 - 1607
- 判断当前时钟的种类,并且对时钟寄存器进行初始化
- 参看时钟
关于1599 - 1600 1602 1604的说明1608
1609 /*
1610 * set up 'known' i-nodes
1611 */
1612
1613 cinit();
1614 binit();
1615 iinit();
1616 rootdir = iget(rootdev, ROOTINO);
- 初始化块缓存
- 初始化字符缓存
- 初始化文件系统
1617 rootdir->i_flag =& ~ILOCK;
1618 u.u_cdir = iget(rootdev, ROOTINO);
1619 u.u_cdir->i_flag =& ~ILOCK;
1620
- 初始化:
- rootdir
- u.u_cdir
1621 /*
1622 * make init process
1623 * enter scheduling loop
1624 * with system process
1625 */
1626
1627 if(newproc()) {
1628 expand(USIZE+1);
1629 estabur(0, 1, 0, 0);
1630 copyout(icode, 0, sizeof icode);
1631 /*
1632 * Return goes to loc. 0 of user init
1633 * code just copied out.
1634 */
1635 return;
1636 }
1637 sched();icode存放的是用户态启动程序的二进制代码 详细参看 LIONS代码分析
- 创建1号进程
- 对于新创建的1#进程
- 扩展进程图像
- 设置相对地址映照
- 将icode数组中的内容拷贝到用户态地址空间的起始地址
1638 }
- 对于0#进程,执行进程图像调入调出主循环
1639 /* ------------------------- */