Usermode can now use ports! (IOPB test)
This commit is contained in:
parent
03109a25ca
commit
cb16df6240
@ -46,6 +46,8 @@ typedef struct {
|
|||||||
uint32_t ldt; // Unused...
|
uint32_t ldt; // Unused...
|
||||||
uint16_t trap;
|
uint16_t trap;
|
||||||
uint16_t iomap_base;
|
uint16_t iomap_base;
|
||||||
|
char iopb[8192]; // IO port bitmap
|
||||||
|
uint8_t set_ff;
|
||||||
} __attribute__((packed)) tss_entry;
|
} __attribute__((packed)) tss_entry;
|
||||||
|
|
||||||
gdt_entry gdt[NUM_ENTRIES];
|
gdt_entry gdt[NUM_ENTRIES];
|
||||||
@ -79,29 +81,37 @@ void set_entry(int i,uint32_t base,uint32_t limit,uint8_t access) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void write_tss(int32_t num, uint16_t ss0, uint32_t esp0) {
|
void write_tss(int32_t num, uint16_t ss0, uint32_t esp0) {
|
||||||
// Firstly, let's compute the base and limit of our entry into the GDT.
|
// Firstly, let's compute the base and limit of our entry into the GDT.
|
||||||
uint32_t base = (uint32_t) &tss;
|
uint32_t base = (uint32_t) &tss;
|
||||||
uint32_t limit = base + sizeof(tss_entry);
|
uint32_t limit = base + sizeof(tss_entry);
|
||||||
|
|
||||||
// Now, add our TSS descriptor's address to the GDT.
|
// Now, add our TSS descriptor's address to the GDT.
|
||||||
gdt[num].limit_low16=limit&0xFFFF;
|
gdt[num].limit_low16=limit&0xFFFF;
|
||||||
gdt[num].base_low16=base&0xFFFFF;
|
gdt[num].base_low16=base&0xFFFFF;
|
||||||
gdt[num].base_mid8=(base&0xFF0000)>>16;
|
gdt[num].base_mid8=(base&0xFF0000)>>16;
|
||||||
gdt[num].access=0xe9;
|
gdt[num].access=0xe9;
|
||||||
gdt[num].limit_flags=(limit&0xF0000)>>16;
|
gdt[num].limit_flags=(limit&0xF0000)>>16;
|
||||||
gdt[num].base_high8=(base&0xFF000000)>>24;
|
gdt[num].base_high8=(base&0xFF000000)>>24;
|
||||||
|
|
||||||
// Ensure the descriptor is initially zero.
|
// Ensure the descriptor is initially zero.
|
||||||
memset((void*)&tss,0,sizeof(tss));
|
memset((void*)&tss,0,sizeof(tss));
|
||||||
tss.ss0 = ss0; // Set the kernel stack segment.
|
tss.ss0 = ss0; // Set the kernel stack segment.
|
||||||
tss.esp0 = esp0; // Set the kernel stack pointer.
|
tss.esp0 = esp0; // Set the kernel stack pointer.
|
||||||
|
|
||||||
// Here we set the cs, ss, ds, es, fs and gs entries in the TSS. These specify what
|
//Set the last byte to 0xFF (End marker for IOPB)
|
||||||
// segments should be loaded when the processor switches to kernel mode. Therefore
|
tss.set_ff=0xFF;
|
||||||
// they are just our normal kernel code/data segments - 0x08 and 0x10 respectively,
|
|
||||||
// but with the last two bits set, making 0x0b and 0x13. The setting of these bits
|
// Now, set the offset for the IOPB
|
||||||
// sets the RPL (requested privilege level) to 3, meaning that this TSS can be used
|
// (All ports are already OK from the zeroing)
|
||||||
// to switch to kernel mode from ring 3.
|
tss.iomap_base=104;
|
||||||
tss.cs = 0x0b;
|
|
||||||
tss.ss = tss.ds = tss.es = tss.fs = tss.gs = 0x13;
|
|
||||||
|
// Here we set the cs, ss, ds, es, fs and gs entries in the TSS. These specify what
|
||||||
|
// segments should be loaded when the processor switches to kernel mode. Therefore
|
||||||
|
// they are just our normal kernel code/data segments - 0x08 and 0x10 respectively,
|
||||||
|
// but with the last two bits set, making 0x0b and 0x13. The setting of these bits
|
||||||
|
// sets the RPL (requested privilege level) to 3, meaning that this TSS can be used
|
||||||
|
// to switch to kernel mode from ring 3.
|
||||||
|
tss.cs = 0x0b;
|
||||||
|
tss.ss = tss.ds = tss.es = tss.fs = tss.gs = 0x13;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "../cpu/cpu_init.h"
|
#include "../cpu/cpu_init.h"
|
||||||
|
#include "../cpu/i386/ports.h"
|
||||||
#include "../drivers/vga.h"
|
#include "../drivers/vga.h"
|
||||||
#include <grub/text_fb_info.h>
|
#include <grub/text_fb_info.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -39,4 +40,11 @@ void kmain(multiboot_info_t* header) {
|
|||||||
1: \
|
1: \
|
||||||
");
|
");
|
||||||
vga_write_string("UMODE!\n");
|
vga_write_string("UMODE!\n");
|
||||||
|
port_byte_out(0xe9,'U');
|
||||||
|
port_byte_out(0xe9,'M');
|
||||||
|
port_byte_out(0xe9,'O');
|
||||||
|
port_byte_out(0xe9,'D');
|
||||||
|
port_byte_out(0xe9,'E');
|
||||||
|
port_byte_out(0xe9,'!');
|
||||||
|
port_byte_out(0xe9,'\n');
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user