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...
|
||||
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;
|
||||
}
|
||||
|
@ -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');
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user