您的位置:首页 > 运维架构 > Linux

《linux 内核完全剖析》 chapter 8 内核代码

2014-05-08 20:45 369 查看

chapter 8 内核代码



8.1.1中断处理程序

traps.c

#define get_seg_byte(seg,addr) ({ \ //取seg中addr处1byte
register char __res; \
__asm__("push %%fs;mov %%ax,%%fs;movb %%fs:%2,%%al;pop %%fs" \
:"=a" (__res):"0" (seg),"m" (*(addr))); \
__res;})

#define get_seg_long(seg,addr) ({ \ //取seg中addr处4字节
register unsigned long __res; \
__asm__("push %%fs;mov %%ax,%%fs;movl %%fs:%2,%%eax;pop %%fs" \
:"=a" (__res):"0" (seg),"m" (*(addr))); \
__res;})

#define _fs() ({ \ //取fs段的内容,段选择符
register unsigned short __res; \
__asm__("mov %%fs,%%ax":"=a" (__res):); \
__res;})

static void die(char * str,long esp_ptr,long nr)
{
long * esp = (long *) esp_ptr;
int i;

printk("%s: %04x\n\r",str,nr&0xffff);
printk("EIP:\t%04x:%p\nEFLAGS:\t%p\nESP:\t%04x:%p\n",
esp[1],esp[0],esp[2],esp[4],esp[3]); //打印栈的相关信息
printk("fs: %04x\n",_fs()); //段选择符
printk("base: %p, limit: %p\n",get_base(current->ldt[1]),get_limit(0x17)); //基地址,段限长
if (esp[4] == 0x17) { //esp[4]是ss(堆栈段寄存器)的值,0x17是用户栈
printk("Stack: ");
for (i=0;i<4;i++)
printk("%p ",get_seg_long(0x17,i+(long *)esp[3]));
printk("\n");
}
str(i); //这里是个sched.h里面的宏定义,但是又有相同的名字参数传进来,会不会有歧义?
printk("Pid: %d, process nr: %d\n\r",current->pid,0xffff & i);
for(i=0;i<10;i++)
printk("%02x ",0xff & get_seg_byte(esp[1],(i+(char *)esp[0])));
printk("\n\r");
do_exit(11); //释放当前进程所占用的资源,结束进程        /* play segment exception */
}


void do_double_fault(long esp, long error_code) //都是调用die
{
die("double fault",esp,error_code);
}

void do_general_protection(long esp, long error_code)
{
die("general protection",esp,error_code);
}

void do_alignment_check(long esp, long error_code)
{
die("alignment check",esp,error_code);
}

void do_divide_error(long esp, long error_code)
{
die("divide error",esp,error_code);
}

void do_nmi(long esp, long error_code)
{
die("nmi",esp,error_code);
}

void do_debug(long esp, long error_code)
{
die("debug",esp,error_code);
}

void do_overflow(long esp, long error_code)
{
die("overflow",esp,error_code);
}

void do_bounds(long esp, long error_code)
{
die("bounds",esp,error_code);
}

void do_invalid_op(long esp, long error_code)
{
die("invalid operand",esp,error_code);
}

void do_device_not_available(long esp, long error_code)
{
die("device not available",esp,error_code);
}

void do_coprocessor_segment_overrun(long esp, long error_code)
{
die("coprocessor segment overrun",esp,error_code);
}

void do_invalid_TSS(long esp,long error_code)
{
die("invalid TSS",esp,error_code);
}

void do_segment_not_present(long esp,long error_code)
{
die("segment not present",esp,error_code);
}

void do_stack_segment(long esp,long error_code)
{
die("stack segment",esp,error_code);
}

void do_coprocessor_error(long esp, long error_code)
{
if (last_task_used_math != current)
return;
die("coprocessor error",esp,error_code);
}

void do_reserved(long esp, long error_code)
{
die("reserved (15,17-47) error",esp,error_code);
}


sys_call.s

我唯一目前有兴趣的就是这家伙 fork系统调用

.align 2
_sys_fork:
call _find_empty_process//首先调用find_empty_process,找出可用的pid数字
testl %eax,%eax
js 1f
push %gs
pushl %esi
pushl %edi
pushl %ebp
pushl %eax //压入各种寄存器
call _copy_process //接着调用_copy_process
addl $20,%esp
1:    ret
我才知道,这个就是fork的实现!

8.5 mktime.c

mktime.c 学习笔记

8.6 sched.c

sched.c 学习笔记

8.7 signal.c

signal.c 学习笔记

8.8 exit.c

exit.c 学习笔记

8.9 fork.c

fork.c 学习笔记

8.10 sys.c

sys.c 学习笔记

8.11 vsprintf.c

vsprintf.c 学习笔记

 免掉了printk.c 和panic.c 前者确实很简单,后者涉及到的东西太多,所以暂时第八章就这样了

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: