自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

cszhao1980的专栏

十年碌碌

  • 博客(69)
  • 收藏
  • 关注

原创 (莱昂氏unix源代码分析导读-51) 交互式终端

1 DL11/KL11终端有很多种终端可供选择使用,在一台计算机上可能同时连接若干种不同类型的终端。在我们的模型里,使用DL11 / KL 11终端。 一个DL11/KL11终端拥有4个设备寄存器,分为接收和发送两组,可用如下结构表示:8016: struct klregs { 8017:     int klrcsr;   //接收状态寄存器8018:     i

2013-09-21 09:05:07 4920 4

原创 (莱昂氏unix源代码分析导读-50)LP11行式打印机

LP11有两个设备寄存器:状态寄存器(lpsr)和数据缓冲寄存器(lpbuf),可通过以下结构进行访问:8812: #define LPADDR 01775148823: struct {8824:     int lpsr;8825:     int lpbuf;8826: }; (1).  LPADDR.lpsr:状态寄存器i. 第15位(最高位):出错标记;

2013-08-17 13:16:42 3813

原创 (莱昂氏unix源代码分析导读-49) 字符缓冲区

同块设备一样,对字符设备的输入输出也是通过缓冲区来进行的。使用缓冲区有个额外的好处,即以缓冲区为界,函数可分为高低两个层次。低层函数负责与实际设备交互,而高层函数只与缓冲区打交道,只对缓冲区存取数据,这样可以蔽掉掉底层的许多细节。 对于字符缓冲区,有两个最重要结构,即cblock和clist。前者是缓冲区本身,后者则用作字符链表(队列)的头结点。莱昂在第23章中详细介绍了这两个

2013-08-02 12:28:14 3869

原创 (莱昂氏unix源代码分析导读-48) 字符设备

我们终于到达了本书的最后一章,它涉及的是慢速、面向字符外部设备的输入和输出。同块设备一样,unix v6使用一个“设备switch” struct来进行设备操控。

2013-07-15 12:42:34 3867

原创 (莱昂氏unix源代码分析导读-47) exec

by cszhao1980现在,我们已经储备了足够的知识,该吹响向EXEC sys call冲锋的号角了。exec是系统中最重要也是最复杂的系统调用之一,它的作用是执行指定的“可执行文件”。一般说来,exec与fork配合使用,fork生成一个新进程,而exec是新进程执行其应该执行的代码。 莱昂对exec有着比较详细的介绍,但很不幸,这些代码理解起来仍然困难重重。所以,我要在

2013-06-30 08:54:28 4941

原创 (莱昂氏unix源代码分析导读-46)权限、管道

by cszhao1980 1.    文件与权限控制进程u结构中,身份相关的信息有:0420: char u_uid; /* effective user id */0421: char u_gid; /* effective group id */0422: char u_ruid; /* real user id */0423: char u_rgid; /* rea

2013-06-15 21:10:21 3961

原创 (莱昂氏unix源代码分析导读-45) 文件与“资源”

by cszhao1980我们已经知道文件会占用很多资源,如磁盘inode资源、盘块资源,访问时还要占用inode数组资源,等等。 除此之外,unix v6还使用file数组来记录整个系统中被open开的文件,file数组的定义如下:5507: struct file5508: {5509:      char f_flag;5510:      char f_co

2013-05-29 19:33:28 4041

原创 (莱昂氏unix源代码分析导读-44) 文件系统资源

by cszhao1980一个设备被mount进系统后,就被称为一个文件系统。它有两类资源:(1)         磁盘inode资源;(2)         普通盘块资源。1. 磁盘inode资源对于inode资源,unix v6采用了一种很简单的管理方法。即在超级块中维护一个free inode资源数组(max 100 entry),存放可用的inode资源(inode

2013-05-05 08:20:34 3974

原创 (莱昂氏unix源代码分析导读-43) 文件系统的mount

By cszhao1980当一个设备被mount进系统,就会在“mount表”中占据一个表项,mount表的定义如下:0272: struct mount0273: {0274:     int m_dev     /* device mounted */0275:     int *m_bufp;   /* pointer to superblock */0276:

2013-04-02 09:13:05 3800

原创 (莱昂氏unix源代码分析导读-42) 硬链接

by cszhao1980熟悉unix/linux的同学都听说过硬链接的概念,老实说,在阅读源码之前,对硬链接的理解总是模模糊糊的。现在,我们已经了解了inode、目录,是时候对硬链接有个清楚的了解了。 我们知道,新建一个文件时,需要申请很多资源,如:(1)申请磁盘盘块用于写文件的内容;(2)申请inode资源,存放文件inode;(3)在父目录文件中添加一目录项,

2013-03-25 11:15:27 4087

原创 (莱昂氏unix源代码分析导读-41)文件系统树状结构的形成

By cszhao1980我们现在对inode有了一定的了解,正如前面所说,inode记录的信息比较靠近文件的物理存储。那末,文件系统的树状结构是如何实现的呢? 答案就是“目录”。首先需要强调的是,目录也是一种文件,它也拥有与普通文件相同的inode结构。所不同的是其文件内容——逻辑上,我们可以把目录文件的内容看作一个“目录项数组”,它由若干“目录项”构成,一个目录

2013-02-25 12:11:17 4466

原创 (莱昂氏unix源代码分析导读-40)inode“指向文件的内容”的读写

by cszhao1980前面已经说过,inode指向文件的内容是通过i_addr[]数组来组织和记录的。本章讨论一下文件内容的读写。在进行文件读写时,使用了进程u空间的若干变量,先介绍如下:        0418:      char u_segflg;       /* flag for IO; user or kernel space */0425:

2013-01-18 13:33:08 3856

原创 (莱昂氏unix源代码分析导读-39)inode“资源”的获取和释放

by cszhao1980iget()函数用于获取inode资源,它有2个参数,设备号和inode id。前面说过,通过这两个参数会唯一确定一个inode。简单的说,该函数的作用就是将指定的磁盘inode读入内存inode数组,并Lock该项(即会设置 ILOCK flag),它返回一个指向该inode数组项的指针。 事实上,iget()做的更多一些,它首先检查内存inod

2012-12-26 12:55:18 4172

原创 (莱昂氏unix源代码分析导读-38)文件物理存放位置与inode

by cszhao1980文件的物理位置指文件存放:(1)哪个设备;(2)该设备的哪些块。 Inode使用i_addr[8]数组来记录文件的物理块号:(1)对“小文件”(占用的块数块),i_addr数组内直接存放文件占用的物理块号;     如文件占用6块,则使用i_addr[0] ~ i_addr[5]存放这6个块号 (2)当文件占用的块数超过8块(此时,

2012-12-18 12:32:18 4504

原创 (莱昂氏unix源代码分析导读-37) 文件系统与inode

by cszhao1980前面所讲的各项内容,进程管理也好,中断处理也罢,都静静的工作在幕后,普通用户甚至根本感觉不到他们的存在。但文件系统不同,它工作在前台,用户或多或少都有一定的感性及理性认识——这给我们的读码带来了巨大的好处。在这里我假设大家对unix文件管理有一定的认识,比如,知道文件系统的树状层次结构,知道文件的访问控制,知道绝对路径与相对路径,知道如何将一个

2012-12-10 12:34:00 4427

原创 (莱昂氏unix源代码分析导读-36) 缓存管理(下)

by cszhao1980理解了上述内容,下面的这些程序就不难理解了。首先是函数brelse(buf bp),该函数将传入的缓存归还到AV队列中,函数采用尾插法,即缓存会插到AV队列的队尾——这样做显然有助于提高“延迟写”技术的效率。莱昂特别指出,brelse没有清理B_DONE标志,这一点非常重要,读完本章后大家就会明白。 接下来是binit()函数,完成初始化:

2012-11-19 10:52:49 4125

原创 (莱昂氏unix源代码分析导读-35)缓存管理(上)

by cszhao1980系统定义了NBUF个缓存区域,每个514个字节:4720: char buffers[NBUF][514]; 【注】:514个字节稍稍大于一个物理盘块的size,多出的2个byte的用途不明。 而“缓存头”数组buf[NBUF]的每个entry对应一个缓存区域,其b_addr被设置为对应的缓存区的首地址,如:&buffers[1]。对于缓存的使

2012-11-12 12:57:39 4171

原创 (莱昂氏unix源代码分析导读-34)You are not expected to understand this

By cszhao1980本章将探讨unix v6代码中最微妙的部分,即著名的注释:“ You are not expected to understand this”。 2178: swtch()2179: {2180:     static struct proc *p;2181:     register i, n;2182:     register struc

2012-10-31 13:22:51 7588

原创 (莱昂氏unix源代码分析导读-33) swap函数

By cszhao1980是了解swap函数的时候了,它有四个参数:(1)blkno:磁盘块号;(2)coreaddr:物理内存block号;(3)count:读写字节数;(4)rdflg:读写标志。 swap函数尽力使用device independent的方法来实现功能:(1)它通过swapdev在块设备表中查表来操控swap设备;(2)启动设备时,通过块设

2012-10-15 11:43:02 3960

原创 进(线)程同步原语

<!--p {margin-bottom:0.08in}-->                                                                                      现代操作系统的核心任务之一就是实现进线程的并发,因此必须采用一定的方法来消除进线程间的“竞态条件”(racecondition),

2012-09-26 11:50:22 4667

原创 (莱昂氏unix源代码分析导读-32) RK磁盘驱动

by cszhao1980别紧张,RK磁盘是一种非常简单设备——这一点从其代码量中也可以看出。首先,它由一个控制器外加 1~8个devices组成,这8个devices编号为0~7,缓冲头的b_dev的minor号记录的就是该device编号,为简单起见,我们不考虑多于8个device的情况——对RK磁盘来说,b_dev的minor部分就是0~7,而major部分为0。

2012-09-24 11:48:34 2904

原创 Linux线程模型概述

By cszhao19801. 轻量进程(LWP)我们知道进程拥有大量资源,如:(1)寄存器信息,如pc等;(2)Data段(3)Stack;(4)正文段(可与其他进程共享);(5)open 的file;(6)信号;(7)etc。 在进行context switch时,os必须妥善的保存进程的各种资源,开销较大,故进程有也被称为重量进程(HWP)。传统的

2012-09-21 11:07:59 5138

原创 (莱昂氏unix源代码分析导读-31) “缓存头”初探

By cszhao1980struct buf结构,又被称为“缓存头”结构,而buf[NBUF]数组被称为“缓存头”数组。顾名思义,“缓存头”结构应该是用于缓存处理的,事实上,它确实有这个功能——“缓存头”数组的每个entry可与系统的一个缓存区域对应,用于操控一个缓存区域。 4520: struct buf4521: {4522:     int b_flags;

2012-09-17 15:05:59 2514

原创 (莱昂氏unix源代码分析导读-30) device

By cszhao1980我们现在必须放下身段看一看低层的IO操作了,复杂繁琐的外设。 PDP-11/40拥有两种外设:(1)         Block device (2)         Character device 简单说来,Block device以block来单位操作数据,而character device则以character为单位操作数据。我

2012-09-10 12:23:25 2640

原创 (莱昂氏unix源代码分析导读-29) swap in/out (下)

by cszhao1980最后,看一下我们的老朋友sched(),上次看到它还是在系统初启时,#0进程在sched()函数中调用sleep(&runout ,…)睡眠,从而让出cpu,切换至#1进程。 sched()函数是个黑洞,它内部是个死循环,永远也不会退出(除非出错)。也就是说#0进程将陷入在sched()中,而sched()用来进行调度,自此#0进程就蜕变为调度

2012-09-03 11:48:42 4003

原创 (莱昂氏unix源代码分析导读-28) swap in/out (中)

by cszhao1980换出时,使用函数xswap(),它有三个参数,前两个参数很容易理解:(1)p——指向进程表项;(2)ff—— free flag,如非0,则free core空间; 但第三个参数就难以琢磨了:(3)os—— old size。是什么意思呢?既然p->p_size记录了进程swap image的size,这个os又是作什么用的。为了理解这

2012-08-27 12:28:36 2726

原创 (莱昂氏unix源代码分析导读-27) Swap in/out (上)

By   cszhao1980Swap in/out指的是进程在物理内存(core空间)和磁盘交换文件间的双向移动过程,进程在active状态时,其segment必然被swap in内存空间(core空间),而一旦处于非活动状态就有可能被swap out到磁盘交换文件中。换进换出的过程必然涉及到磁盘io——这可看作是比较低层的操作,因此,这部分内容可以分为两部分:高层的模型

2012-08-20 12:06:29 3197

原创 (莱昂氏unix源代码分析导读-26) trace

by:cszhao1980trace是unix提供的一种是父进程可以跟踪子进程进展的手段,子进程被跟踪时,当子进程收到signal后,会进入“暂停(SSTOP)”状态,使父进程有机会进行干预。子进程的暂停是在issig()函数中实现的: 3997:    if(n = p->p_sig) {3998:       if (p->p_flag&STRC) {   /进程处

2012-08-14 12:03:43 2411

原创 (莱昂氏unix源代码分析导读-25) signal(下)

By cszhao1980下面来看一下信号的处理过程。首先,进程需要不时的检查自己是否收到signal,此时需要调用issig()函数,该函数会返回进程此时收到的signal的signal type(如果没有signal,或忽略此signal,则返回0):3991: issig()3992: {3993:    register n;3994:    registe

2012-08-06 12:02:49 2612 1

原创 (莱昂氏unix源代码分析导读-24)signal(上)

by cszhao1980signal更确切的称呼应该是soft interruption,顾名思义,就是一种能够通过软件手段达到类似interruption目的的方法。 Unix最多支持NSIG(20)种软中断,进程的u中有u.signal[NSIG]数组,记录每种软中断的处理方法。u_signal〔n〕的值当#n中断发生时

2012-07-30 12:54:12 2570

原创 (莱昂氏unix源代码分析导读-23) 若干系统调用的实现

By cszhao1980                                                                                                 System call是提供给user进程的接口,使其可以主动进入内核,完成一些特殊的操作。 多数的sys call的实现很简单,莱昂留给大家分析,我在这里多说

2012-07-23 12:02:01 2940

原创 (莱昂氏unix源代码分析导读-22) trap函数(2693)

莱昂的分析比较清晰。在这里我只说明几个容易让人感到迷惑的问题。 首先是trap函数的长长的参数列表,同clock函数一样,这些参数来自于入口处的设置,回头看一下栈图,这些参数的容易理解了。 函数开头就检查进程的“前状态”——绝大多数情况下,应该是user态。核态的陷入在大多数情况下都是一个错误,会引起panic的调用,导致系统down掉。 在“2701: u.u_a

2012-07-16 11:58:51 3096

转载 linux下tty,控制台,虚拟终端,串口,console(控制台终端)详解

首先:1。终端和控制台都不是个人电脑的概念,而是多人共用的小型中型大型计算机上的概念。一台主机,连很多终端,终端为主机提供了人机接口,每个人都通过终端使用主机的资源.。终端有字符哑终端和图形终端两种. 控制台是另一种人机接口,,不通过终端与主机相连,,而是通过显示卡-显示器和键盘接口分别与主机相连,这是人控制主机的第一人机接口。 回到个人计算机上,个人计算机只有

2012-07-04 10:33:55 3702

原创 (莱昂氏unix源代码分析导读-21)时钟中断处理

时钟中断是系统中最重要的中断,每个时钟滴答都会产生时钟中断,它的中断矢量为(0100)或(0103)。 0533: . = 100^.0534:       kwlp; br60535:       kwlp; br6 0569: .globl  _clock0570: kwlp:  jsr r0,call; _clock 显然,时钟中断会通过call例程调用_

2012-07-02 12:00:18 10824 5

原创 (莱昂氏unix源代码分析导读-20)中断、陷入的入口和出口

陷入处理程序的入口都为“trap”(这里是指一个汇编程序,而非PDP11指令);中断则不同。他们有不同的入口,如:525     .=60^.                       当前地址设置为60 octal526     klin; br4                      /(中断矢量地址为60,电传打字机输入的中断处理程序)527     klou; br4

2012-06-25 12:10:30 3658 1

原创 (莱昂氏unix源代码分析导读-19)再谈进程swtch

我们已经涉及到了部分进程切换的概念,在本章中,我们会从更一般的意义上考察进程切换的行为。首先,进程切换(也称作context switch)一定是在内核中完成的。比如,以下为发生进程切换的最常见的情况:(1)    active进程因等待某资源阻塞,自动让出cpu;(2) 进程时间片用完; 情况1中,进程会通过系统调用进入内核,在内核态让出cpu;而情况2的检查是在

2012-06-18 12:02:24 4872

原创 (莱昂氏unix源代码分析导读-18) 再谈中断与陷入

从产生原因看,中断和陷入也有巨大的差别。 硬件中断由外部事件造成,属于异步事件,往往与当前进程毫无关系;陷入则不同,它常常都是同步的(如除0错),并与当前进程上下文相关。 除此之外,陷入还用来实现系统调用——内核为user进程提供了大量的服务,这些服务就是通过系统调用来访问的。PDP11提供了trap指令来使user进程进入内核,进行系统调用。 由于系统调用的存在,

2012-06-11 12:00:03 4146

原创 (莱昂氏unix源代码分析导读-17)系统初启(10)

小结本章的内容到此结束。由于我们跳过了一些专题,启动代码中仍有一些未解之谜,但它的神秘面纱已经揭开,这是一个好的开始。 最后,给出fuibyte(0)的分析结果:0814 _fuibyte: 0815 _fubyte:0816 mov 2(sp),r1            /参数(输入地址)--->r10817 bic $1,r1

2012-06-05 11:59:51 3843

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

回到start 现在,继续#1进程之旅。main()1627 if(newproc()) {                        1628      expand(USIZE+1);                          /调整进程“私有空间”大小,暂不考虑换出情况的话程序/较简单,读者自行分析1629      estabur(0, 1, 0,

2012-06-04 12:02:44 3859

原创 (莱昂氏unix源代码分析导读-15) 系统初启(8)

进程user态下的分段 User态中将进程空间分为text、data、stack segment三部分。 estabur(nt, nd, ns,sep)根据各个segment的大小,为各段分配page,参数如下:(1) nt—— text segment的长度(block)(2) nd—— data segment的长度(block)(3) ns—— stack seg

2012-06-01 12:05:28 4037

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除