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

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 前者确实很简单,后者涉及到的东西太多,所以暂时第八章就这样了














  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值