From dffcbfa64118fcdf5810cb28585c5501de966352 Mon Sep 17 00:00:00 2001 From: hinus Date: Sat, 3 Jul 2021 11:22:19 +0800 Subject: [PATCH 1/2] Title: Elevator algorithm. Issue: https://gitee.com/hinus/linux_kernel_011/issues/I3YY2E Description: Elevator aalgorithm for block dev. --- kernel/blk_drv/blk.h | 6 +++++ kernel/blk_drv/hd.c | 37 +++++++++++++++++++++++++++++- kernel/blk_drv/ll_rw_blk.c | 47 +++++++++++++++++++++++++++++++++++++- kernel/main.c | 2 ++ 4 files changed, 90 insertions(+), 2 deletions(-) diff --git a/kernel/blk_drv/blk.h b/kernel/blk_drv/blk.h index 0b39c46..5df337e 100644 --- a/kernel/blk_drv/blk.h +++ b/kernel/blk_drv/blk.h @@ -17,6 +17,11 @@ struct request { struct request * next; }; +#define IN_ORDER(s1,s2) \ +((s1)->cmd<(s2)->cmd || (s1)->cmd==(s2)->cmd && \ +((s1)->dev < (s2)->dev || ((s1)->dev == (s2)->dev && \ +(s1)->sector < (s2)->sector))) + struct blk_dev_struct { void (*request_fn)(void); struct request * current_request; @@ -24,6 +29,7 @@ struct blk_dev_struct { extern struct blk_dev_struct blk_dev[NR_BLK_DEV]; extern struct request request[NR_REQUEST]; +extern struct task_struct * wait_for_request; #ifdef MAJOR_NR diff --git a/kernel/blk_drv/hd.c b/kernel/blk_drv/hd.c index fa8644d..edfdb08 100644 --- a/kernel/blk_drv/hd.c +++ b/kernel/blk_drv/hd.c @@ -191,6 +191,7 @@ static void read_intr(void) { printk("read callback\n"); if (win_result()) { printk("hd read error.\n"); + do_hd_request(); return; } port_read(HD_DATA,CURRENT->buffer,256); @@ -203,9 +204,28 @@ static void read_intr(void) { return; } end_request(1); + do_hd_request(); +} + +static void write_intr() { + if (win_result()) { + do_hd_request(); + } + + if (--CURRENT->nr_sectors) { + CURRENT->sector++; + CURRENT->buffer += 512; + SET_INTR(&write_intr); + port_write(HD_DATA,CURRENT->buffer,256); + return; + } + + end_request(1); + do_hd_request(); } void do_hd_request() { + int i,r; unsigned int block,dev; unsigned int sec,head,cyl; unsigned int nsect; @@ -214,6 +234,11 @@ void do_hd_request() { dev = MINOR(CURRENT->dev); block = CURRENT->sector; + if (dev >= 5*NR_HD || block+2 > hd[dev].nr_sects) { + end_request(0); + goto repeat; + } + block += hd[dev].start_sect; dev /= 5; @@ -224,9 +249,17 @@ void do_hd_request() { sec++; nsect = CURRENT->nr_sectors; - if (CURRENT->cmd == READ) { + if (CURRENT->cmd == WRITE) { + hd_out(dev,nsect,sec,head,cyl,WIN_WRITE,&write_intr); + for(i=0 ; i<10000 && !(r=inb_p(HD_STATUS)&DRQ_STAT) ; i++) + /*nothing*/; + port_write(HD_DATA,CURRENT->buffer,256); + } + else if (CURRENT->cmd == READ) { hd_out(dev,nsect,sec,head,cyl,WIN_READ,&read_intr); } + else + printk("unknown hd-command"); } void hd_init() { @@ -248,6 +281,8 @@ inline void end_request(int uptodate) { printk("dev %04x, block %d\n\r",CURRENT->dev, CURRENT->bh->b_blocknr); } + wake_up(&CURRENT->waiting); + wake_up(&wait_for_request); CURRENT->dev = -1; CURRENT = CURRENT->next; } diff --git a/kernel/blk_drv/ll_rw_blk.c b/kernel/blk_drv/ll_rw_blk.c index 313c81c..2588240 100644 --- a/kernel/blk_drv/ll_rw_blk.c +++ b/kernel/blk_drv/ll_rw_blk.c @@ -7,6 +7,8 @@ struct request request[NR_REQUEST]; +struct task_struct * wait_for_request = NULL; + inline void lock_buffer(struct buffer_head * bh) { cli(); while (bh->b_lock) @@ -36,13 +38,48 @@ static void add_request(struct blk_dev_struct * dev, struct request * req) { (dev->request_fn)(); return; } + + for ( ; tmp->next ; tmp=tmp->next) { + if (!req->bh) { + if (tmp->next->bh) + break; + else + continue; + } + + if ((IN_ORDER(tmp,req) || + !IN_ORDER(tmp,tmp->next)) && + IN_ORDER(req,tmp->next)) + break; + } + + req->next=tmp->next; + tmp->next=req; + sti(); } static void make_request(int major,int rw, struct buffer_head * bh) { struct request * req; lock_buffer(bh); + if ((rw == WRITE && !bh->b_dirt) || (rw == READ && bh->b_uptodate)) { + unlock_buffer(bh); + return; + } + +repeat: + if (rw == READ) + req = request+NR_REQUEST; + else + req = request+((NR_REQUEST*2)/3); - req = request+NR_REQUEST; + while (--req >= request) + if (req->dev<0) + break; + + if (req < request) { + sleep_on(&wait_for_request); + goto repeat; + } req->dev = bh->b_dev; req->cmd = rw; @@ -63,4 +100,12 @@ void ll_rw_block(int rw, struct buffer_head * bh) { make_request(major,rw,bh); } +void blk_dev_init() { + int i; + + for (i=0 ; i Date: Mon, 5 Jul 2021 22:23:39 +0800 Subject: [PATCH 2/2] Title: Initialize floppy driver. Issue: https://gitee.com/hinus/linux_kernel_011/issues/I3Z0NY Description: Initialization for floppy driver. --- include/linux/fdreg.h | 6 ++++++ kernel/blk_drv/Makefile | 5 ++++- kernel/blk_drv/blk.h | 10 +++++++++- kernel/blk_drv/floppy.c | 28 ++++++++++++++++++++++++++++ kernel/main.c | 7 +++++-- kernel/sys_call.S | 30 +++++++++++++++++++++++++++++- 6 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 include/linux/fdreg.h create mode 100644 kernel/blk_drv/floppy.c diff --git a/include/linux/fdreg.h b/include/linux/fdreg.h new file mode 100644 index 0000000..cde6852 --- /dev/null +++ b/include/linux/fdreg.h @@ -0,0 +1,6 @@ +#ifndef _FDREG_H +#define _FDREG_H + + + +#endif diff --git a/kernel/blk_drv/Makefile b/kernel/blk_drv/Makefile index 6e9fbcd..3e0b2a9 100644 --- a/kernel/blk_drv/Makefile +++ b/kernel/blk_drv/Makefile @@ -2,7 +2,7 @@ AR := ar LD := ld GCC := gcc CCFLAG := -m32 -I../../include -nostdinc -ffreestanding -fno-pic -Wall -fomit-frame-pointer -fno-stack-protector -c -OBJS := hd.o ll_rw_blk.o +OBJS := hd.o ll_rw_blk.o floppy.o blk_drv.a : $(OBJS) $(AR) rcs $@ $^ @@ -14,6 +14,9 @@ hd.o : hd.c ll_rw_blk.o : ll_rw_blk.c $(GCC) $(CCFLAG) -o $@ $< +floppy.o : floppy.c + $(GCC) $(CCFLAG) -o $@ $< + clean : rm *.o rm blk_drv.a diff --git a/kernel/blk_drv/blk.h b/kernel/blk_drv/blk.h index 5df337e..6706289 100644 --- a/kernel/blk_drv/blk.h +++ b/kernel/blk_drv/blk.h @@ -33,7 +33,15 @@ extern struct task_struct * wait_for_request; #ifdef MAJOR_NR -#if (MAJOR_NR == 3) +#if (MAJOR_NR == 2) +#define DEVICE_NAME "floppy" +#define DEVICE_INTR do_floppy +#define DEVICE_REQUEST do_fd_request +#define DEVICE_NR(device) ((device) & 3) +#define DEVICE_ON(device) floppy_on(DEVICE_NR(device)) +#define DEVICE_OFF(device) floppy_off(DEVICE_NR(device)) + +#elif (MAJOR_NR == 3) #define DEVICE_NAME "harddisk" #define DEVICE_INTR do_hd #define DEVICE_TIMEOUT hd_timeout diff --git a/kernel/blk_drv/floppy.c b/kernel/blk_drv/floppy.c new file mode 100644 index 0000000..a906ecc --- /dev/null +++ b/kernel/blk_drv/floppy.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include +#include +#include +#include + +#define MAJOR_NR 2 +#include "blk.h" + +extern void floppy_interrupt(); + +void unexpected_floppy_interrupt() { + printk("unexpected floppy interrupt.\n"); +} + +void do_fd_request() { + +} + +void floppy_init() { + //blk_size[MAJOR_NR] = floppy_sizes; + blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST; + set_trap_gate(0x26,&floppy_interrupt); + outb(inb_p(0x21)&~0x40,0x21); +} + diff --git a/kernel/main.c b/kernel/main.c index 075421a..4f6bb0e 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -21,8 +21,9 @@ int printf(const char* fmt, ...); extern int vsprintf(char* buf, const char* fmt, va_list args); void init(); -extern void hd_init(void); -extern void blk_dev_init(void); +extern void hd_init(); +extern void floppy_init(); +extern void blk_dev_init(); extern void mem_init(long start, long end); #define EXT_MEM_K (*(unsigned short *)0x90002) @@ -73,6 +74,8 @@ void main(void) blk_dev_init(); hd_init(); + floppy_init(); + sti(); move_to_user_mode(); diff --git a/kernel/sys_call.S b/kernel/sys_call.S index ceee7d1..cd15ffd 100644 --- a/kernel/sys_call.S +++ b/kernel/sys_call.S @@ -1,7 +1,7 @@ .code32 .text .globl system_call, timer_interrupt, sys_fork -.globl hd_interrupt +.globl hd_interrupt, floppy_interrupt EAX = 0x00 EBX = 0x04 @@ -120,3 +120,31 @@ hd_interrupt: popl %eax iret +floppy_interrupt: + pushl %eax + pushl %ecx + pushl %edx + pushl %ds + pushl %es + pushl %fs + movl $0x10, %eax + movw %ax, %ds + movw %ax, %es + movl $0x17, %eax + movw %ax, %fs + xorl %edx, %edx + xchgl do_floppy, %edx + testl %edx, %edx + jne 1f + movl $unexpected_floppy_interrupt, %edx +1: call *%edx + movb $0x20, %al + outb %al, $0x20 + popl %fs + popl %es + popl %ds + popl %edx + popl %ecx + popl %eax + iret + -- Gitee