Usermode can now use ports! (IOPB test)

This commit is contained in:
pjht 2019-02-10 18:09:07 -06:00
parent 03109a25ca
commit cb16df6240
2 changed files with 40 additions and 22 deletions

View File

@ -46,6 +46,8 @@ typedef struct {
uint32_t ldt; // Unused...
uint16_t trap;
uint16_t iomap_base;
char iopb[8192]; // IO port bitmap
uint8_t set_ff;
} __attribute__((packed)) tss_entry;
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) {
// Firstly, let's compute the base and limit of our entry into the GDT.
uint32_t base = (uint32_t) &tss;
uint32_t limit = base + sizeof(tss_entry);
// Firstly, let's compute the base and limit of our entry into the GDT.
uint32_t base = (uint32_t) &tss;
uint32_t limit = base + sizeof(tss_entry);
// Now, add our TSS descriptor's address to the GDT.
gdt[num].limit_low16=limit&0xFFFF;
gdt[num].base_low16=base&0xFFFFF;
gdt[num].base_mid8=(base&0xFF0000)>>16;
gdt[num].access=0xe9;
gdt[num].limit_flags=(limit&0xF0000)>>16;
gdt[num].base_high8=(base&0xFF000000)>>24;
// Now, add our TSS descriptor's address to the GDT.
gdt[num].limit_low16=limit&0xFFFF;
gdt[num].base_low16=base&0xFFFFF;
gdt[num].base_mid8=(base&0xFF0000)>>16;
gdt[num].access=0xe9;
gdt[num].limit_flags=(limit&0xF0000)>>16;
gdt[num].base_high8=(base&0xFF000000)>>24;
// Ensure the descriptor is initially zero.
memset((void*)&tss,0,sizeof(tss));
tss.ss0 = ss0; // Set the kernel stack segment.
tss.esp0 = esp0; // Set the kernel stack pointer.
// Ensure the descriptor is initially zero.
memset((void*)&tss,0,sizeof(tss));
tss.ss0 = ss0; // Set the kernel stack segment.
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
// 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;
//Set the last byte to 0xFF (End marker for IOPB)
tss.set_ff=0xFF;
// Now, set the offset for the IOPB
// (All ports are already OK from the zeroing)
tss.iomap_base=104;
// 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;
}

View File

@ -1,4 +1,5 @@
#include "../cpu/cpu_init.h"
#include "../cpu/i386/ports.h"
#include "../drivers/vga.h"
#include <grub/text_fb_info.h>
#include <stdlib.h>
@ -39,4 +40,11 @@ void kmain(multiboot_info_t* header) {
1: \
");
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');
}