(莱昂氏unix源代码分析导读-9)系统初启(2)

2.2 main

现在,让我们看看mainC语言代码,我们的老朋友。

1550 main()

1551 {

        ......

1558

1559 updlock = 0;

1560 i = *ka6 + USIZE;                     /iPPDA之后的blockblock

1561 UISD->r[0] = 077406;              /077406,熟悉的数字 4k rw

1562 for(;;) {

1563       UISA->r[0] = i;                 /设置UISA0

1564       if(fuibyte(0) < 0)              /莱昂中将fuibyte的分析留给了读者,这是个很好的练习

                                                         /我的分析在本章的最后,但建议您先自己分析一下

1565                break;

1566       clearseg(i);                        /clear 1block

 

下面详细介绍clearseg——顺便说一下,现在是搞清楚mfpimtpi的时候了。

 

675 .  .globl  _clearseg              

676   _clearseg:

677      mov    PS, -(sp)              /保存PS(压栈)

678      mov    UISA0, -(sp)         /保存UISA0(压栈)

679      mov    $30340,PS            /设置PSCPU优先级7

680      mov    6(sp),UISA0         /参数---->UISA0

681      mov    UISD0, -(sp)        /保存UISD0(压栈)

682      mov    $6, UISD0            /UISD0设置为6rw           

683      clr      r0                           / r0 = 0

684      mov    $32.,r1                 /r1 = 32dec

685   1:

686      clr      -(sp)                /0压栈

687      mtpi    (r0)+               /从当前栈上弹出1 word(值为0)到previous空间r0/向的地址

                                              /1r00,故处在第一个virtual page中,故使用UISA0/进行地址变换; 

                                              /2UISA0设置为参数值;

                                              /3)故,将参数指定的地址清0

688      sob     r1,1b               /循环32次(即1Block长度)

 

689      mov    (sp)+,UISD0         /恢复UISD0

690      mov    (sp)+,UISA0         /恢复UISA0

691      mov    (sp)+,PS                /恢复PS

692      rts     pc                             /return to caller

 

因此, clearseg(i)的执行结果为,将i指向的block0

让我们一鼓作气,顺便把copyseg也解决掉。

695 .  .globl  _copyseg

696   _ copyseg:

697      mov    PS, -(sp)                /保存PS(压栈)

698      mov    UISA0, -(sp)         /保存UISA0(压栈)

699      mov    UISA1, -(sp)         /保存UISA1(压栈)

700      mov    $30340PS 

701      mov    10(sp)UISA0       /这两句是我们的老朋友了:

702      mov    12(SP),UISA1        /  参数1--->UISA0;参数2---->UISA1

703      mov    UISD0, -(sp)         /保存UISD0(压栈)

704      mov    UISD1, -(sp)         /保存UISD1(压栈)

705      mov    $6, UISD0            /UISD0设置为6rw

706      mov    $6, UISD1            /UISD1设置为6rw

707      mov    r2, -(sp)               /保存r

708      clr     r0                           /r00

                                                    /现在,好戏开始了。

709      mov   $8192., r1             /8192.,这个神奇数字是什么意思?

710      mov   $32., r2                 /32.,显然,是block的长度

711  1:

712     mfpi   (r0)+                 /把“前地址空间”的r0地址的内容压栈

713     mtpi   (r1)+                 /从栈中弹出1word到“前地址空间”的r1地址

                                                /完成了将参数1指向word拷贝到了参数2指向的word

714     sob    r2,1b                   /循环32次(1Block长度),结束后就拷贝了整个block

                                

715     mov   (sp)+,r2               /恢复各个寄存器

716     mov   (sp)+,UISD1

717     mov   (sp)+, UISD0

718     mov   (sp)+, UISA1

719     mov   (sp)+, UISA1

720     mov   (sp)+,PS

721     rts     pc                         /return to caller

 

这个神奇的拷贝过程是怎么发生的?

(1)   首先,要先搞清8192这个神奇数字——它是一个page的长度,同时也是第二个virtual page 的起始地址!

(2)   首次执行mfpi  (r0)+时,r00,是第一个virtual page的起始地址!

             物理地址=UISA0*64+0——会将该地址的内容压栈;

(3)   mtpi   (r1)+,而r1为第二个virtual page的起始地址,它指向的物理地址为“物理地址= UISA1*64+0”。这条语句

             会将栈内的内容(UISA0*64+0的内容)弹出到该物理地址上;

(4)   执行32次后,就拷贝了整个block

 

UISA0UISA1分别由两个参数设置,所以,copyseg的作用就是将参数1指向的block的内容拷贝到参数2指向的block

【注】:mfpi mtpi是“fuibyte”的难点所在。如果“fuibyte”一直使您迷惑的话,现在是解决它的时候了。
               您最好独立完成这个习题,我的分析在本章的最后,但希望您在完成自己的分析之前不要去看它。

 

1567       maxmem++;             /可用memory大小

1568       mfree(coremap, 1, i);      /扩充可用memory

1569       i++;

1570 }

 

这个无限for循环会从PPDA后的第一个block开始,一直Loop到物理内存的尽头,将可用内存block通过mfree回收到可用内存表中。

 

1571 if(cputype == 70)                              /1461  _cputype:40

1572      for(i=0; i<62; i=+2) {                   /故,此段代码不会被执行到,跳过不看

1573           UBMAP->r[i] = i<<12;

1574           UBMAP->r[i+1] = 0;

1575      }

                   ……

1595 /*

1596 * determine clock

1597 */

1598

1599 UISA->r[7] = ka6[1]; /* io segment */           /陷阱!

                                                                               /ka6[1]指向最后一个 pageka6[0]才是第7page

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;

1608

 

博客地址:http://blog.csdn.net/cszhao1980

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
目 录 献辞 致谢 序(一) 序(二) 历史注记 上篇 UNIX操作系统版本6源代码 UNIX操作系统过程分类索引 3 UNIX操作系统文件及过程 5 UNIX操作系统定义的符号列表 7 UNIX操作系统源代码交叉引用列表 9 第一部分 初始化、进程初始化 25 第二部分 陷入、中断、系统调用和 进程管理 75 第三部分 程序交换、基本输入/输出、 块设备 109 第四部分 文件和目录、文件系统、管道 133 第五部分 面向字符的特殊文件 181 下篇 莱昂UNIX源代码分析 前言 207 第1章 绪论 209 1.1 UNIX操作系统 209 1.2 公用程序 209 1.3 其他文档 210 1.4 UNIX程序员手册 210 1.5 UNIX文档 211 1.6 UNIX操作系统源代码 211 1.7 源代码中各部分 212 1.8 源代码文件 212 1.9 分析的使用 212 1.10 对程序设计水平的一条注释 212 第2章 基础知识 214 2.1 处理机 214 2.2 处理机状态字 214 2.3 通用寄存器 214 2.4 指令集 215 2.5 寻址方式 216 2.5.1 寄存器方式 217 2.5.2 寄存器延迟方式 217 2.5.3 自动增1方式 217 2.5.4 自动减1方式 217 2.5.5 变址方式 217 2.5.6 立即方式 218 2.5.7 相对方式 218 2.6 UNIX汇编程序 219 2.7 存储管理 219 2.8 段寄存器 220 2.9 页说明寄存器 220 2.10 存储分配 220 2.11 状态寄存器 221 2.12 “i”和“d”空间 221 2.13 启动条件 221 2.14 专用设备寄存器 221 第3章 阅读“C”程序 222 3.1 某些选出的例子 222 3.2 例1 222 3.3 例2 223 3.4 例3 223 3.5 例4 225 3.6 例5 225 3.7 例6 227 3.8 例7 227 3.9 例8 228 3.10 例9 228 3.11 例10 229 3.12 例11 229 3.13 例12 230 3.14 例13 230 3.15 例14 231 3.16 例15 231 3.17 例16 232 3.18 例17 233 第4章 概述 235 4.1 变量分配 235 4.2 全局变量 235 4.3 “C”预处理程序 235 4.4 第一部分 236 4.4.1 第1组“.h”文件 236 4.4.2 汇编语言文件 237 4.4.3 在第一部分中的其他文件 237 4.5 第二部分 237 4.6 第三部分 238 4.7 第四部分 238 4.8 第五部分 239 第一部分 初始化、进程初始化 第5章 两个文件 241 5.1 文件malloc.c 241 5.1.1 列表维护规则 241 5.1.2 malloc(2528) 242 5.1.3 mfree(2556) 243 5.1.4 结论 244 5.2 文件prf.c 244 5.2.1 printf(2340) 244 5.2.2 printn(2369) 245 5.2.3 putchar(2386) 246 5.2.4 panic(2419) 247 5.2.5 prdev(2433)、deverror(2447) 247 5.3 包含的文件 247 第6章 系统初启 249 6.1 操作员的动作 249 6.2 start(0612) 249 6.3 main(1550) 251 6.4 进程 252 6.5 proc〔0〕的初始化 252 6.6 sched(1940) 253 6.7 sleep(2066) 253 6.8 swtch(2178) 253 6.9 再回到main 254 第7章 进程 256 7.1 进程映像 256 7.2 proc结构(0358) 257 7.3 user结构(0413) 257 7.4 每个进程数据区 258 7.5 段 258 7.6 映像的执行 258 7.7 核心态执行 259 7.8 用户态执行
### 回答1: 《莱昂UNIX源码分析》是一本经典的计算机技术书籍,全书共分为五个部分,详细介绍了UNIX操作系统源代码及其实现原理。该书以莱昂UNIX源代码为基础,通过源代码的解析和分析,深入探讨了UNIX操作系统的内核设计、进程管理、文件系统、网络通信等核心内容。 在《莱昂UNIX源码分析》中,作者通过逐行分析UNIX操作系统源代码,揭示了UNIX操作系统的内部工作机制。读者可以通过学习这本书,深入理解UNIX操作系统的运行原理,并且从中获得对操作系统设计和实现的深入洞察。 此外,该书还提供了大量的实例代码和实验,帮助读者动手实践和验证。通过实际的操作和实验,读者可以更好地理解和掌握UNIX操作系统的核心概念和原理。 《莱昂UNIX源码分析》可以说是UNIX操作系统研究者和操作系统开发者的必备参考书籍之一。通过阅读该书,读者可以系统地学习和掌握UNIX操作系统源代码和实现原理,为自己的研究和开发工作提供有效的指导和帮助。无论是对于对UNIX操作系统感兴趣的学生还是从事操作系统相关工作的专业人士,这本书都是必不可少的学习资料。 ### 回答2: 《莱昂UNIX源码分析》是一本非常经典的Unix操作系统源码分析书籍,由Peter H. Salus于1994年编写。该书主要讲解了UNIX操作系统的内核源码,通过深入分析UNIX的实现原理和设计思想,帮助读者理解UNIX操作系统的核心机制。 书中首先介绍了UNIX的历史和发展背景,包括UNIX的创始人Ken Thompson和Dennis Ritchie,以及UNIX与其他操作系统的区别与联系。接着,作者详细解析了UNIX系统的整体结构和组成部分,包括进程管理、文件系统、内存管理、设备驱动等。 在分析过程中,作者引用了大量的UNIX源码片段,并逐行详细解释了每个函数或数据结构的作用和实现原理。读者可以通过学习这些源码片段,深入了解UNIX操作系统的实现细节。同时,作者还提供了一些实践性的示例,通过自己手动修改和运行源码,加深对UNIX系统的理解。 《莱昂UNIX源码分析》以其通俗易懂的语言和深入浅出的分析方式,成为了许多计算机科学等相关领域的学生和研究人员的必备参考书。通过阅读该书,读者不仅可以掌握UNIX操作系统的内部工作原理,还能够培养良好的源码阅读和分析能力。 总之,作为一本经典的UNIX源码分析书籍,《莱昂UNIX源码分析》通过讲解UNIX操作系统的实现原理,帮助读者深入了解UNIX的核心机制和设计思想。无论是对于计算机科学专业的学生,还是对于对UNIX操作系统感兴趣的人士,该书都值得一读。 ### 回答3: 《莱昂UNIX源码分析》是一本经典的计算机图书,对UNIX操作系统源代码进行了详细的解析。该书通过分析UNIX操作系统内核的源代码,深入剖析了UNIX操作系统的设计思想、核心机制和关键模块的实现方式。 在《莱昂UNIX源码分析》中,作者结合了自己多年的研究和实践经验,将UNIX操作系统内核的代码逐行逐句地进行解读,包括进程管理、内存管理、文件系统、设备驱动等方面。读者可以通过学习这本书,了解UNIX操作系统内部的各个模块是如何协同工作的,以及它们之间的相互关系。 该书不仅介绍了UNIX操作系统的基本原理和设计思想,还对各个模块的实现细节进行了详细的讲解。通过对源代码的解析,读者可以了解到UNIX操作系统是如何管理进程、分配内存、访问文件、处理中断等一系列操作的。 《莱昂UNIX源码分析》以其深入浅出的语言和逻辑结构,引导读者逐步理解UNIX操作系统的设计和实现。读者可以通过学习这本书,提升自己的系统编程能力,加深对UNIX操作系统的理解。 总之,《莱昂UNIX源码分析》是一本非常值得阅读的图书,它对UNIX操作系统源代码进行了全面深入的分析,对于希望深入了解UNIX操作系统内部工作原理的读者来说,是一本非常好的参考书。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值