mirror of
https://github.com/cccriscv/mini-riscv-os.git
synced 2025-11-16 04:24:33 +00:00
refactor
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -7,4 +7,6 @@
|
|||||||
*.bak
|
*.bak
|
||||||
bak
|
bak
|
||||||
.vscode
|
.vscode
|
||||||
|
*.img
|
||||||
|
*.dsk
|
||||||
|
|
||||||
|
|||||||
@@ -18,12 +18,12 @@ string.c
|
|||||||
|
|
||||||
QEMU = qemu-system-riscv32
|
QEMU = qemu-system-riscv32
|
||||||
QFLAGS = -nographic -smp 4 -machine virt -bios none
|
QFLAGS = -nographic -smp 4 -machine virt -bios none
|
||||||
QFLAGS += -drive file=fs.img,if=none,format=raw,id=x0
|
QFLAGS += -drive if=none,format=raw,file=hdd.dsk,id=x0
|
||||||
QFLAGS += -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0
|
QFLAGS += -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0
|
||||||
|
|
||||||
OBJDUMP = riscv64-unknown-elf-objdump
|
OBJDUMP = riscv64-unknown-elf-objdump
|
||||||
|
|
||||||
all: os.elf
|
all: clean os.elf hdd.dsk qemu
|
||||||
|
|
||||||
os.elf: $(OBJ)
|
os.elf: $(OBJ)
|
||||||
$(CC) $(CFLAGS) -T os.ld -o os.elf $^
|
$(CC) $(CFLAGS) -T os.ld -o os.elf $^
|
||||||
@@ -34,10 +34,10 @@ qemu: $(TARGET)
|
|||||||
$(QEMU) $(QFLAGS) -kernel os.elf
|
$(QEMU) $(QFLAGS) -kernel os.elf
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.elf
|
rm -f *.elf *.img *.dsk
|
||||||
|
|
||||||
fs.img:
|
hdd.dsk:
|
||||||
qemu-img create -f raw fs.img 50M
|
dd if=/dev/urandom of=hdd.dsk bs=1M count=32
|
||||||
|
|
||||||
.PHONY : debug
|
.PHONY : debug
|
||||||
debug: all
|
debug: all
|
||||||
|
|||||||
Binary file not shown.
@@ -19,12 +19,13 @@ void os_start()
|
|||||||
{
|
{
|
||||||
uart_init();
|
uart_init();
|
||||||
lib_puts("OS start\n");
|
lib_puts("OS start\n");
|
||||||
virtio_disk_init();
|
|
||||||
user_init();
|
user_init();
|
||||||
trap_init();
|
trap_init();
|
||||||
plic_init();
|
plic_init();
|
||||||
|
virtio_disk_init();
|
||||||
timer_init(); // start timer interrupt ...
|
timer_init(); // start timer interrupt ...
|
||||||
virtio_tester();
|
virtio_tester(1);
|
||||||
|
virtio_tester(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int os_main(void)
|
int os_main(void)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// ref: https://github.com/qemu/qemu/blob/master/include/hw/riscv/virt.h
|
// ref: https://github.com/qemu/qemu/blob/master/include/hw/riscv/virt.h
|
||||||
// Intro: https://github.com/ianchen0119/AwesomeCS/wiki/2-5-RISC-V::%E4%B8%AD%E6%96%B7%E8%88%87%E7%95%B0%E5%B8%B8%E8%99%95%E7%90%86----PLIC-%E4%BB%8B%E7%B4%B9
|
// Intro: https://github.com/ianchen0119/AwesomeCS/wiki/2-5-RISC-V::%E4%B8%AD%E6%96%B7%E8%88%87%E7%95%B0%E5%B8%B8%E8%99%95%E7%90%86----PLIC-%E4%BB%8B%E7%B4%B9
|
||||||
#define PLIC_BASE 0x0c000000L
|
#define PLIC_BASE 0x0c000000
|
||||||
#define PLIC_PRIORITY(id) (PLIC_BASE + (id)*4)
|
#define PLIC_PRIORITY(id) (PLIC_BASE + (id)*4)
|
||||||
#define PLIC_PENDING(id) (PLIC_BASE + 0x1000 + ((id) / 32))
|
#define PLIC_PENDING(id) (PLIC_BASE + 0x1000 + ((id) / 32))
|
||||||
#define PLIC_MENABLE(hart) (PLIC_BASE + 0x2000 + (hart)*0x80)
|
#define PLIC_MENABLE(hart) (PLIC_BASE + 0x2000 + (hart)*0x80)
|
||||||
@@ -15,10 +15,16 @@ void plic_init()
|
|||||||
int hart = r_tp();
|
int hart = r_tp();
|
||||||
// QEMU Virt machine support 7 priority (1 - 7),
|
// QEMU Virt machine support 7 priority (1 - 7),
|
||||||
// The "0" is reserved, and the lowest priority is "1".
|
// The "0" is reserved, and the lowest priority is "1".
|
||||||
*(uint32_t *)PLIC_PRIORITY(UART0_IRQ) = 1;
|
for (size_t i = VIRTIO_IRQ; i <= UART0_IRQ; i++)
|
||||||
|
{
|
||||||
|
*(uint32_t *)PLIC_PRIORITY(i) = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Enable UART0 */
|
/* Enable UART0 and VIRTIO */
|
||||||
*(uint32_t *)PLIC_MENABLE(hart) = (1 << UART0_IRQ);
|
for (size_t i = VIRTIO_IRQ; i <= UART0_IRQ; i++)
|
||||||
|
{
|
||||||
|
*(uint32_t *)PLIC_MENABLE(hart) |= (1 << i);
|
||||||
|
}
|
||||||
|
|
||||||
/* Set priority threshold for UART0. */
|
/* Set priority threshold for UART0. */
|
||||||
|
|
||||||
|
|||||||
@@ -14,8 +14,9 @@ void external_handler()
|
|||||||
{
|
{
|
||||||
lib_isr();
|
lib_isr();
|
||||||
}
|
}
|
||||||
else if (irq == VIRTIO_IRQ)
|
else if (0 < irq < 9)
|
||||||
{
|
{
|
||||||
|
panic("Virio IRQ");
|
||||||
virtio_disk_isr();
|
virtio_disk_isr();
|
||||||
}
|
}
|
||||||
else if (irq)
|
else if (irq)
|
||||||
@@ -63,7 +64,7 @@ reg_t trap_handler(reg_t epc, reg_t cause)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Synchronous trap - exception */
|
/* Synchronous trap - exception */
|
||||||
lib_puts("Sync exceptions!\n");
|
lib_printf("Sync exceptions! cause code: %d\n", cause_code);
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* code */
|
/* code */
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
#ifndef __TYPES_H__
|
#ifndef __TYPES_H__
|
||||||
#define __TYPES_H__
|
#define __TYPES_H__
|
||||||
|
|
||||||
typedef signed char int8;
|
typedef unsigned int uint;
|
||||||
|
typedef unsigned short ushort;
|
||||||
|
typedef unsigned char uchar;
|
||||||
|
|
||||||
typedef unsigned char uint8;
|
typedef unsigned char uint8;
|
||||||
typedef short int16;
|
|
||||||
typedef unsigned short uint16;
|
typedef unsigned short uint16;
|
||||||
typedef int int32;
|
typedef unsigned int uint32;
|
||||||
typedef unsigned uint32;
|
|
||||||
typedef long long int64;
|
|
||||||
typedef unsigned long long uint64;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -53,8 +53,6 @@ void user_task3(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern virtio_tester();
|
|
||||||
|
|
||||||
void user_init()
|
void user_init()
|
||||||
{
|
{
|
||||||
// lock_init(&lock);
|
// lock_init(&lock);
|
||||||
|
|||||||
@@ -5,30 +5,15 @@
|
|||||||
#define BSIZE 1024 // block size
|
#define BSIZE 1024 // block size
|
||||||
#define PGSHIFT 12
|
#define PGSHIFT 12
|
||||||
|
|
||||||
struct buf
|
struct blk
|
||||||
{
|
{
|
||||||
int valid; // has data been read from disk?
|
|
||||||
int disk; // does disk "own" buf?
|
|
||||||
uint32 dev;
|
uint32 dev;
|
||||||
uint32 blockno;
|
uint32 blockno;
|
||||||
lock_t lock;
|
lock_t lock;
|
||||||
uint32 refcnt;
|
uint32 refcnt;
|
||||||
struct buf *prev; // LRU cache list
|
|
||||||
struct buf *next;
|
|
||||||
unsigned char data[BSIZE];
|
unsigned char data[BSIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
lock_t lock;
|
|
||||||
struct buf buf[30];
|
|
||||||
|
|
||||||
// Linked list of all buffers, through prev/next.
|
|
||||||
// Sorted by how recently the buffer was used.
|
|
||||||
// head.next is most recent, head.prev is least.
|
|
||||||
struct buf head;
|
|
||||||
} bcache;
|
|
||||||
|
|
||||||
static struct disk
|
static struct disk
|
||||||
{
|
{
|
||||||
char pages[2 * PGSIZE];
|
char pages[2 * PGSIZE];
|
||||||
@@ -42,7 +27,7 @@ static struct disk
|
|||||||
char free[NUM];
|
char free[NUM];
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
struct buf *b;
|
struct blk *b;
|
||||||
char status;
|
char status;
|
||||||
} info[NUM];
|
} info[NUM];
|
||||||
uint16 used_idx;
|
uint16 used_idx;
|
||||||
@@ -52,38 +37,51 @@ static struct disk
|
|||||||
struct lock vdisk_lock;
|
struct lock vdisk_lock;
|
||||||
} __attribute__((aligned(PGSIZE))) disk;
|
} __attribute__((aligned(PGSIZE))) disk;
|
||||||
|
|
||||||
void virtio_tester()
|
struct blk b[3];
|
||||||
|
|
||||||
|
void virtio_tester(int write)
|
||||||
{
|
{
|
||||||
// int valid; // has data been read from disk?
|
if (!b[0].dev)
|
||||||
// int disk; // does disk "own" buf?
|
{
|
||||||
// uint32 dev;
|
lib_puts("buffer init...\n");
|
||||||
// uint32 blockno;
|
for (size_t i = 0; i < 1; i++)
|
||||||
// lock_t lock;
|
{
|
||||||
// uint32 refcnt;
|
b[i].dev = 1; // always is 1
|
||||||
// struct buf *prev; // LRU cache list
|
b[i].blockno = i + 1;
|
||||||
// struct buf *next;
|
for (size_t j = 0; j < BSIZE; j++)
|
||||||
// unsigned char data[BSIZE];
|
{
|
||||||
struct buf b[3];
|
b[i].data[j] = 0;
|
||||||
lib_puts("buffer init...\n");
|
}
|
||||||
for (size_t i = 0; i < 3; i++)
|
|
||||||
|
lock_init(&(b[i].lock));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (write)
|
||||||
{
|
{
|
||||||
b[i].valid = 1;
|
|
||||||
b[i].disk = 1;
|
|
||||||
b[i].dev = 1;
|
|
||||||
b[i].blockno = i;
|
|
||||||
for (size_t j = 0; j < BSIZE; j++)
|
for (size_t j = 0; j < BSIZE; j++)
|
||||||
{
|
{
|
||||||
b[i].data[j] = (j + i + 1) % 10;
|
b[0].data[j] = (j + 1) % 10;
|
||||||
}
|
}
|
||||||
|
lib_puts("block write...\n");
|
||||||
lock_init(&(b[i].lock));
|
virtio_disk_rw(&b[0], write);
|
||||||
|
lib_puts("done...!\n");
|
||||||
}
|
}
|
||||||
lib_puts("buffer write...\n");
|
else
|
||||||
for (size_t i = 0; i < 3; i++)
|
|
||||||
{
|
{
|
||||||
virtio_disk_rw(&b[i], 1);
|
for (size_t j = 0; j < BSIZE; j++)
|
||||||
|
{
|
||||||
|
b[0].data[j] = 0;
|
||||||
|
}
|
||||||
|
lib_puts("block read...\n");
|
||||||
|
virtio_disk_rw(&b[0], write);
|
||||||
|
size_t i = 0;
|
||||||
|
for (; i < 10; i++)
|
||||||
|
{
|
||||||
|
lib_printf("%d ", b[0].data[i]);
|
||||||
|
}
|
||||||
|
lib_puts("\n");
|
||||||
}
|
}
|
||||||
lib_puts("wait...\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void virtio_disk_init()
|
void virtio_disk_init()
|
||||||
@@ -99,6 +97,8 @@ void virtio_disk_init()
|
|||||||
{
|
{
|
||||||
panic("could not find virtio disk");
|
panic("could not find virtio disk");
|
||||||
}
|
}
|
||||||
|
/* Reset the device */
|
||||||
|
*R(VIRTIO_MMIO_STATUS) = status;
|
||||||
/* Set the ACKNOWLEDGE status bit to the status register. */
|
/* Set the ACKNOWLEDGE status bit to the status register. */
|
||||||
status |= VIRTIO_CONFIG_S_ACKNOWLEDGE;
|
status |= VIRTIO_CONFIG_S_ACKNOWLEDGE;
|
||||||
*R(VIRTIO_MMIO_STATUS) = status;
|
*R(VIRTIO_MMIO_STATUS) = status;
|
||||||
@@ -106,7 +106,7 @@ void virtio_disk_init()
|
|||||||
status |= VIRTIO_CONFIG_S_DRIVER;
|
status |= VIRTIO_CONFIG_S_DRIVER;
|
||||||
*R(VIRTIO_MMIO_STATUS) = status;
|
*R(VIRTIO_MMIO_STATUS) = status;
|
||||||
/* negotiate features */
|
/* negotiate features */
|
||||||
uint64 features = *R(VIRTIO_MMIO_DEVICE_FEATURES);
|
uint32 features = *R(VIRTIO_MMIO_DEVICE_FEATURES);
|
||||||
features &= ~(1 << VIRTIO_BLK_F_RO);
|
features &= ~(1 << VIRTIO_BLK_F_RO);
|
||||||
features &= ~(1 << VIRTIO_BLK_F_SCSI);
|
features &= ~(1 << VIRTIO_BLK_F_SCSI);
|
||||||
features &= ~(1 << VIRTIO_BLK_F_CONFIG_WCE);
|
features &= ~(1 << VIRTIO_BLK_F_CONFIG_WCE);
|
||||||
@@ -129,12 +129,12 @@ void virtio_disk_init()
|
|||||||
*R(VIRTIO_MMIO_QUEUE_SEL) = 0;
|
*R(VIRTIO_MMIO_QUEUE_SEL) = 0;
|
||||||
uint32 max = *R(VIRTIO_MMIO_QUEUE_NUM_MAX);
|
uint32 max = *R(VIRTIO_MMIO_QUEUE_NUM_MAX);
|
||||||
if (max == 0)
|
if (max == 0)
|
||||||
lib_puts("virtio disk has no queue 0\n");
|
panic("virtio disk has no queue 0\n");
|
||||||
if (max < NUM)
|
if (max < NUM)
|
||||||
lib_puts("virtio disk max queue too short\n");
|
panic("virtio disk max queue too short\n");
|
||||||
*R(VIRTIO_MMIO_QUEUE_NUM) = NUM;
|
*R(VIRTIO_MMIO_QUEUE_NUM) = NUM;
|
||||||
memset(disk.pages, 0, sizeof(disk.pages));
|
memset(disk.pages, 0, sizeof(disk.pages));
|
||||||
*R(VIRTIO_MMIO_QUEUE_PFN) = ((uint64)disk.pages) >> PGSHIFT;
|
*R(VIRTIO_MMIO_QUEUE_PFN) = ((uint32)disk.pages) >> PGSHIFT;
|
||||||
|
|
||||||
// desc = pages -- num * virtq_desc
|
// desc = pages -- num * virtq_desc
|
||||||
// avail = pages + 0x40 -- 2 * uint16, then num * uint16
|
// avail = pages + 0x40 -- 2 * uint16, then num * uint16
|
||||||
@@ -214,18 +214,11 @@ alloc3_desc(int *idx)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void virtio_disk_rw(struct buf *b, int write)
|
void virtio_disk_rw(struct blk *b, int write)
|
||||||
{
|
{
|
||||||
uint64 sector = b->blockno * (BSIZE / 512);
|
uint32 sector = b->blockno * (BSIZE / 512);
|
||||||
|
|
||||||
lock_acquire(&disk.vdisk_lock);
|
|
||||||
|
|
||||||
// the spec's Section 5.2 says that legacy block operations use
|
|
||||||
// three descriptors: one for type/reserved/sector, one for the
|
|
||||||
// data, one for a 1-byte status result.
|
|
||||||
|
|
||||||
// allocate the three descriptors.
|
// allocate the three descriptors.
|
||||||
lib_puts("rw init...\n");
|
|
||||||
int idx[3];
|
int idx[3];
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@@ -244,15 +237,15 @@ void virtio_disk_rw(struct buf *b, int write)
|
|||||||
buf0->type = VIRTIO_BLK_T_OUT; // write the disk
|
buf0->type = VIRTIO_BLK_T_OUT; // write the disk
|
||||||
else
|
else
|
||||||
buf0->type = VIRTIO_BLK_T_IN; // read the disk
|
buf0->type = VIRTIO_BLK_T_IN; // read the disk
|
||||||
buf0->reserved = 0; // The reserved portion is used to pad the header to 16 bytes and move the 64-bit sector field to the correct place.
|
buf0->reserved = 0; // The reserved portion is used to pad the header to 16 bytes and move the 32-bit sector field to the correct place.
|
||||||
buf0->sector = sector; // specify the sector that we wanna modified.
|
buf0->sector = sector; // specify the sector that we wanna modified.
|
||||||
|
|
||||||
disk.desc[idx[0]].addr = (uint64)buf0;
|
disk.desc[idx[0]].addr = (uint32)buf0;
|
||||||
disk.desc[idx[0]].len = sizeof(struct virtio_blk_req);
|
disk.desc[idx[0]].len = sizeof(struct virtio_blk_req);
|
||||||
disk.desc[idx[0]].flags = VRING_DESC_F_NEXT;
|
disk.desc[idx[0]].flags = VRING_DESC_F_NEXT;
|
||||||
disk.desc[idx[0]].next = idx[1];
|
disk.desc[idx[0]].next = idx[1];
|
||||||
|
|
||||||
disk.desc[idx[1]].addr = (uint64)b->data;
|
disk.desc[idx[1]].addr = (uint32)b->data;
|
||||||
disk.desc[idx[1]].len = BSIZE;
|
disk.desc[idx[1]].len = BSIZE;
|
||||||
if (write)
|
if (write)
|
||||||
disk.desc[idx[1]].flags = 0; // device reads b->data
|
disk.desc[idx[1]].flags = 0; // device reads b->data
|
||||||
@@ -262,36 +255,27 @@ void virtio_disk_rw(struct buf *b, int write)
|
|||||||
disk.desc[idx[1]].next = idx[2];
|
disk.desc[idx[1]].next = idx[2];
|
||||||
|
|
||||||
disk.info[idx[0]].status = 0xff; // device writes 0 on success
|
disk.info[idx[0]].status = 0xff; // device writes 0 on success
|
||||||
disk.desc[idx[2]].addr = (uint64)&disk.info[idx[0]].status;
|
disk.desc[idx[2]].addr = (uint32)&disk.info[idx[0]].status;
|
||||||
disk.desc[idx[2]].len = 1;
|
disk.desc[idx[2]].len = 1;
|
||||||
disk.desc[idx[2]].flags = VRING_DESC_F_WRITE; // device writes the status
|
disk.desc[idx[2]].flags = VRING_DESC_F_WRITE; // device writes the status
|
||||||
disk.desc[idx[2]].next = 0;
|
disk.desc[idx[2]].next = 0;
|
||||||
|
|
||||||
// record struct buf for virtio_disk_intr().
|
// record struct buf for virtio_disk_intr().
|
||||||
b->disk = 1;
|
|
||||||
disk.info[idx[0]].b = b;
|
disk.info[idx[0]].b = b;
|
||||||
|
|
||||||
|
__sync_synchronize();
|
||||||
|
|
||||||
// tell the device the first index in our chain of descriptors.
|
// tell the device the first index in our chain of descriptors.
|
||||||
disk.avail->ring[disk.avail->idx % NUM] = idx[0];
|
disk.avail->ring[disk.avail->idx % NUM] = idx[0];
|
||||||
lib_puts("rw wait...\n");
|
|
||||||
__sync_synchronize();
|
__sync_synchronize();
|
||||||
|
|
||||||
// tell the device another avail ring entry is available.
|
// tell the device another avail ring entry is available.
|
||||||
disk.avail->idx += 1; // not % NUM ...
|
disk.avail->idx += 1; // not % NUM ...
|
||||||
|
|
||||||
__sync_synchronize();
|
*R(VIRTIO_MMIO_QUEUE_NOTIFY) = 0; // The device starts immediately when we write 0 to queue_notify.
|
||||||
|
|
||||||
*R(VIRTIO_MMIO_QUEUE_NOTIFY) = 0; // value is queue number
|
|
||||||
|
|
||||||
// Wait for virtio_disk_intr() to say request has finished.
|
|
||||||
// while (b->disk == 1)
|
|
||||||
// {
|
|
||||||
// }
|
|
||||||
|
|
||||||
disk.info[idx[0]].b = 0;
|
disk.info[idx[0]].b = 0;
|
||||||
free_chain(idx[0]);
|
|
||||||
|
|
||||||
lock_free(&disk.vdisk_lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void virtio_disk_isr()
|
void virtio_disk_isr()
|
||||||
@@ -319,8 +303,7 @@ void virtio_disk_isr()
|
|||||||
if (disk.info[id].status != 0)
|
if (disk.info[id].status != 0)
|
||||||
panic("virtio_disk_intr status");
|
panic("virtio_disk_intr status");
|
||||||
|
|
||||||
struct buf *b = disk.info[id].b;
|
struct blk *b = disk.info[id].b;
|
||||||
b->disk = 0; // disk is done with buf
|
|
||||||
|
|
||||||
disk.used_idx += 1;
|
disk.used_idx += 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ typedef struct virtq_desc
|
|||||||
* flags: 用於控制 descriptor 。
|
* flags: 用於控制 descriptor 。
|
||||||
* next: 告訴 Device 下一個描述符的 Index 。如果指定了 VIRTQ_DESC_F_NEXT, Device 僅讀取該字段。否則無效。
|
* next: 告訴 Device 下一個描述符的 Index 。如果指定了 VIRTQ_DESC_F_NEXT, Device 僅讀取該字段。否則無效。
|
||||||
*/
|
*/
|
||||||
uint64 addr;
|
uint32 addr;
|
||||||
uint32 len;
|
uint32 len;
|
||||||
uint16 flags;
|
uint16 flags;
|
||||||
uint16 next;
|
uint16 next;
|
||||||
@@ -115,5 +115,5 @@ typedef struct virtio_blk_req
|
|||||||
{
|
{
|
||||||
uint32 type; // VIRTIO_BLK_T_IN or ..._OUT
|
uint32 type; // VIRTIO_BLK_T_IN or ..._OUT
|
||||||
uint32 reserved; // 將 Header 擴充到 16-byte ,並將 64-bit sector 移到正確的位置。
|
uint32 reserved; // 將 Header 擴充到 16-byte ,並將 64-bit sector 移到正確的位置。
|
||||||
uint64 sector;
|
uint32 sector;
|
||||||
} virtio_blk_req_t;
|
} virtio_blk_req_t;
|
||||||
@@ -62,3 +62,4 @@ in the `LICENSE` file.
|
|||||||
- [Adventures in RISC-V](https://matrix89.github.io/writes/writes/experiments-in-riscv/)
|
- [Adventures in RISC-V](https://matrix89.github.io/writes/writes/experiments-in-riscv/)
|
||||||
- [Xv6, a simple Unix-like teaching operating system](https://pdos.csail.mit.edu/6.828/2020/xv6.html)
|
- [Xv6, a simple Unix-like teaching operating system](https://pdos.csail.mit.edu/6.828/2020/xv6.html)
|
||||||
- [Basics of programming a UART](https://www.activexperts.com/serial-port-component/tutorials/uart/)
|
- [Basics of programming a UART](https://www.activexperts.com/serial-port-component/tutorials/uart/)
|
||||||
|
- [QEMU RISC-V Virt Machine Platform](https://github.com/riscv/opensbi/blob/master/docs/platform/qemu_virt.md)
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ struct virtq_used
|
|||||||
+------------------+
|
+------------------+
|
||||||
```
|
```
|
||||||
|
|
||||||
完成 Device Driver 方便我們在日後實現檔案系統。
|
完成 Device Driver 會讓我們在日後實現檔案系統更為方便,此外,參考 xv6-riscv 的設計,我們還會需要實現一層 Buffer cache 用來同步硬碟上的資料。
|
||||||
|
|
||||||
### 指定寫入的 Sector
|
### 指定寫入的 Sector
|
||||||
|
|
||||||
@@ -153,7 +153,7 @@ if(write)
|
|||||||
buf0->type = VIRTIO_BLK_T_OUT; // write the disk
|
buf0->type = VIRTIO_BLK_T_OUT; // write the disk
|
||||||
else
|
else
|
||||||
buf0->type = VIRTIO_BLK_T_IN; // read the disk
|
buf0->type = VIRTIO_BLK_T_IN; // read the disk
|
||||||
buf0->reserved = 0; // The reserved portion is used to pad the header to 16 bytes and move the 64-bit sector field to the correct place.
|
buf0->reserved = 0; // The reserved portion is used to pad the header to 16 bytes and move the 32-bit sector field to the correct place.
|
||||||
buf0->sector = sector; // specify the sector that we wanna modified.
|
buf0->sector = sector; // specify the sector that we wanna modified.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user