grub引导内核 如何设置gdt, idt(模仿《30天自制操作系统》开启键盘中断,不成功)

weixin_39410618 2018-08-13 07:08:04
用grub引导后的内核,试图模仿《30天自制操作系统》中开启键盘中断,不能成功。感觉是gdt,idt未能成功设置,不知大侠们有何高招。由于可输入字符有限,一些不相关代码未在其中,汇编的实现与《30天自制操作系统》书中一样未做改动,也未包含在这里。

#include "multiboot2.h"

void myfun (void);
extern int * idt;
void set_8253(void);

typedef struct SEGMENT_DESCRIPTOR {
short limit_low, base_low;
char base_mid, access_right;
char limit_high, base_high;
}__attribute__((packed))SEGMENT_DESCRIPTOR;

typedef struct GATE_DESCRIPTOR {
short offset_low, selector;
char dw_count, access_right;
short offset_high;
}__attribute__((packed))GATE_DESCRIPTOR;

void get_video_addr(void);
void boxfill8 (int * vram, int xsize, int c, int x0, int y0, int x1, int y1);
void init_gdtidt(void);
void set_segmdesc(struct SEGMENT_DESCRIPTOR *sd, unsigned int limit, int base, int ar);
void set_gatedesc(struct GATE_DESCRIPTOR *gd, int offset, int selector, int ar);
void load_gdtr(int limit, int addr);
void load_idtr(int limit, int addr);


void init_pic(void);
void inthandler21(int *esp);
void inthandler2c(int *esp);
void inthandler27(int *esp);

void asm_inthandler21(void);
void asm_inthandler27(void);
void asm_inthandler2c(void);
void asm_inthandler_all(void);
void io_sti(void);
void io_out8(int port, int data);
void io_hlt(void);


typedef char * va_list;

#ifdef __cplusplus
#define _ADDRESSOF(v) ( &reinterpret_cast<const char &>(v) )
#else
#define _ADDRESSOF(v) ( &(v) )
#endif

#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )

#define _crt_va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
#define _crt_va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define _crt_va_end(ap) ( ap = (va_list)0 )

#define Test_va_start _crt_va_start
#define Test_va_arg _crt_va_arg
#define Test_va_end _crt_va_end

#define ZEROPAD 1
#define SIGN 2
#define PLUS 4
#define SPACE 8
#define LEFT 16
#define SPECIAL 32
#define LARGE 64

int _div(long* n,unsigned base);
static inline int isdigit(int ch);
static int skip_atoi(const char **s);
static char *Test_number(char *str, long num, int base, int size, int precision, int type);
int Test_vsprintf(char *buf, const char *fmt, va_list args);
int strnlen(char * s, int precision);

int sprintf(char *buf, const char *fmt, ...);

int kernel_main (unsigned int magic, unsigned int addr) ;

void putfont8 (int * vram, int xsize, int x, int y, int c, char * fontt);
void putfonts8_asc (int *vram, int xsize, int x0, int y0, int c, char * s);
void putblock8_8(int *vram, int vxsize, int pxsize, int pysize, int px0, int py0, int *buf, int bxsize);


char string[256];

void init_mouse_cursor8(int *mouse, int bc);

void * fb;
int * myfb;

void boxfill8 (int * vram, int xsize, int c, int x0, int y0, int x1, int y1);

int kernel_main (unsigned int eax, unsigned int ebx) {

get_video_addr();
myfb = (int *) fb;
boxfill8 (myfb, 1024, 0x008484, 10, 10, 1013, 757);
char * video = 0xb8000;

sprintf(string, "= 0x%x", asm_inthandler21);
putfonts8_asc (myfb, 1024, 120, 120, 0xffffff, string);

init_gdtidt();

init_pic();

io_sti();





io_out8(0x21, 0xf9); /* 开放PIC1和键盘中断(11111001) */
io_out8(0xa1, 0xef); /* 开放鼠标中断(11101111) */



for (;;) {
io_hlt();
}

return 1;
}








void get_video_addr(void) {
struct multiboot_tag *tag;
for (tag = (struct multiboot_tag *) (addr + 8);
tag->type != MULTIBOOT_TAG_TYPE_END;
tag = (struct multiboot_tag *) ((multiboot_uint8_t *) tag + ((tag->size + 7) & ~7))) {

switch (tag->type) {
case MULTIBOOT_TAG_TYPE_FRAMEBUFFER: {
struct multiboot_tag_framebuffer *tagfb = (struct multiboot_tag_framebuffer *) tag;
fb = (void *) (unsigned long) tagfb->common.framebuffer_addr;
}
}
}
}

void boxfill8 (int * vram, int xsize, int c, int x0, int y0, int x1, int y1) {
int x, y;
for (y = y0; y <= y1; y++)
for (x = x0; x <= x1; x++)
*(vram + y * xsize + x) = c;
return;
}

void putfont8 (int * vram, int xsize, int x, int y, int c, char * fontt) {
int i;
int *p;
unsigned char d;
for (i = 0; i < 16; i++) {
d = fontt[i];
p = vram + (y + i) * xsize + x;
if ((d & 0x80) != 0) {*(p + 0) = c;}
if ((d & 0x40) != 0) {*(p + 1) = c;}
if ((d & 0x20) != 0) {*(p + 2) = c;}
if ((d & 0x10) != 0) {*(p + 3) = c;}
if ((d & 0x08) != 0) {*(p + 4) = c;}
if ((d & 0x04) != 0) {*(p + 5) = c;}
if ((d & 0x02) != 0) {*(p + 6) = c;}
if ((d & 0x01) != 0) {*(p + 7) = c;}
}
return;
}

void putfonts8_asc (int *vram, int xsize, int x0, int y0, int c, char * s) {
extern char myfont[4096];
for (; *s != 0; s++) {
putfont8(vram, xsize, x0, y0, c, myfont+ *s * 16 );
x0 +=8;
}
return;
}

void init_mouse_cursor8(int *mouse, int bc)
{
static char cursor[16][16] = {
"**************..",
"*OOOOOOOOOOO*...",
"*OOOOOOOOOO*....",
"*OOOOOOOOO*.....",
"*OOOOOOOO*......",
"*OOOOOOO*.......",
"*OOOOOOO*.......",
"*OOOOOOOO*......",
"*OOOO**OOO*.....",
"*OOO*..*OOO*....",
"*OO*....*OOO*...",
"*O*......*OOO*..",
"**........*OOO*.",
"*..........*OOO*",
"............*OO*",
".............***"
};
int x, y;

for (y = 0; y < 16; y++) {
for (x = 0; x < 16; x++) {
if (cursor[y][x] == '*') {
mouse[y * 16 + x] = 0x000000;
}
if (cursor[y][x] == 'O') {
mouse[y * 16 + x] = 0x00FFFF;
}
if (cursor[y][x] == '.') {
mouse[y * 16 + x] = bc;
}
}
}
return;
}

void putblock8_8(int *vram, int vxsize, int pxsize,
int pysize, int px0, int py0, int *buf, int bxsize)
{
int x, y;
for (y = 0; y < pysize; y++) {
for (x = 0; x < pxsize; x++) {
vram[(py0 + y) * vxsize + (px0 + x)] = buf[y * bxsize + x];
}
}
return;
}

void init_gdtidt(void)
{
struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) 0x0; //0x00270000;
struct GATE_DESCRIPTOR *idt = (struct GATE_DESCRIPTOR *) idt;//0x0026f800;
int i;

for (i = 0; i < 8192; i++) {
set_segmdesc(gdt + i, 0, 0, 0);
}
set_segmdesc(gdt + 1, 0xffffffff, 0x00000000, 0xc092);
set_segmdesc(gdt + 2, 0xffffffff, 0x00000000, 0xc09a);
load_gdtr(0xffff, 0x0);

for (i = 0; i < 256; i++) {
set_gatedesc(idt + i, (int) asm_inthandler_all, 2 * 8, 0x8e);
}
load_idtr(0x7ff, idt);
set_gatedesc(idt + 0x21, (int) asm_inthandler21, 2 * 8, 0x8e);
set_gatedesc(idt + 0x27, (int) asm_inthandler27, 2 * 8, 0x8e);
set_gatedesc(idt + 0x2c, (int) asm_inthandler2c, 2 * 8, 0x8e);


return;
}

void set_segmdesc(struct SEGMENT_DESCRIPTOR *sd, unsigned int limit, int base, int ar)
{
if (limit > 0xfffff) {
ar |= 0x8000;
limit /= 0x1000;
}
sd->limit_low = limit & 0xffff;
sd->base_low = base & 0xffff;
sd->base_mid = (base >> 16) & 0xff;
sd->access_right = ar & 0xff;
sd->limit_high = ((limit >> 16) & 0x0f) | ((ar >> 8) & 0xf0);
sd->base_high = (base >> 24) & 0xff;
return;
}

void set_gatedesc(struct GATE_DESCRIPTOR *gd, int offset, int selector, int ar)
{
gd->offset_low = offset & 0xffff;
gd->selector = selector;
gd->dw_count = (ar >> 8) & 0xff;
gd->access_right = ar & 0xff;
gd->offset_high = (offset >> 16) & 0xffff;
return;
}


#define PIC0_ICW1 0x0020
#define PIC0_OCW2 0x0020
#define PIC0_IMR 0x0021
#define PIC0_ICW2 0x0021
#define PIC0_ICW3 0x0021
#define PIC0_ICW4 0x0021
#define PIC1_ICW1 0x00a0
#define PIC1_OCW2 0x00a0
#define PIC1_IMR 0x00a1
#define PIC1_ICW2 0x00a1
#define PIC1_ICW3 0x00a1
#define PIC1_ICW4 0x00a1


void init_pic(void)

{
io_out8(PIC0_IMR, 0xff );
io_out8(PIC1_IMR, 0xff );

io_out8(PIC0_ICW1, 0x11 );
io_out8(PIC0_ICW2, 0x20 );
io_out8(PIC0_ICW3, 1 << 2);
io_out8(PIC0_ICW4, 0x01 );

io_out8(PIC1_ICW1, 0x11 );
io_out8(PIC1_ICW2, 0x28 );
io_out8(PIC1_ICW3, 2 );
io_out8(PIC1_ICW4, 0x01 );

io_out8(PIC0_IMR, 0xfb );
io_out8(PIC1_IMR, 0xff );

return;
}


void inthandler21(int *esp)

{
io_out8(0x20, 0x61);
boxfill8(myfb, 1024, 0x0, 0, 0, 32 * 8 - 1, 15);
putfonts8_asc(myfb, 1024, 0, 0, 0xffffff, "INT 21 (IRQ-1) : PS/2 keyboard");
// for (;;) {
// io_hlt();
// }
return;
}

void inthandler2c(int *esp)

{

boxfill8(myfb, 1024, 0x0, 0, 0, 32 * 8 - 1, 15);
putfonts8_asc(myfb, 1024, 0, 0, 0xffffff, "INT 2C (IRQ-12) : PS/2 mouse");
// for (;;) {
// io_hlt();
// }
return;
}

void inthandler27(int *esp)

{
io_out8(0x20, 0x67);
return;
}

void inthandler_all(void) {
boxfill8(myfb, 1024, 0x0, 200, 200, 32 * 8 - 1, 15);
putfonts8_asc(myfb, 1024, 200, 200, 0xffffff, "ERROR!");
// for (;;) {
// io_hlt();
// }
return;
}


...全文
313 2 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
ZSP95 2018-08-20
  • 打赏
  • 举报
回复
被邀 但是对于这块 实在知识浅薄 顶下帖子 希望你早日得到解决

4,465

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧