Chinaunix首页 | 论坛 | 博客
  • 博客访问: 63996
  • 博文数量: 10
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 143
  • 用 户 组: 普通用户
  • 注册时间: 2013-10-20 21:24
个人简介

学习是一种修行

文章分类

全部博文(10)

文章存档

2014年(2)

2013年(8)

我的朋友

分类: LINUX

2013-12-29 17:36:06

hd_init一共有四句
第一句:
blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
主要获取块设备操作函数地址,DEVICE_REQUEST其实是个调用宏,获取他的地址有什么用呢?获取了快设备操作函数地址,当要访问硬盘是,就可以直接使用该地址来访问块设备。
第二句:set_intr_gate(0x2E,&hd_interrupt);
这是一个中断初始化函数,用于指定中断服务例程。宏#define set_intr_gate(n,addr)    _set_gate(&idt[n],14,0,addr)
函数实体:
#define _set_gate(gate_addr,type,dpl,addr) \
__asm__ ("movw %%dx,%%ax\n\t" \
        "movw %0,%%dx\n\t" \
        "movl %%eax,%1\n\t" \
        "movl %%edx,%2" \
        : \     
        : "i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
        "o" (*((char *) (gate_addr))), \
        "o" (*(4+(char *) (gate_addr))), \
        "d" ((char *) (addr)),"a" (0x00080000))
是一段内联汇编,主要是设置段描述符,其实就是中断门描述符。对着图看。如图:
而中断服务程序是(hd_interrupt):
hd_interrupt:
        pushl %eax
        pushl %ecx      
        pushl %edx 
        push %ds        
        push %es        
        push %fs
        movl $0x10,%eax
        mov %ax,%ds
        mov %ax,%es
        movl $0x17,%eax
        mov %ax,%fs
        movb $0x20,%al
        outb %al,$0xA0          # EOI to interrupt controller #1
        jmp 1f                  # give port chance to breathe
1:      jmp 1f
1:      xorl %edx,%edx
        xchgl do_hd,%edx
        testl %edx,%edx
        jne 1f
        movl $unexpected_hd_interrupt,%edx
1:      outb %al,$0x20
        call *%edx              # "interesting" way of handling intr.
        pop %fs
        pop %es
        pop %ds
        popl %edx
        popl %ecx
        popl %eax
        iret
是一段汇编,用于真正访问硬盘。
第三和第四句:
outb_p(inb_p(0x21)&0xfb,0x21);
 outb(inb_p(0xA1)&0xbf,0xA1);
是8259A中断设置,设置的是磁盘中断。

总结一下,首先设置并获取块设备函数地址,用以后要通过块设备访问磁盘时的入口地址。接着设置中断门描述符,包括中断服务列程,
最后设置磁盘中断,就是开启相应中断位。当要访问磁盘时,调用块设备函数,系统接到访问请求,发生一个中断,
执行中断服务程序hd_interrupt,访问磁盘,对磁盘进行操作.
2
floppy_init和前面基本一致,只是访问的是软驱。

3
sti()的实体很简单,如下,就是开启中断,开始运行进程进程:
#define sti() __asm__ ("sti"::)
sti是开中断,允许硬件中断

4
move_to_user_mode的实体也是一段内联汇编
#define move_to_user_mode() \
__asm__ ("movl %%esp,%%eax\n\t" \
        "pushl $0x17\n\t" \
        "pushl %%eax\n\t" \
        "pushfl\n\t" \
        "pushl $0x0f\n\t" \ 
        "pushl $1f\n\t" \
        "iret\n" \
        "1:\tmovl $0x17,%%eax\n\t" \
        "movw %%ax,%%ds\n\t" \
        "movw %%ax,%%es\n\t" \
        "movw %%ax,%%fs\n\t" \
        "movw %%ax,%%gs" \
        :::"ax")

主要是将进程0从内核态移动到移应用中,就是特权级0到3的过程


阅读(2620) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~