#2
ditg2020-06-25 16:19
|
先跳入32位保护模式后进入这个c函数
void show()
{
char ss[]="Asd";
bootinfo.p = (bit_8 *)0xa0000;
bootinfo.xsize = 320;
initpalette(); //设置调色板
initscreen(); //初始化窗口
showstr(bootinfo.p,bootinfo.xsize,5,5,COLOR_3,ss); //显示文字Asd
initGDT();
initIDT();
initPIC();
io_sti();
}
关键是initGDT initIDT initPIC 这三个函数分别是初始化GDT 、 IDT 和PIC 我不知道把设置PIC放在最后对不对, 我在initGDT和initIDT中都重新加载了新的GDT和IDT加载函数是用汇编写的,in_out8是把一个值写入一个端口,这些函数细节如下
load_gdtr:
mov edx,[esp+4]
lgdt [edx]
ret
load_idtr:
mov edx,[esp+4]
lidt [edx]
ret
io_out8:
mov edx,[esp+4]
mov al,[esp+8]
out dx,al
ret
然后这三个c函数
#define AR_DATA32_RW 0x4092
#define AR_CODE32_ER 0x409a
#define AR_INTGATE32 0x008e
void initGDT()
{
setdesc(GDT_NEW + 1, 0xffffffff, 0x00000000, AR_CODE32_ER);
setdesc(GDT_NEW + 2, 0xffffffff, 0x00000000, AR_DATA32_RW);
*((bit_16 *)&GDTR_NEW) = 0xffff;
*((bit_32 *)(&GDTR_NEW[2])) = (bit_32)&GDT_NEW;
load_gdtr((bit_32)&GDTR_NEW);
return;
}
void setdesc(DESCRIPTOR * p,bit_32 limit,bit_32 base,bit_16 access)
{
if(limit > 0xfffff)
{
access |= 0x8000;
limit /= 0x1000;
}
p -> base_low = base & 0xffff;
p -> base_mid = (base >> 16) & 0xff;
p -> base_high = (base >> 24) & 0xff;
p -> access = access & 0xff;
p -> limit_low = limit & 0xffff;
p -> limit_high = ((limit >> 16) & 0x0f) | ((access >> 8) & 0xf0);
return;
}
void setgate(GATE * p,bit_32 offset,bit_16 selector,bit_16 access)
{
p -> offset_low = offset & 0xffff;
p -> offset_high = (offset >> 16) & 0xffff;
p -> selector = selector;
p -> access = access & 0xff;
p -> count = (access >> 8) & 0xff;
return;
}
void initIDT()
{
setgate(&IDT_NEW[0x21],(bit_32)asm_inthandler21,1 * 8,AR_INTGATE32);
*((bit_16 *)(&IDTR_NEW)) = sizeof(GATE) * 256 - 1;
*((bit_32 *)(&IDTR_NEW[2])) = (bit_32)(&IDT_NEW);
load_idtr((bit_32)&IDTR_NEW);
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 initPIC()
{
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(bit_32 * esp)
{
char ss[]="keyboard";
showstr(bootinfo.p,bootinfo.xsize,25,25,COLOR_3,ss);
return;
}