用大白话说操作系统(九)

好的,OK,心情不好就输出,操作系统真是解忧啊~~~~

buffer_init(buffer_memory_end)

前面我们已经把主内存区的初始化大表给建立起来了,现在就来看缓冲区的管理。

extern int end;
struct buffer_head * start_buffer = (struct buffer_head *) &end;

void buffer_init(long buffer_end) {
    struct buffer_head * h = start_buffer;
    void * b = (void *) buffer_end;
    while ( (b -= 1024) >= ((void *) (h+1)) ) {
        h->b_dev = 0;
        h->b_dirt = 0;
        h->b_count = 0;
        h->b_lock = 0;
        h->b_uptodate = 0;
        h->b_wait = NULL;
        h->b_next = NULL;
        h->b_prev = NULL;
        h->b_data = (char *) b;
        h->b_prev_free = h-1;
        h->b_next_free = h+1;
        h++;
    }
    h--;
    free_list = start_buffer;
    free_list->b_prev_free = h;
    h->b_next_free = free_list;
    for (int i=0;i<307;i++)
        hash_table[i]=NULL;
}

外部变量end
end赋值给了我们的缓冲区的开始变量start_buffer。
由链接器ld在链接整个程序时设置的一个外部变量,帮我们计算好了整个内核代码的末尾地址。

void buffer_init(long buffer_end) {
    struct buffer_head * h = start_buffer;
    void * b = (void *) buffer_end;
    while ( (b -= 1024) >= ((void *) (h+1)) ) {
        ...
        h->b_data = (char *) b;
        h->b_prev_free = h-1;
        h->b_next_free = h+1;
        h++;
    }
    ...
}

这里有一个buffer_head的结构h,代表缓冲头
这里有一个b,代表缓冲块,指针值是buffer_end,也就是缓冲区结尾。
缓冲区结尾的b 每次循环-1024,也就是一页的值,缓冲区结尾的h每次循环+1,直到碰到一块为止。
这个h,有三个东西,b_data指向b , b_prev_free指向前一个,b_next_free指向后一个,可以看出这是一个管理缓冲块的双向链表。
在这里插入图片描述

void buffer_init(long buffer_end) {
    ...
    free_list = start_buffer;
    free_list->b_prev_free = h;
    h->b_next_free = free_list;
    ...
}

缓冲头是具体缓冲块的管理结构,free_list开头的双向链表是缓冲头的管理结构

void buffer_init(long buffer_end) {
    ...
    for (i=0;i<307;i++)
        hash_table[i]=NULL;
}

这里有一个307的hash_table数组,这个是用来看块设备读取时,要读取的数据是否已经在内存缓冲区存在了。如果存在直接读内存缓冲区就可以了。

hd_init()

终于来到了硬盘初始化。

//struct blk_dev_struct {
//    void (*request_fn)(void);
//    struct request * current_request;
//};
//extern struct blk_dev_struct blk_dev[NR_BLK_DEV];

void hd_init(void) {
    blk_dev[3].request_fn = do_hd_request;
    set_intr_gate(0x2E,&hd_interrupt);
    outb_p(inb_p(0x21)&0xfb,0x21);
    outb(inb_p(0xA1)&0xbf,0xA1); 
}

对于硬件设备的初始化大体都是1.往某些IO端口上读写一些文件,表示开启它;2.向中断向量表中添加一个中断,使得CPU能够响应这个硬件设备的动作。3.初始化一些数据结构来管理。

第一行代码:把blk_dev数组索引3的位置的块设备管理结构blk_dev_struct的request_fn赋值为do_hd_request。

struct blk_dev_struct blk_dev[NR_BLK_DEV] = {
    { NULL, NULL },     /* no_dev */
    { NULL, NULL },     /* dev mem */
    { NULL, NULL },     /* dev fd */
    { NULL, NULL },     /* dev hd */
    { NULL, NULL },     /* dev ttyx */
    { NULL, NULL },     /* dev tty */
    { NULL, NULL }      /* dev lp */
};

因为有很多块设备,用一个blk_dev数组来管理,每一个索引表示一个块设备。
索引为3是给硬盘这个块设备留的位置。
每个块设备执行读写请求都有自己的函数实现,在上层看来都是一个同一个的函数request_fn,但是具体实现各有不同,就相当于多态,这个硬盘的读写函数就是do_hd_request;
第二行代码

set_intr_gate(0x2E,&hd_interrupt);

这里是设置一个硬盘中断,这个已经完全不陌生了,我们之前在中断初始化的时候设置了一些中断,然后键盘中断,时钟中断和系统调用中断,加上现在的硬盘中断。
最后两行代码就是网几个IO端口上读写,作用是允许硬盘控制器发送中断请求信号。
好的,OK,今天就说到这里吧,有问题欢迎留言讨论!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

神仙诙谐代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值