⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 1128.html

📁 著名的linux英雄站点的文档打包
💻 HTML
📖 第 1 页 / 共 3 页
字号:
                    <TBODY>
                    <TR>
                        <TD vAlign=top width="80%"> 
                          <DIV align=center>
                        <FORM action="search.html" tppabs="http://www.linuxhero.com/docs/search.html" method=get>
                            </FORM>
                        <TABLE cellSpacing=0 cellPadding=0 width="95%" 
                          border=0><TBODY>
                          <TR>
                            <TD background="images/bgi.gif" tppabs="http://www.linuxhero.com/docs/images/bgi.gif" 
                          height=30></TD></TR></TBODY></TABLE>
                        <TABLE cellSpacing=0 cellPadding=3 width="95%" 
                        align=center border=0>
                          <TBODY>
                          <TR>
                            <TD>
                              <TABLE cellSpacing=0 cellPadding=3 width="100%" 
                              border=0>
                                <TBODY>
                                <TR>
                                      <TD vAlign=top> 
<p><FONT class=normalfont><B><font color=blue>linux内核分析---系统调用实现代码分析</font></B></FONT><BR><FONT class=smallfont color=#ff9900>2004-04-23 15:18 pm</FONT><BR><FONT class=normalfont>作者:e4gle<e4gle@netguard.com.cn><br>来自:Linux知识宝库<br>联系方式:无名<br><br>2001年6月5日<br>
启动早就读完,现在为了写笔记再从启动之后粗略的大体读一遍,基本就是几个大模块:启动和初始化,<br>
中断信号,进程及调度,内存管理,文件系统,网络,驱动和模块等,我主要也从这几块入手。由于启动<br>
部分在start_kernel之前牵涉到大量的x86体系相关的汇编知识,需要大量的时间,于是我跳过,先把握<br>
整个系统的大体脉络,然后做二次,三次分析。网络部分的分析,我会从4.4BSD-Lite的代码中分析。<br>
<br>
系统调用:<br>
<br>
先说一下系统调用,奇怪的很,所有的读核资料都没有把系统调用单独提出来说,我觉得还是比较重要的<br>
。用户和系统内核通信的关键的枢纽,不过分吧,呵呵。仔细研究一下它的机制,准备花三天时间,手头<br>
有些书和资料,帮助我理解。<br>
<br>
概念:(明晰一下基本概念)<br>
系统调用发生在用户进程,通过一些特殊的函数(如open)来请求内核提供服务,这时,用户进程挂起,<br>
内核验证用户请求,尝试之行,并把结果反馈给用户进程,接着用户进程重新启动。这些机制在一般的编<br>
程书里都有,我就是来通过源代码的实现来讨论这种机制。<br>
<br>
具体实现代码:arch/i386/kernel/entry.S(内核版本2.2.14)<br>
从entry.S的第171行,就是system_call开始,171-248行代码贴出来,分析以注释形式:<br>
<br>
ENTRY(system_call)     \所有系统调用的入口点,参数system_call是所希望激活的系统调用的数<br>
pushl %eax# 保存orig_eax,这个值就是希望系统调用数<br>
SAVE_ALL    <br>
/*SAVE_ALL宏定义如下:<br>
#define SAVE_ALL <br>
cld; <br>
pushl %es; <br>
pushl %ds; <br>
pushl %eax; <br>
pushl %ebp; <br>
pushl %edi; <br>
pushl %esi; <br>
pushl %edx; <br>
pushl %ecx; <br>
pushl %ebx; <br>
movl $(__KERNEL_DS),%edx; <br>
movl %dx,%ds; <br>
movl %dx,%es;<br>
  他的作用是先把所有寄存器的值压栈,然后在system_call返回之前使用RESTORE_ALL把栈从栈中弹出<br>
,在这其中system_call可以根据需要子去使用寄存器的值。任何它调用的c函数都可以从栈中查找到所希<br>
望的参数,因为SAVE_ALL已经把所有寄存器的值都压入栈中了 */<br>
--------------------------------------------------------------------------------------------<br>
GET_CURRENT(%ebx)     /*利用GET_CURRENT宏从ebx中取得当前任务指针,GET_CURRENT宏定义<br>
如下:  <br>
       #define GET_CURRENT(reg) <br>
movl %esp, reg; <br>
andl $-8192, reg;这段代码应该很好理解,把esp指移到reg变量,减去8129得到当前任务地址<br>
*/<br>
--------------------------------------------------------------------------------------------<br>
cmpl $(NR_syscalls),%eax   /*察看保存在eax中的系统调用数是否超过最大数(常数NR_syscalls代表系统调用的最大数)如果确实超过了,请看下面一句:jae badsys,程序则跳转到badsys<br>
。*/<br>
jae badsys<br>
testb $0x20,flags(%ebx)# PF_TRACESYS/*检查系统调用是否正在被跟踪*/<br>
jne tracesys    /*如果系统调用被跟踪,则程序跳转到tracesys*/<br>
call *SYMBOL_NAME(sys_call_table)(,%eax,4)/*调用系统函数*/<br>
/*SYMBOL_NAME宏不处理任何工作,只是简单的被文本参数(也就是系统调用名)所替换,所以可以忽略<br>
sys_call_table也定义在entry.S(373行)中,是一张由指向实现各种系统调用的内核函数的函数指针组<br>
成的表:<br>
       ENTRY(sys_call_table)<br>
.long SYMBOL_NAME(sys_ni_syscall)/* 0  -  old "setup()" system call*/<br>
.long SYMBOL_NAME(sys_exit)<br>
.long SYMBOL_NAME(sys_fork)<br>
.long SYMBOL_NAME(sys_read)<br>
.long SYMBOL_NAME(sys_write)<br>
.long SYMBOL_NAME(sys_open)/* 5 */<br>
.long SYMBOL_NAME(sys_close)<br>
.long SYMBOL_NAME(sys_waitpid)<br>
.long SYMBOL_NAME(sys_creat)<br>
.long SYMBOL_NAME(sys_link)<br>
.long SYMBOL_NAME(sys_unlink)/* 10 */<br>
.long SYMBOL_NAME(sys_execve)<br>
.long SYMBOL_NAME(sys_chdir)<br>
.long SYMBOL_NAME(sys_time)<br>
.long SYMBOL_NAME(sys_mknod)<br>
.long SYMBOL_NAME(sys_chmod)/* 15 */<br>
.long SYMBOL_NAME(sys_lchown)<br>
.long SYMBOL_NAME(sys_ni_syscall)/* old break syscall holder */<br>
.long SYMBOL_NAME(sys_stat)<br>
.long SYMBOL_NAME(sys_lseek)<br>
.long SYMBOL_NAME(sys_getpid)/* 20 */<br>
.long SYMBOL_NAME(sys_mount)<br>
.long SYMBOL_NAME(sys_oldumount)<br>
.long SYMBOL_NAME(sys_setuid)<br>
.long SYMBOL_NAME(sys_getuid)<br>
.long SYMBOL_NAME(sys_stime)/* 25 */<br>
.long SYMBOL_NAME(sys_ptrace)<br>
.long SYMBOL_NAME(sys_alarm)<br>
.long SYMBOL_NAME(sys_fstat)<br>
.long SYMBOL_NAME(sys_pause)<br>
.long SYMBOL_NAME(sys_utime)/* 30 */<br>
.long SYMBOL_NAME(sys_ni_syscall)/* old stty syscall holder */<br>
.long SYMBOL_NAME(sys_ni_syscall)/* old gtty syscall holder */<br>
.long SYMBOL_NAME(sys_access)<br>
.long SYMBOL_NAME(sys_nice)<br>
.long SYMBOL_NAME(sys_ni_syscall)/* 35 */ /* old ftime syscall holder */<br>
.long SYMBOL_NAME(sys_sync)<br>
.long SYMBOL_NAME(sys_kill)<br>
.long SYMBOL_NAME(sys_rename)<br>
.long SYMBOL_NAME(sys_mkdir)<br>
.long SYMBOL_NAME(sys_rmdir)/* 40 */<br>
.long SYMBOL_NAME(sys_dup)<br>
.long SYMBOL_NAME(sys_pipe)<br>
.long SYMBOL_NAME(sys_times)<br>
.long SYMBOL_NAME(sys_ni_syscall)/* old prof syscall holder */<br>
.long SYMBOL_NAME(sys_brk)/* 45 */<br>
.long SYMBOL_NAME(sys_setgid)<br>
.long SYMBOL_NAME(sys_getgid)<br>
.long SYMBOL_NAME(sys_signal)<br>
.long SYMBOL_NAME(sys_geteuid)<br>
.long SYMBOL_NAME(sys_getegid)/* 50 */<br>
.long SYMBOL_NAME(sys_acct)<br>
.long SYMBOL_NAME(sys_umount)/* recycled never used phys() */<br>
.long SYMBOL_NAME(sys_ni_syscall)/* old lock syscall holder */<br>
.long SYMBOL_NAME(sys_ioctl)<br>
.long SYMBOL_NAME(sys_fcntl)/* 55 */<br>
.long SYMBOL_NAME(sys_ni_syscall)/* old mpx syscall holder */<br>
.long SYMBOL_NAME(sys_setpgid)<br>
.long SYMBOL_NAME(sys_ni_syscall)/* old ulimit syscall holder */<br>
.long SYMBOL_NAME(sys_olduname)<br>
.long SYMBOL_NAME(sys_umask)/* 60 */<br>
.long SYMBOL_NAME(sys_chroot)<br>
.long SYMBOL_NAME(sys_ustat)<br>
.long SYMBOL_NAME(sys_dup2)<br>
.long SYMBOL_NAME(sys_getppid)<br>
.long SYMBOL_NAME(sys_getpgrp)/* 65 */<br>
.long SYMBOL_NAME(sys_setsid)<br>
.long SYMBOL_NAME(sys_sigaction)<br>
.long SYMBOL_NAME(sys_sgetmask)<br>
.long SYMBOL_NAME(sys_ssetmask)<br>
.long SYMBOL_NAME(sys_setreuid)/* 70 */<br>
.long SYMBOL_NAME(sys_setregid)<br>
.long SYMBOL_NAME(sys_sigsuspend)<br>
.long SYMBOL_NAME(sys_sigpending)<br>
.long SYMBOL_NAME(sys_sethostname)<br>
.long SYMBOL_NAME(sys_setrlimit)/* 75 */<br>
.long SYMBOL_NAME(sys_getrlimit)<br>
.long SYMBOL_NAME(sys_getrusage)<br>
.long SYMBOL_NAME(sys_gettimeofday)<br>
.long SYMBOL_NAME(sys_settimeofday)<br>
.long SYMBOL_NAME(sys_getgroups)/* 80 */<br>
.long SYMBOL_NAME(sys_setgroups)<br>
.long SYMBOL_NAME(old_select)<br>
.long SYMBOL_NAME(sys_symlink)<br>
.long SYMBOL_NAME(sys_lstat)<br>
.long SYMBOL_NAME(sys_readlink)/* 85 */<br>
.long SYMBOL_NAME(sys_uselib)<br>
.long SYMBOL_NAME(sys_swapon)<br>
.long SYMBOL_NAME(sys_reboot)<br>
.long SYMBOL_NAME(old_readdir)<br>
.long SYMBOL_NAME(old_mmap)/* 90 */<br>
.long SYMBOL_NAME(sys_munmap)<br>
.long SYMBOL_NAME(sys_truncate)<br>
.long SYMBOL_NAME(sys_ftruncate)<br>
.long SYMBOL_NAME(sys_fchmod)<br>
.long SYMBOL_NAME(sys_fchown)/* 95 */<br>
.long SYMBOL_NAME(sys_getpriority)<br>
.long SYMBOL_NAME(sys_setpriority)<br>
.long SYMBOL_NAME(sys_ni_syscall)/* old profil syscall holder */<br>
.long SYMBOL_NAME(sys_statfs)<br>
.long SYMBOL_NAME(sys_fstatfs)/* 100 */<br>
.long SYMBOL_NAME(sys_ioperm)<br>
.long SYMBOL_NAME(sys_socketcall)<br>
.long SYMBOL_NAME(sys_syslog)<br>
.long SYMBOL_NAME(sys_setitimer)<br>
.long SYMBOL_NAME(sys_getitimer)/* 105 */<br>
.long SYMBOL_NAME(sys_newstat)<br>
.long SYMBOL_NAME(sys_newlstat)<br>
.long SYMBOL_NAME(sys_newfstat)<br>
.long SYMBOL_NAME(sys_uname)<br>
.long SYMBOL_NAME(sys_iopl)/* 110 */<br>
.long SYMBOL_NAME(sys_vhangup)<br>
.long SYMBOL_NAME(sys_idle)<br>
.long SYMBOL_NAME(sys_vm86old)<br>
.long SYMBOL_NAME(sys_wait4)<br>
.long SYMBOL_NAME(sys_swapoff)/* 115 */<br>
.long SYMBOL_NAME(sys_sysinfo)<br>
.long SYMBOL_NAME(sys_ipc)<br>
.long SYMBOL_NAME(sys_fsync)<br>
.long SYMBOL_NAME(sys_sigreturn)<br>
.long SYMBOL_NAME(sys_clone)/* 120 */<br>
.long SYMBOL_NAME(sys_setdomainname)<br>
.long SYMBOL_NAME(sys_newuname)<br>
.long SYMBOL_NAME(sys_modify_ldt)<br>
.long SYMBOL_NAME(sys_adjtimex)<br>
.long SYMBOL_NAME(sys_mprotect)/* 125 */<br>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -