better mouse driver
This commit is contained in:
parent
88ec7f1be2
commit
4f3db9a86e
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
obj/
|
||||
iso/
|
||||
.vscode/
|
||||
@ -15,7 +15,7 @@
|
||||
/* Macros Declaration */
|
||||
/************************************************************************/
|
||||
#define KB_IN_BYTES 320 /* size of keyboard input buffer */ /* FIXME */
|
||||
#define MOUSE_IN_BYTES 3
|
||||
#define MOUSE_IN_BYTES 4
|
||||
#define MAP_COLS 3 /* Number of columns in keymap */
|
||||
#define NR_SCAN_CODES 0x80 /* Number of scan codes (rows in keymap) */
|
||||
|
||||
@ -119,7 +119,18 @@
|
||||
#define PAD_MID PAD_5 /* Middle key */
|
||||
#define PAD_DEL PAD_DOT /* Del */
|
||||
|
||||
#define PS2_PORT_DATA (0x60)
|
||||
#define PS2_PORT_CMD (0x64)
|
||||
|
||||
#define PS2_CMD_2ND_OUT (0xD4)
|
||||
#define PS2_CMD_2ND_ENB (0xA8)
|
||||
#define PS2_CMD_READRAM (0x20)
|
||||
#define PS2_CMD_SET_DEFAULT (0xF6)
|
||||
#define PS2_CMD_DATA_REPORT_DIS (0xF5)
|
||||
#define PS2_CMD_DATA_REPORT_ENB (0xF4)
|
||||
#define PS2_CMD_SAMPLE_RATE (0xF3)
|
||||
#define PS2_CMD_GET_DEVICE (0xF2)
|
||||
#define PS2_ACK (0xfa)
|
||||
/************************************************************************/
|
||||
/* Stucture Definition */
|
||||
/************************************************************************/
|
||||
|
||||
@ -1217,8 +1217,8 @@ static int do_rdwt(MESSAGE *fs_msg)
|
||||
//added by mingxuan 2019-5-19
|
||||
int dev = pin->i_start_sect;
|
||||
int nr_tty = MINOR(dev);
|
||||
if(MAJOR(dev) != 4) {
|
||||
panic("Error: MAJOR(dev) == 4\n");
|
||||
if(MAJOR(dev) != DEV_CHAR_TTY) {
|
||||
panic("Error: MAJOR(dev) should be DEV_CHAR_TTY(4)\n");
|
||||
}
|
||||
|
||||
if(fs_msg->type == DEV_READ){
|
||||
|
||||
@ -10,6 +10,8 @@
|
||||
#include "keyboard.h"
|
||||
#include "keymap.h"
|
||||
#include "x86.h"
|
||||
#include "stdio.h"
|
||||
#include "assert.h"
|
||||
|
||||
|
||||
static KB_INPUT kb_in;
|
||||
@ -33,10 +35,54 @@ static void set_leds();
|
||||
static void set_mouse_leds();
|
||||
static void kb_wait();
|
||||
// static void kb_ack();
|
||||
/*
|
||||
* Helper Procedures for PS/2 Mouse Operation
|
||||
* */
|
||||
static void mouse_wait(u8 a_type) {
|
||||
int _time_out=100000;
|
||||
if(a_type==0) {
|
||||
while(_time_out--) if((inb(PS2_PORT_CMD) & 1)==1) return;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
while(_time_out--) if((inb(PS2_PORT_CMD) & 2)==0) return;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void mouse_write(u8 a_write) {
|
||||
mouse_wait(1);//Wait to be able to send a command
|
||||
outb(PS2_PORT_CMD, PS2_CMD_2ND_OUT);//Tell the mouse we are sending a command
|
||||
mouse_wait(1);//Wait for the final part
|
||||
outb(PS2_PORT_DATA, a_write);//Finally write
|
||||
}
|
||||
|
||||
//Get's response from mouse
|
||||
static u8 mouse_read() {
|
||||
mouse_wait(0);
|
||||
return inb(PS2_PORT_DATA);
|
||||
}
|
||||
|
||||
static void mouse_set_rate(u8 rate) {
|
||||
mouse_write(0xf3); // set sample rate cmd
|
||||
assert(mouse_read() == PS2_ACK);
|
||||
mouse_write(rate);
|
||||
assert(mouse_read() == PS2_ACK);
|
||||
}
|
||||
|
||||
static u8 mouse_get_id() {
|
||||
mouse_write(PS2_CMD_DATA_REPORT_DIS);
|
||||
assert(mouse_read() == PS2_ACK);
|
||||
mouse_write(PS2_CMD_GET_DEVICE); // report
|
||||
assert(mouse_read() == PS2_ACK);
|
||||
u8 device_type = mouse_read();
|
||||
mouse_write(PS2_CMD_DATA_REPORT_ENB);
|
||||
assert(mouse_read() == PS2_ACK);
|
||||
return device_type;
|
||||
}
|
||||
|
||||
void kb_handler(int irq){
|
||||
u8 scan_code = inb(0x60);
|
||||
u8 scan_code = inb(PS2_PORT_DATA);
|
||||
if(kb_in.count < KB_IN_BYTES){
|
||||
*(kb_in.p_head) = scan_code;
|
||||
kb_in.p_head++;
|
||||
@ -52,14 +98,13 @@ void kb_handler(int irq){
|
||||
#define TTY_END (tty_table+NR_CONSOLES)
|
||||
|
||||
void mouse_handler(int irq){
|
||||
u8 scan_code = inb(0x60);
|
||||
if(!mouse_init){
|
||||
mouse_init = 1;
|
||||
return;
|
||||
}
|
||||
u8 scan_code = inb(PS2_PORT_DATA);
|
||||
|
||||
mouse_in.buf[mouse_in.count]=scan_code;
|
||||
mouse_in.count++;
|
||||
if(mouse_in.count==3){
|
||||
if ((mouse_in.buf[0] & 0xc8) == 0x08)
|
||||
mouse_in.count++; // simple trick to sync mouse data
|
||||
if(mouse_in.count==4){
|
||||
// printf("0x%02x 0x%02x 0x%02x 0x%02x\n", mouse_in.buf[0], mouse_in.buf[1], mouse_in.buf[2], mouse_in.buf[3]);
|
||||
TTY* p_tty;
|
||||
for (p_tty = TTY_FIRST; p_tty < TTY_END; p_tty++) {
|
||||
if(p_tty->console==&console_table[current_console]){
|
||||
@ -92,8 +137,6 @@ void mouse_handler(int irq){
|
||||
|
||||
mouse_in.count=0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void init_mouse(){
|
||||
@ -101,7 +144,28 @@ void init_mouse(){
|
||||
|
||||
put_irq_handler(MOUSE_IRQ,mouse_handler);
|
||||
enable_irq(MOUSE_IRQ);
|
||||
mouse_wait(1);
|
||||
outb(PS2_PORT_CMD, PS2_CMD_2ND_ENB); // Enable second PS/2 port
|
||||
mouse_wait(1);
|
||||
outb(PS2_PORT_CMD, PS2_CMD_READRAM);// Read "byte 0" from internal RAM
|
||||
mouse_wait(0);
|
||||
u8 _status = inb(PS2_PORT_DATA) | 0x2; // bit-1 <=> Second PS/2 port interrupt
|
||||
mouse_wait(1);
|
||||
outb(PS2_PORT_CMD, PS2_PORT_DATA); // Write next byte to "byte 0" of internal RAM
|
||||
mouse_wait(1);
|
||||
outb(PS2_PORT_DATA, _status); // Write back to internal RAM
|
||||
|
||||
mouse_write(PS2_CMD_SET_DEFAULT); // Set Defaults
|
||||
assert(mouse_read() == PS2_ACK);
|
||||
mouse_write(PS2_CMD_DATA_REPORT_ENB); // Enable Data Reporting
|
||||
assert(mouse_read() == PS2_ACK); // Remember to read ACK, or it may block
|
||||
assert(mouse_get_id() == 0x00); // by init, id should be 0(standard ps/2 mouse)
|
||||
mouse_set_rate(200);
|
||||
mouse_set_rate(100);
|
||||
mouse_set_rate(80); // tricks to enable z-axis, from osdev
|
||||
assert(mouse_get_id() == 0x03); // z-axis enabled, id should be 3 (Mouse with scroll wheel)
|
||||
mouse_write(PS2_CMD_DATA_REPORT_ENB);
|
||||
assert(mouse_read() == PS2_ACK);
|
||||
}
|
||||
|
||||
void init_kb(){
|
||||
|
||||
@ -325,7 +325,7 @@ int do_vwrite(int fd, const char *buf, int count) {
|
||||
bytes = vfs_table[index].op->write(fd,s,iobytes); //modified by mingxuan 2020-10-18
|
||||
if(bytes != iobytes)
|
||||
{
|
||||
return bytes;
|
||||
return bytes; // TODO: Maybe problematic
|
||||
}
|
||||
f_len -= bytes;
|
||||
}
|
||||
|
||||
19
注释.md
Normal file
19
注释.md
Normal file
@ -0,0 +1,19 @@
|
||||
# 代码注释
|
||||
|
||||
## 文件系统逻辑
|
||||
文件系统里面的东西写的比较奇怪,他的目录构成是这样的:
|
||||
```
|
||||
<设备名>/<路径名>
|
||||
```
|
||||
|
||||
在open调用里面有一个`get_index`(kernel/vfs.c:175), 它会自动把第一个`/`前面的部分作为设备名,然后在文件系统的描述符表中去匹配。然后返回设备编号。同时还会更新原来传进去的路径名,把前面的设备名称和`/`给去掉,取后面的路径名。这个东西写的真的很奇怪。。。由于它意义不明的代码,对于没有`/`存在的路径名,他的设备名就是路径名。
|
||||
|
||||
对于字节设备而言,open/close/read/lseek/unlink貌似都是直接转发到`real_<operation>`(kernel/fs.c)里面,也就是在初始化的时候给进去的函数指针。open/unlink有一个处理设备名的过程,这个设计可以说是很智障了。write操作有些许不同,他是将字节划分成512字节的小块写入设备,不过他的实现好想,有点小问题。。。
|
||||
|
||||
tty设备占据vfs表的前三项,分别对应tty0-2,然后每个设备都会分配一个超级块superblock,不过这三个设备的操作都是一样的。
|
||||
|
||||
在文件系统初始化的时候,会专门给tty分配inode,然后把inode的`start_sect`设置为`(DEV_CHAR_TTY<<8)|<tty_id>`,后面就用这个来确定tty号;然后还会特地设置他的inode_nr以便后面匹配inode。然后在open的时候,首先根据路径名,从root inode开始匹配inode的名字,然后返回一个inode_nr(可以看做是inode指针);会根据设备和inode_nr来获取最终的inode,最后塞进文件描述符表中。
|
||||
|
||||
真正调用tty的地方是在kernel/fs.c:do_rdwt,他会判断出打开的设备是啥,然后调用`tty_read/write`来进行实际的读写。
|
||||
|
||||
## 键盘和tty
|
||||
Loading…
Reference in New Issue
Block a user