文档详情

Linux内核分析与高级编程.ppt

发布:2017-06-17约9.83千字共48页下载文档
文本预览下载声明
页表项 31 0 12 11 其它控制位 禁止缓存位 访问位 保护位 修改位 存在位 1=只读 0=读写 页内编移量 查表最终得到 页帧号 + 页帧号  页内偏移量 页帧号 1=存在 0=不存在 物理地址送地址线 MMU在页表的支持下完成 地址映射和虚实转换 线性地址32位 10 位 10位 12位 0 1 1 1 0 1 0 虚存空间页存在位 2 0 1 3 … … 虚拟空间页 … … 0-4k 5-8k 9-12k 13-16k 17-20k 21-24k 61-64k 64k 虚存 1 2 3 7页帧 0页帧 32k 物理内存 0-4k 9-12k 13-16k 29-32k 某时刻的虚实映射 5-8k … 虚实地址映射 0页面 1 2 3 4 5 6 … 15 入口地址高16位 D DPL ODXXX 000 8765 0 段选择码 入口地址低16位 中断门、陷入门及调用门的基本格式定义 31 0 31 用户进程调用系统调用getuid ( ) 执行宏调用_syscall0(int,getuid) 即: 调用getuid() 产生陷入异常(模式切换到进入内核) traps.c 内核初始化时trap_init( ) 建立了调用门 执行系统调用处理函数system_call( ) 保护现场,由系统调用号(24)查系统调用表(sys_call_table) 找到该系统调用的内核处理函数(sys_getuid16( )) 调用sys_getuid16( ) 返回uid, uid →eax,并压入堆栈 执行ret_from_sys_call ( ) 恢复现场,并从堆栈获得(uid)→eax eax →_ _res , uid返回给用户程序 系统调用结束 将系统调用号(_ _NR_getuid=(24)) 送 (eax) ,并执行int $0x80 unistd.h entry.S getuid()函数中的 return _ _res int main ( ) { int uid; ┆ uid=getuid ( ); ┆ printf (“┄”); } int getuid (void) { long _ _res; ┆ movl 调用号,%eax int $0x80; movl %eax,_ _res ┆ return _ _res; } ENTRY (system_call) pushl %eax SAVE_ALL ┆ call sys_getuid 16 (void) ┆ RESTORE_ALL ┆    asmlinkage long \ sys_getuid16 (void) { return 用户UID; } 用户程序 标准C库(系统调用) 系统调用处理函数 内核处理函数 系统调用实现中各程序间的关系示意图 1 0 读锁 SN_READ 写锁 SN_WRITE 0 1 信号量数组(初始状态) 使用信号量(semaphore) 实现读进程\写进程互斥访问共享内存的方法: 1 0 (-1) LOCK 读锁 写进程获取IPC资源 0 0 写共享内存 (+1) UNLOCK 写锁 释放IPC资源 0 1 0 1 (-1) LOCK 写锁 读进程获取IPC资源 0 0 读共享内存 (+1) UNLOCK 读锁 释放IPC资源 1 0 读进程、写进程互斥访问共享内存的流程: 写进程进入临界区 写数据 先写满管道可用空间 唤醒等待的读进程 管道空间=所需空间? N 退出临界区 唤醒读进程 写数据量很大? Y Y Y 阻塞式写操作? 写进程进入等待队列 读进程读数据 N N 写进程写管道的规则和流程 #include stdio.h #include stdlib.h void main() { char str[10]; pid_t pid; pid=fork(); if(pid0) { printf(daemon on duty now!\n); exit(0); } for(; ;) { printf(I am the daemon!\n);
显示全部
相似文档