📄 linux.txt
字号:
代码重定位部分:含供连接程序使用的记录数据,在连接时用于定位代码段中的指针和地址。
数据重定位部分:同上。
符号表部分:含供连接程序使用的记录数据,用于在各模块文件间对变量和函数(符号)进行交叉引用。
字符串表部分:含有与符号名相对应的字符串(描述信息)。用于调试。
可重定位项为一条记录,其中记录着代码中某条寻址指令的目的地址值所在的地址,连接时只需直接修改该可重定位项所指向的位置处的地址即可。
符号表中的符号值是该符号所表示的变量的值在代码中的地址。
连接程序:首先将各模块中相同的段组合在一起,并将所有具有非0值的未解析的外部符号作为公共块来看待。随后进行符号的绑定和代码修改并进行存储空间分配。
make命令:编译内核(以makefile文件为编译过程中的批处理文件),只要在含有makefile文件的目录下运行make命令内核就会进行编译。具体而言,将bootsect.s和setup.s使用8086汇编器进行编译,将其它程序使用GNU的gcc/gas编译器进行编译,最后将各部分合并成一个内核映象文件image。build.c是一个辅助内核编译的工具不包含在内核中。
system.map中存放了符号表:符号地址 类型 符号名
8.内存管理(页表项结构p553)
linux0.11中,页目录表是系统所有进程公用的,而内核中的4页页表(即紧跟在页目录后)则是内核专用,对于新建的进程,系统会在主内存区为其申请页面来存放页表。
引起页出错中断(int 14)的几个原因:
1.地址变换过程中用到的页目录项或页表项中存在位(p)等于0(需时加载do_no_pape);
2.当前执行程序没有足够的特权访问指定的页面(写时复制do_wp_page)。
当访问某一页时,cpu会“自动(非程序,而是CPU体系结构自动执行的)”置位该页所对应页表项的“已修改位”和“已访问位”;但是这些位不会自动复位,需要程序来手动操作(注:页目录项的“已修改位”无用)。
当发生页出错中断时cpu会“自动(非程序,而是CPU体系结构自动执行的)”向页出错异常处理程序提供以下两方面信息:
1.栈中的一个出错码(有32位,但只有最低3个比特有效,具体含义见p555);
2.cr2中存放的引起出错的地址。
页出错中断处理程序根据上述信息决定调用的具体操作:
1.do_no_pape却页异常:首先判断却页原因是否是由于申请新堆栈页引起的(即缺页地址在进程代码数据段范围之外),若是,则直接分配新页并映射该页。若不是则说明缺页发生在执行文件范围内(代码数据段范围内,即欲执行的代码数据还在文件中尚未加载进内存)此时,先尝试页面共享(即若有其它进程执行相同的文件,则尝试同其它进程共享该文件代码),若失败则申请一页并从设备上读入相应的数据且复制到新页中,然后将新页映射到进程线性地址中。
2.do_wp_page写保护函数:首先若欲写入地址在进程的代码段中,则中止进程,否则调用un_wp_page(若欲写入的页面非共享,则直接将对应该页的页表项设为可写;若欲写入的页面为共享,则新申请一页面,并将原页内容复制进来,然后使页表项指向该新页即可)。
mem_map[]字节数组,每个字节描述一个"物理内存页"的占用状况,其中的数值表示引用次数,0表示空闲。该数组从1mb开始。初始时该数组中对应于主内存区的项被清0,对应于缓冲区的项被置为100(已占用)p558
重新加载页目录表地址(cr3)即可起到刷新页变换高速缓冲器的作用。变换高速缓冲器会将最近使用的页表项保存下来以提高速度,但若程序将某一在缓冲器中有拷贝的页表项更改了之后,需手动的重刷缓冲器。
创建新进程时会执行copy_page_tables:将父进程的页表复制给子进程,具体如下:
页表的复制:在主内存中申请一新页,然后将原页表内容复制过来;
页目录项的复制:在页目录表中新建一项,使其指向上面分配的页表;
设置:将原页表项和目的页表项都设为只读;
mem_map:将相应的物理页引用计数加1(mem_map中相应项的值加1)。
(注:对于进程0而言只完成上述的1,2步。原因是一方面进程0和进程1虽然共享同一代码,但它们执行该代码的不同区域所以不会出现冲突;另一方面,mem_map管是low_mem以上的内存,而进程0和进程1的代码数据在low_mem以下。)
页表不存在于一般进程的空间中,而存在于进程0的空间中(0-64mb),即页表是独立于进程的。
给出一个线性地址,CPU通过页机制将其转换为物理地的这一过程中,查询页表的寻址操作将不使用页机制。
9。c语言函数调用机制(p129--p133)
函数调用返回时由调用者自动丢弃堆栈上的参数。
int abc(int a)以此为例,abc本身也是一个地址和一般的变量类似。故函数指针和一般的变量指针也类似。
10.中断;异常;系统调用
异常:打印出一些信息并中止程序
系统调用:相应的功能调用
中断:相应的功能调用
在某一用户态中发生上述情况中的一种时:首先CPU“自动”将SS:ESP堆栈寄存器,SFLAGS,CS:EIP指令寄存器压入堆栈,然后在中断向量表中找到相应的处理程序的入口地址,然后“自动”加载内核的CS及SS(CS寄存器在发生任何远跳转时会自动重加载)。然后手动加载内核的DS,ES。
内核态中的进程能接受中断,但不能接受进程调度。
**p:当一个程序调用另一个程序时,若参数为int i则被调用函数不能修改i的值;若参数为int *i则被调用函数可修改i的值(但不能修改i指针的值);若参数为int **i则被调用函数可些改i的值且可修改i指针的值。
11.信号处理
在进程每次调用系统调用或发生时钟中断时,若进程已收到信号,则信号预处理程序会将用户自定义的信号处理程序置为iret的返回地址(即进程处理完系统调用或时钟中断后,返回到用户态时,将直接返回到自定义的信号处理程序处),随后通过一个函数指针(参数restorer)跳转到善后程序(在编译连接时由libc函数库提供,非内核程序,用于将信号处理程序;的返回地址及
返回的上下文设为用户进程刚执行系统调时的上下文)。
在将字符从用户缓冲区写入字符设备辅助缓冲队列(或反之)时,如遇到有待处理信号则直接退出读写函数,返回读写出错标志。
12.硬盘(p280图)
hd_infor结构:存放硬盘信息,该信息来源于cmos供16季节,包括(柱面数,磁头数,写前预补偿柱面号,控制字节,磁头着陆区柱面号,每磁道扇区数)
hd结构:存放硬盘分区表信息,该信息来原于硬盘引导扇区446字节处的硬盘分区表(见p278),包括:(起始扇区,长度)
do_hd_request:第一次运行时,直接向硬盘控制器发出相应的命令,随后返回。过一会当硬盘控制器执行完命令后会发出一个中断(向硬盘控制器发命令时将会设置与该命令对应的中断处理程序),中断处理程序会出现3个分支:分支1出错(此时进一步判断出错的次数,较少则调用do_hd_request重发命令,较多则调用do_hd_request发送复位硬盘。命令(硬盘执行该命令后也会产生中断,并执行相应的处理程序),太多则废弃该请求项并退出;分支2正确但未完(缓冲区指针后移,并退出中断处理程序,等待下一个中断的到来);分支3正确且完成(唤醒等待进程,并开始执行下一个请求项)。
引导扇区结构:p278
缓冲区:缓冲区中的一块与硬盘中的一块向对应,当进行硬盘读写操作时若预读写的硬盘块在缓冲区中有对应的块,则直接对缓冲区读写。
一次成功的读写硬盘操作后该缓冲块的uptodate标志将置1,此时再对该缓冲块所对应的硬盘块进行读操作时,将直接从缓冲块中去读取。
13.键盘
8042键盘控制芯片(p345)
每当键盘按下时会发送一个扫描码(1<<7+按键的码);释放时也会发送一个扫描码(0<<7+按键的码)
当用户按下一个按键时:首先键盘向键盘控制器发送该键的扫描码,然后当键盘控制器收到扫描码后向8259A发键盘中断,然后调有键盘处理程序,然后当键盘处理程序处理完毕后重置键盘(先关再开),并向8259A发EOI结束本次中断。
键盘处理程序:根据扫描码直接调用相应的子程序(对于一般按键则直接将其转换为字符并存入缓冲队列;对于像ctrl,shift,alt这种控制键则仅仅将标志字段中的相应位置位;对于像F1,F2这种功能键则将其转化为相应的字符序列并存入缓冲队列中),然后将读缓冲队列中的数据进行格式转换,并存放到辅助队列中。
14.显示
控制台方式下欲在屏幕上显示字符:首先将欲显示的字符存入设备的写缓冲队列write_q中,然后将写缓冲队列中的字符经过转换后(如回车字符转换为一行空格)写入显存。对于控制台而言显示的实质其实就是将欲显示的字符放入显存中(显存可看成是一个逻辑上的屏幕),然后显示控制器会自动的从显存中读出数据并显示到屏幕上,欲修改屏幕上的内容只需直接修改相应显存中的内容即可
15.终端(p327)
字符设备文件的i_zone[0]中存放着该设备的设备号,其对应于tty_table[]数组中的索引号(tty_table[]中的每一项为一个tty_struct),即一个设备字符文件对应于一个tty_struct对应一个设备。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -