Skip to content

Commit

Permalink
✨ 078 虚拟设备
Browse files Browse the repository at this point in the history
  • Loading branch information
StevenBaby committed Sep 11, 2022
1 parent 3a4b37c commit d631173
Show file tree
Hide file tree
Showing 14 changed files with 253 additions and 8 deletions.
26 changes: 26 additions & 0 deletions docs/09 设备驱动/078 虚拟设备.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# 虚拟设备

对硬件设备进行一层抽象,使得读写更加的统一,方便以后的操作。

```c++
// 安装设备
dev_t device_install(
int type, int subtype,
void *ptr, char *name, dev_t parent,
void *ioctl, void *read, void *write);

// 根据子类型查找设备
device_t *device_find(int type, idx_t idx);

// 根据设备号查找设备
device_t *device_get(dev_t dev);

// 控制设备
int device_ioctl(dev_t dev, int cmd, void *args, int flags);

// 读设备
int device_read(dev_t dev, void *buf, size_t count, idx_t idx, int flags);

// 写设备
int device_write(dev_t dev, void *buf, size_t count, idx_t idx, int flags);
```
1 change: 0 additions & 1 deletion src/include/onix/console.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@

void console_init();
void console_clear();
int32 console_write(char *buf, u32 count);

#endif
60 changes: 60 additions & 0 deletions src/include/onix/device.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#ifndef ONIX_DEVICE_H
#define ONIX_DEVICE_H

#include <onix/types.h>

#define NAMELEN 16

// 设备类型
enum device_type_t
{
DEV_NULL, // 空设备
DEV_CHAR, // 字符设备
DEV_BLOCK, // 块设备
};

// 设备子类型
enum device_subtype_t
{
DEV_CONSOLE = 1, // 控制台
DEV_KEYBOARD, // 键盘
};

typedef struct device_t
{
char name[NAMELEN]; // 设备名
int type; // 设备类型
int subtype; // 设备子类型
dev_t dev; // 设备号
dev_t parent; // 父设备号
void *ptr; // 设备指针
// 设备控制
int (*ioctl)(void *dev, int cmd, void *args, int flags);
// 读设备
int (*read)(void *dev, void *buf, size_t count, idx_t idx, int flags);
// 写设备
int (*write)(void *dev, void *buf, size_t count, idx_t idx, int flags);
} device_t;

// 安装设备
dev_t device_install(
int type, int subtype,
void *ptr, char *name, dev_t parent,
void *ioctl, void *read, void *write);

// 根据子类型查找设备
device_t *device_find(int type, idx_t idx);

// 根据设备号查找设备
device_t *device_get(dev_t dev);

// 控制设备
int device_ioctl(dev_t dev, int cmd, void *args, int flags);

// 读设备
int device_read(dev_t dev, void *buf, size_t count, idx_t idx, int flags);

// 写设备
int device_write(dev_t dev, void *buf, size_t count, idx_t idx, int flags);

#endif
1 change: 1 addition & 0 deletions src/include/onix/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <onix/types.h>

char *strcpy(char *dest, const char *src);
char *strncpy(char *dest, const char *src, size_t count);
char *strcat(char *dest, const char *src);
size_t strlen(const char *str);
int strcmp(const char *lhs, const char *rhs);
Expand Down
1 change: 1 addition & 0 deletions src/include/onix/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ typedef unsigned int u32;
typedef unsigned long long u64;

typedef int32 pid_t;
typedef int32 dev_t;

typedef u32 time_t;
typedef u32 idx_t;
Expand Down
8 changes: 7 additions & 1 deletion src/kernel/console.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <onix/io.h>
#include <onix/string.h>
#include <onix/interrupt.h>
#include <onix/device.h>

#define CRT_ADDR_REG 0x3D4 // CRT(6845)索引寄存器
#define CRT_DATA_REG 0x3D5 // CRT(6845)数据寄存器
Expand Down Expand Up @@ -155,7 +156,7 @@ static void command_del()

extern void start_beep();

int32 console_write(char *buf, u32 count)
int32 console_write(void *dev, char *buf, u32 count)
{
bool intr = interrupt_disable(); // 禁止中断

Expand Down Expand Up @@ -218,4 +219,9 @@ int32 console_write(char *buf, u32 count)
void console_init()
{
console_clear();

device_install(
DEV_CHAR, DEV_CONSOLE,
NULL, "console", 0,
NULL, NULL, console_write);
}
114 changes: 114 additions & 0 deletions src/kernel/device.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#include <onix/device.h>
#include <onix/string.h>
#include <onix/task.h>
#include <onix/assert.h>
#include <onix/debug.h>
#include <onix/arena.h>

#define LOGK(fmt, args...) DEBUGK(fmt, ##args)

#define DEVICE_NR 64 // 设备数量

static device_t devices[DEVICE_NR]; // 设备数组

// 获取空设备
static device_t *get_null_device()
{
for (size_t i = 1; i < DEVICE_NR; i++)
{
device_t *device = &devices[i];
if (device->type == DEV_NULL)
return device;
}
panic("no more devices!!!");
}

int device_ioctl(dev_t dev, int cmd, void *args, int flags)
{
device_t *device = device_get(dev);
if (device->ioctl)
{
return device->ioctl(device->ptr, cmd, args, flags);
}
LOGK("ioctl of device %d not implemented!!!\n", dev);
return EOF;
}

int device_read(dev_t dev, void *buf, size_t count, idx_t idx, int flags)
{
device_t *device = device_get(dev);
if (device->read)
{
return device->read(device->ptr, buf, count, idx, flags);
}
LOGK("read of device %d not implemented!!!\n", dev);
return EOF;
}

int device_write(dev_t dev, void *buf, size_t count, idx_t idx, int flags)
{
device_t *device = device_get(dev);
if (device->write)
{
return device->write(device->ptr, buf, count, idx, flags);
}
LOGK("write of device %d not implemented!!!\n", dev);
return EOF;
}

// 安装设备
dev_t device_install(
int type, int subtype,
void *ptr, char *name, dev_t parent,
void *ioctl, void *read, void *write)
{
device_t *device = get_null_device();
device->ptr = ptr;
device->parent = parent;
device->type = type;
device->subtype = subtype;
strncpy(device->name, name, NAMELEN);
device->ioctl = ioctl;
device->read = read;
device->write = write;
return device->dev;
}

void device_init()
{
for (size_t i = 0; i < DEVICE_NR; i++)
{
device_t *device = &devices[i];
strcpy((char *)device->name, "null");
device->type = DEV_NULL;
device->subtype = DEV_NULL;
device->dev = i;
device->parent = 0;
device->ioctl = NULL;
device->read = NULL;
device->write = NULL;
}
}

device_t *device_find(int subtype, idx_t idx)
{
idx_t nr = 0;
for (size_t i = 0; i < DEVICE_NR; i++)
{
device_t *device = &devices[i];
if (device->subtype != subtype)
continue;
if (nr == idx)
return device;
nr++;
}
return NULL;
}

device_t *device_get(dev_t dev)
{
assert(dev < DEVICE_NR);
device_t *device = &devices[dev];
assert(device->type != DEV_NULL);
return device;
}
16 changes: 15 additions & 1 deletion src/kernel/gate.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <onix/task.h>
#include <onix/console.h>
#include <onix/memory.h>
#include <onix/device.h>

#define LOGK(fmt, args...) DEBUGK(fmt, ##args)

Expand All @@ -27,14 +28,27 @@ static void sys_default()

static u32 sys_test()
{
char ch;
device_t *device;

device = device_find(DEV_KEYBOARD, 0);
assert(device);
device_read(device->dev, &ch, 1, 0, 0);

device = device_find(DEV_CONSOLE, 0);
assert(device);
device_write(device->dev, &ch, 1, 0, 0);

return 255;
}

extern int32 console_write();

int32 sys_write(fd_t fd, char *buf, u32 len)
{
if (fd == stdout || fd == stderr)
{
return console_write(buf, len);
return console_write(NULL, buf, len);
}
// todo
panic("write!!!!");
Expand Down
8 changes: 7 additions & 1 deletion src/kernel/keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <onix/fifo.h>
#include <onix/mutex.h>
#include <onix/task.h>
#include <onix/device.h>

#define LOGK(fmt, args...) DEBUGK(fmt, ##args)

Expand Down Expand Up @@ -391,7 +392,7 @@ void keyboard_handler(int vector)
}
}

u32 keyboard_read(char *buf, u32 count)
u32 keyboard_read(void *dev, char *buf, u32 count)
{
lock_acquire(&lock);
int nr = 0;
Expand Down Expand Up @@ -423,4 +424,9 @@ void keyboard_init()

set_interrupt_handler(IRQ_KEYBOARD, keyboard_handler);
set_interrupt_mask(IRQ_KEYBOARD, true);

device_install(
DEV_CHAR, DEV_KEYBOARD,
NULL, "keyboard", 0,
NULL, keyboard_read, NULL);
}
4 changes: 3 additions & 1 deletion src/kernel/printk.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include <onix/console.h>
#include <onix/stdio.h>

extern int32 console_write();

static char buf[1024];

int printk(const char *fmt, ...)
Expand All @@ -15,7 +17,7 @@ int printk(const char *fmt, ...)

va_end(args);

console_write(buf, i);
console_write(NULL, buf, i);

return i;
}
2 changes: 2 additions & 0 deletions src/kernel/start.asm
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ header_start:
dd 8 ; size
header_end:

extern device_init
extern console_init
extern gdt_init
extern memory_init
Expand All @@ -32,6 +33,7 @@ _start:
push ebx; ards_count
push eax; magic

call device_init ; 虚拟设备初始化
call console_init ; 控制台初始化

; xchg bx, bx
Expand Down
5 changes: 2 additions & 3 deletions src/kernel/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,7 @@ void test_thread()

while (true)
{
// LOGK("test task %d....\n", counter++);
// BMB;
sleep(2000);
test();
// sleep(10);
}
}
14 changes: 14 additions & 0 deletions src/lib/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,20 @@ char *strcpy(char *dest, const char *src)
}
}

char *strncpy(char *dest, const char *src, size_t count)
{
char *ptr = dest;
size_t nr = 0;
for (; nr < count; nr++)
{
*ptr++ = *src;
if (*src++ == EOS)
return dest;
}
dest[count - 1] = EOS;
return dest;
}

char *strcat(char *dest, const char *src)
{
char *ptr = dest;
Expand Down
1 change: 1 addition & 0 deletions src/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ $(BUILD)/kernel.bin: \
$(BUILD)/kernel/start.o \
$(BUILD)/kernel/main.o \
$(BUILD)/kernel/io.o \
$(BUILD)/kernel/device.o \
$(BUILD)/kernel/console.o \
$(BUILD)/kernel/printk.o \
$(BUILD)/kernel/assert.o \
Expand Down

0 comments on commit d631173

Please sign in to comment.