有关0.11版本内核的解释,在看赵炯的0.11版本系统内核讲解书籍时,main中调用了诸如fork() write()等库函数,再看系统调用时,只有例如open函数有这样的定义
- #define __LIBRARY__
- #include <unistd.h>
- #include <stdarg.h>
- int open(const char * filename, int flag, ...)
- {
- register int res;
- va_list arg;
- va_start(arg,flag);
- __asm__("int $0x80"
- :"=a" (res)
- :"0" (__NR_open),"b" (filename),"c" (flag),
- "d" (va_arg(arg,int)));
- if (res>=0)
- return res;
- errno = -res;
- return -1;
- }
而其他函数例如read只在unistd.h有一个声明,而之后的system_call.s中调用sys_call_table中全部都是sys_xxxx这样格式的函数,来自unistd.h有定义_syscall这个宏,在这个宏中也调用了int 0x80这个软件中断,具体的调用如下,这个版本的宏只到3.
- #define _syscall3(type,name,atype,a,btype,b,ctype,c) \
- type name(atype a,btype b,ctype c) \
- { \
- long __res; \
- __asm__ volatile ("int $0x80" \
- : "=a" (__res) \
- : "0" (__NR_##name),"b" ((long)(a)),"c" ((long)(b)),"d" ((long)(c))); \
- if (__res>=0) \
- return (type) __res; \
- errno=-__res; \
- return -1; \
- }
同样也是使用int 0x80来实现
idt表和相关的中断处理函数在主函数的初始化程序中进行了关联
在0.11中,系统调用中断服务函数system_call和时间中断函数timer_interrupt与idt的关联都在sched_init中实现,不知道为什么
中断处理程序在system_call.s汇编中实现,在0.11中sys_fork也是在这个文件中实现
这样我就搞不懂fork()这样的函数是怎样和int 0x80软件中断相联系从而调用sys_call_table中的sys_fork这样的系统调用
度娘说在GNU lib c中实现,于是在上面下载到了0.12版本的glibc,从unistd文件夹中找到了这些函数的实现
例如fcntl函数的实现
- #define __LIBRARY__
- #include <unistd.h>
- #include <stdarg.h>
- int fcntl(int fildes, int cmd, ...)
- {
- register int res;
- va_list arg;
- va_start(arg,cmd);
- __asm__("int $0x80"
- :"=a" (res)
- :"0" (__NR_fcntl),"b" (fildes),"c" (cmd),
- "d" (va_arg(arg,int)));
- if (res>=0)
- return res;
- errno = -res;
- return -1;
- }
同样还有read/write函数的实现
- #define __LIBRARY__
- #include <unistd.h>
- _syscall3(int,read,int,fd,char *,buf,off_t,count)
这个宏会定义一个int read()有三个参数的函数,从而实现read()与sys_read的关联,后面的流程在内核源码中实现
阅读(3347) | 评论(0) | 转发(1) |