Syscalls working! Keyboard driver must run in kmode unfortunately :(
This commit is contained in:
parent
ae5b1ad448
commit
00f066fc9b
@ -1,34 +0,0 @@
|
|||||||
gdt_start: ; don't remove the labels, they're needed to compute sizes and jumps
|
|
||||||
; the GDT starts with a null 8-byte
|
|
||||||
dd 0x0 ; 4 byte
|
|
||||||
dd 0x0 ; 4 byte
|
|
||||||
|
|
||||||
; GDT for code segment. base = 0x00000000, length = 0xfffff
|
|
||||||
; for flags, refer to os-dev.pdf document, page 36
|
|
||||||
gdt_code:
|
|
||||||
dw 0x0000 ; segment length, bits 0-15
|
|
||||||
dw 0x0 ; segment base, bits 0-15
|
|
||||||
db 0x0 ; segment base, bits 16-23
|
|
||||||
db 10011010b ; flags (8 bits)
|
|
||||||
db 11000001b ; flags (4 bits) + segment length, bits 16-19
|
|
||||||
db 0x0 ; segment base, bits 24-31
|
|
||||||
|
|
||||||
; GDT for data segment. base and length identical to code segment
|
|
||||||
; some flags changed, again, refer to os-dev.pdf
|
|
||||||
gdt_data:
|
|
||||||
dw 0x0000
|
|
||||||
dw 0x0
|
|
||||||
db 0x0
|
|
||||||
db 10010010b
|
|
||||||
db 11000001b
|
|
||||||
|
|
||||||
gdt_end:
|
|
||||||
|
|
||||||
; GDT descriptor
|
|
||||||
gdt_descriptor:
|
|
||||||
dw gdt_end - gdt_start - 1 ; size (16 bit), always one less of its true size
|
|
||||||
dd gdt_start ; address (32 bit)
|
|
||||||
|
|
||||||
; define some constants for later use
|
|
||||||
CODE_SEG equ gdt_code - gdt_start
|
|
||||||
DATA_SEG equ gdt_data - gdt_start
|
|
80
bochsout.txt
80
bochsout.txt
@ -33,39 +33,39 @@
|
|||||||
00000000000i[ ] Sound support: no
|
00000000000i[ ] Sound support: no
|
||||||
00000000000i[ ] USB support: UHCI
|
00000000000i[ ] USB support: UHCI
|
||||||
00000000000i[ ] VGA extension support: vbe cirrus
|
00000000000i[ ] VGA extension support: vbe cirrus
|
||||||
00000000000i[MEM0 ] allocated memory at 0x10a780000. after alignment, vector=0x10a780000
|
00000000000i[MEM0 ] allocated memory at 0x10684c000. after alignment, vector=0x10684c000
|
||||||
00000000000i[MEM0 ] 32.00MB
|
00000000000i[MEM0 ] 32.00MB
|
||||||
00000000000i[MEM0 ] mem block size = 0x00020000, blocks=256
|
00000000000i[MEM0 ] mem block size = 0x00020000, blocks=256
|
||||||
00000000000i[MEM0 ] rom at 0xfffe0000/131072 ('/usr/local/Cellar/bochs/2.6.9_2/share/bochs/BIOS-bochs-latest')
|
00000000000i[MEM0 ] rom at 0xfffe0000/131072 ('/usr/local/Cellar/bochs/2.6.9_2/share/bochs/BIOS-bochs-latest')
|
||||||
00000000000i[ ] lt_dlhandle is 0x7fa5fec76d60
|
00000000000i[ ] lt_dlhandle is 0x7fd0b3e74bd0
|
||||||
00000000000i[PLUGIN] loaded plugin libbx_hdimage.so
|
00000000000i[PLUGIN] loaded plugin libbx_hdimage.so
|
||||||
00000000000i[ ] lt_dlhandle is 0x7fa5fef32320
|
00000000000i[ ] lt_dlhandle is 0x7fd0b3e63650
|
||||||
00000000000i[PLUGIN] loaded plugin libbx_pci.so
|
00000000000i[PLUGIN] loaded plugin libbx_pci.so
|
||||||
00000000000i[ ] lt_dlhandle is 0x7fa5fec77050
|
00000000000i[ ] lt_dlhandle is 0x7fd0b605b640
|
||||||
00000000000i[PLUGIN] loaded plugin libbx_pci2isa.so
|
00000000000i[PLUGIN] loaded plugin libbx_pci2isa.so
|
||||||
00000000000i[ ] lt_dlhandle is 0x7fa5fec77450
|
00000000000i[ ] lt_dlhandle is 0x7fd0b3c43400
|
||||||
00000000000i[PLUGIN] loaded plugin libbx_usb_uhci.so
|
00000000000i[PLUGIN] loaded plugin libbx_usb_uhci.so
|
||||||
00000000000i[ ] lt_dlhandle is 0x7fa5fef33ad0
|
00000000000i[ ] lt_dlhandle is 0x7fd0b3c44e70
|
||||||
00000000000i[PLUGIN] loaded plugin libbx_acpi.so
|
00000000000i[PLUGIN] loaded plugin libbx_acpi.so
|
||||||
00000000000i[ ] lt_dlhandle is 0x7fa60106e670
|
00000000000i[ ] lt_dlhandle is 0x7fd0b3c453f0
|
||||||
00000000000i[PLUGIN] loaded plugin libbx_cmos.so
|
00000000000i[PLUGIN] loaded plugin libbx_cmos.so
|
||||||
00000000000i[ ] lt_dlhandle is 0x7fa5fec77dc0
|
00000000000i[ ] lt_dlhandle is 0x7fd0b3c454b0
|
||||||
00000000000i[PLUGIN] loaded plugin libbx_dma.so
|
00000000000i[PLUGIN] loaded plugin libbx_dma.so
|
||||||
00000000000i[ ] lt_dlhandle is 0x7fa5fec78370
|
00000000000i[ ] lt_dlhandle is 0x7fd0b3c45c20
|
||||||
00000000000i[PLUGIN] loaded plugin libbx_pic.so
|
00000000000i[PLUGIN] loaded plugin libbx_pic.so
|
||||||
00000000000i[ ] lt_dlhandle is 0x7fa5fec78530
|
00000000000i[ ] lt_dlhandle is 0x7fd0b3e74f90
|
||||||
00000000000i[PLUGIN] loaded plugin libbx_pit.so
|
00000000000i[PLUGIN] loaded plugin libbx_pit.so
|
||||||
00000000000i[ ] lt_dlhandle is 0x7fa5fec78920
|
00000000000i[ ] lt_dlhandle is 0x7fd0b605c180
|
||||||
00000000000i[PLUGIN] loaded plugin libbx_vga.so
|
00000000000i[PLUGIN] loaded plugin libbx_vga.so
|
||||||
00000000000i[ ] lt_dlhandle is 0x7fa5fed37690
|
00000000000i[ ] lt_dlhandle is 0x7fd0b605c3c0
|
||||||
00000000000i[PLUGIN] loaded plugin libbx_floppy.so
|
00000000000i[PLUGIN] loaded plugin libbx_floppy.so
|
||||||
00000000000i[ ] lt_dlhandle is 0x7fa5fed37c80
|
00000000000i[ ] lt_dlhandle is 0x7fd0b3e75870
|
||||||
00000000000i[PLUGIN] loaded plugin libbx_ioapic.so
|
00000000000i[PLUGIN] loaded plugin libbx_ioapic.so
|
||||||
00000000000i[ ] lt_dlhandle is 0x7fa5fec78db0
|
00000000000i[ ] lt_dlhandle is 0x7fd0b3f3b4a0
|
||||||
00000000000i[PLUGIN] loaded plugin libbx_keyboard.so
|
00000000000i[PLUGIN] loaded plugin libbx_keyboard.so
|
||||||
00000000000i[ ] lt_dlhandle is 0x7fa60106ef50
|
00000000000i[ ] lt_dlhandle is 0x7fd0b3e76020
|
||||||
00000000000i[PLUGIN] loaded plugin libbx_harddrv.so
|
00000000000i[PLUGIN] loaded plugin libbx_harddrv.so
|
||||||
00000000000i[ ] lt_dlhandle is 0x7fa5fec79570
|
00000000000i[ ] lt_dlhandle is 0x7fd0b605c680
|
||||||
00000000000i[PLUGIN] loaded plugin libbx_pci_ide.so
|
00000000000i[PLUGIN] loaded plugin libbx_pci_ide.so
|
||||||
00000000000i[PLUGIN] init_dev of 'pci' plugin device by virtual method
|
00000000000i[PLUGIN] init_dev of 'pci' plugin device by virtual method
|
||||||
00000000000i[DEV ] i440FX PMC present at device 0, function 0
|
00000000000i[DEV ] i440FX PMC present at device 0, function 0
|
||||||
@ -73,7 +73,7 @@
|
|||||||
00000000000i[DEV ] PIIX3 PCI-to-ISA bridge present at device 1, function 0
|
00000000000i[DEV ] PIIX3 PCI-to-ISA bridge present at device 1, function 0
|
||||||
00000000000i[PLUGIN] init_dev of 'cmos' plugin device by virtual method
|
00000000000i[PLUGIN] init_dev of 'cmos' plugin device by virtual method
|
||||||
00000000000i[CMOS ] Using local time for initial clock
|
00000000000i[CMOS ] Using local time for initial clock
|
||||||
00000000000i[CMOS ] Setting initial clock to: Sat Oct 20 11:17:35 2018 (time0=1540052255)
|
00000000000i[CMOS ] Setting initial clock to: Sun Oct 21 17:00:42 2018 (time0=1540159242)
|
||||||
00000000000i[PLUGIN] init_dev of 'dma' plugin device by virtual method
|
00000000000i[PLUGIN] init_dev of 'dma' plugin device by virtual method
|
||||||
00000000000i[DMA ] channel 4 used by cascade
|
00000000000i[DMA ] channel 4 used by cascade
|
||||||
00000000000i[PLUGIN] init_dev of 'pic' plugin device by virtual method
|
00000000000i[PLUGIN] init_dev of 'pic' plugin device by virtual method
|
||||||
@ -220,30 +220,28 @@
|
|||||||
00001531591i[BXVGA ] VBE known Display Interface b0c5
|
00001531591i[BXVGA ] VBE known Display Interface b0c5
|
||||||
00001534516i[VBIOS ] VBE Bios $Id: vbe.c,v 1.65 2014/07/08 18:02:25 vruppert Exp $
|
00001534516i[VBIOS ] VBE Bios $Id: vbe.c,v 1.65 2014/07/08 18:02:25 vruppert Exp $
|
||||||
00014040189i[BIOS ] Booting from 0000:7c00
|
00014040189i[BIOS ] Booting from 0000:7c00
|
||||||
00014771579i[FLOPPY] partial read() on floppy image returns 128/512
|
00014771579i[FLOPPY] partial read() on floppy image returns 384/512
|
||||||
00014816023i[FLOPPY] read() on floppy image returns 0
|
00014816023i[FLOPPY] read() on floppy image returns 0
|
||||||
00014860467i[FLOPPY] read() on floppy image returns 0
|
00014860467i[FLOPPY] read() on floppy image returns 0
|
||||||
00014904911i[FLOPPY] read() on floppy image returns 0
|
00014904911i[FLOPPY] read() on floppy image returns 0
|
||||||
00015045640e[CPU0 ] fetch_raw_descriptor: GDT: index (2f) 5 > limit (27)
|
00042328074i[CPU0 ] WARNING: HLT instruction with IF=0!
|
||||||
00015051260i[CPU0 ] WARNING: HLT instruction with IF=0!
|
00340680000p[SDL2 ] >>PANIC<< User requested shutdown.
|
||||||
00482728000i[ ] Ctrl-C detected in signal handler.
|
00340680000i[CPU0 ] CPU is in protected mode (halted)
|
||||||
00482728001i[ ] dbg: Quit
|
00340680000i[CPU0 ] CS.mode = 32 bit
|
||||||
00482728001i[CPU0 ] CPU is in protected mode (halted)
|
00340680000i[CPU0 ] SS.mode = 32 bit
|
||||||
00482728001i[CPU0 ] CS.mode = 32 bit
|
00340680000i[CPU0 ] EFER = 0x00000000
|
||||||
00482728001i[CPU0 ] SS.mode = 32 bit
|
00340680000i[CPU0 ] | EAX=00002700 EBX=0007ff3c ECX=00000000 EDX=000003d5
|
||||||
00482728001i[CPU0 ] EFER = 0x00000000
|
00340680000i[CPU0 ] | ESP=0007ffa0 EBP=0007ffb8 ESI=00080000 EDI=0007ff90
|
||||||
00482728001i[CPU0 ] | EAX=00002000 EBX=00001000 ECX=00000000 EDX=000000a0
|
00340680000i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt of df if tf sf zf af PF cf
|
||||||
00482728001i[CPU0 ] | ESP=0008ff78 EBP=0008ff90 ESI=000e0000 EDI=0000ffac
|
00340680000i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
|
||||||
00482728001i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt of df if tf sf zf af PF cf
|
00340680000i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 ffffffff 1 1
|
||||||
00482728001i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
|
00340680000i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
||||||
00482728001i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 ffffffff 1 1
|
00340680000i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
||||||
00482728001i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
00340680000i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
||||||
00482728001i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
00340680000i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
||||||
00482728001i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
00340680000i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
||||||
00482728001i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
00340680000i[CPU0 ] | EIP=00001c77 (00001c77)
|
||||||
00482728001i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
00340680000i[CPU0 ] | CR0=0x60000011 CR2=0x00000000
|
||||||
00482728001i[CPU0 ] | EIP=000019d4 (000019d4)
|
00340680000i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
|
||||||
00482728001i[CPU0 ] | CR0=0x60000011 CR2=0x00000000
|
00340680000i[CMOS ] Last time is 1540159327 (Sun Oct 21 17:02:07 2018)
|
||||||
00482728001i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
|
00340680000i[SIM ] quit_sim called with exit code 1
|
||||||
00482728001i[CMOS ] Last time is 1540052375 (Sat Oct 20 11:19:35 2018)
|
|
||||||
00482728001i[SIM ] quit_sim called with exit code 0
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "gdt.h"
|
#include "gdt.h"
|
||||||
|
#include "../libc/memory.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
static void gdt_set_gate(int32_t num,uint32_t base,uint32_t limit,uint8_t access,uint8_t gran);
|
static void gdt_set_gate(int32_t num,uint32_t base,uint32_t limit,uint8_t access,uint8_t gran);
|
||||||
@ -16,7 +17,7 @@ gdt_ptr_t gdt_ptr;
|
|||||||
tss_entry_t tss_entry;
|
tss_entry_t tss_entry;
|
||||||
|
|
||||||
void init_gdt() {
|
void init_gdt() {
|
||||||
gdt_ptr.limit=(sizeof(gdt_entry_t)*5)-1;
|
gdt_ptr.limit=(sizeof(gdt_entry_t)*6)-1;
|
||||||
gdt_ptr.base =(uint32_t)&gdt_entries;
|
gdt_ptr.base =(uint32_t)&gdt_entries;
|
||||||
|
|
||||||
gdt_set_gate(0, 0, 0, 0, 0); // Null segment
|
gdt_set_gate(0, 0, 0, 0, 0); // Null segment
|
||||||
@ -50,7 +51,7 @@ static void write_tss(int32_t num, uint16_t ss0, uint32_t esp0) {
|
|||||||
gdt_set_gate(num, base, limit, 0xE9, 0x00);
|
gdt_set_gate(num, base, limit, 0xE9, 0x00);
|
||||||
|
|
||||||
// Ensure the descriptor is initially zero.
|
// Ensure the descriptor is initially zero.
|
||||||
memory_set(&tss_entry, 0, sizeof(tss_entry));
|
memory_set((char*)&tss_entry, 0, sizeof(tss_entry));
|
||||||
tss_entry.ss0 = ss0; // Set the kernel stack segment.
|
tss_entry.ss0 = ss0; // Set the kernel stack segment.
|
||||||
tss_entry.esp0 = esp0; // Set the kernel stack pointer.
|
tss_entry.esp0 = esp0; // Set the kernel stack pointer.
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ void set_idt_gate(int n,uint32_t handler) {
|
|||||||
idt[n].low_offset=low_16(handler);
|
idt[n].low_offset=low_16(handler);
|
||||||
idt[n].sel=KERNEL_CS;
|
idt[n].sel=KERNEL_CS;
|
||||||
idt[n].always0=0;
|
idt[n].always0=0;
|
||||||
idt[n].flags=0x8E;
|
idt[n].flags=0xEE;
|
||||||
idt[n].high_offset=high_16(handler);
|
idt[n].high_offset=high_16(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,7 @@ isr_common_stub:
|
|||||||
mov gs, ax
|
mov gs, ax
|
||||||
|
|
||||||
; 2. Call C handler
|
; 2. Call C handler
|
||||||
call isr_handler
|
call isr_handler
|
||||||
|
|
||||||
; 3. Restore state
|
; 3. Restore state
|
||||||
pop eax
|
pop eax
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
@ -90,6 +89,7 @@ global isr28
|
|||||||
global isr29
|
global isr29
|
||||||
global isr30
|
global isr30
|
||||||
global isr31
|
global isr31
|
||||||
|
global isr80
|
||||||
; IRQs
|
; IRQs
|
||||||
global irq0
|
global irq0
|
||||||
global irq1
|
global irq1
|
||||||
@ -326,6 +326,13 @@ isr31:
|
|||||||
push byte 31
|
push byte 31
|
||||||
jmp isr_common_stub
|
jmp isr_common_stub
|
||||||
|
|
||||||
|
; 80: Syscalls
|
||||||
|
isr80:
|
||||||
|
cli
|
||||||
|
push byte 0
|
||||||
|
push byte 80
|
||||||
|
jmp isr_common_stub
|
||||||
|
|
||||||
; IRQ handlers
|
; IRQ handlers
|
||||||
irq0:
|
irq0:
|
||||||
cli
|
cli
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include "../libc/string.h"
|
#include "../libc/string.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "ports.h"
|
#include "ports.h"
|
||||||
|
void irq_handler(registers_t r);
|
||||||
isr_t interrupt_handlers[256];
|
isr_t interrupt_handlers[256];
|
||||||
|
|
||||||
/* Can't do this with a loop because we need the address
|
/* Can't do this with a loop because we need the address
|
||||||
@ -42,7 +42,7 @@ void isr_install() {
|
|||||||
set_idt_gate(29,(uint32_t)isr29);
|
set_idt_gate(29,(uint32_t)isr29);
|
||||||
set_idt_gate(30,(uint32_t)isr30);
|
set_idt_gate(30,(uint32_t)isr30);
|
||||||
set_idt_gate(31,(uint32_t)isr31);
|
set_idt_gate(31,(uint32_t)isr31);
|
||||||
|
set_idt_gate(80,(uint32_t)isr80);
|
||||||
// Remap the PIC
|
// Remap the PIC
|
||||||
port_byte_out(0x20,0x11);
|
port_byte_out(0x20,0x11);
|
||||||
port_byte_out(0xA0,0x11);
|
port_byte_out(0xA0,0x11);
|
||||||
@ -117,14 +117,40 @@ char *exception_messages[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void isr_handler(registers_t r) {
|
void isr_handler(registers_t r) {
|
||||||
write_string("Received interrupt no ");
|
if (r.int_no==80) {
|
||||||
char s[3];
|
switch (r.eax) {
|
||||||
int_to_ascii(r.int_no, s);
|
case 0:
|
||||||
write_string(s);
|
write_string((char*)r.ebx);
|
||||||
write_string(". (");
|
break;
|
||||||
write_string(exception_messages[r.int_no]);
|
case 1:
|
||||||
write_string(")\n");
|
screen_backspace();
|
||||||
asm volatile("hlt");
|
break;
|
||||||
|
case 2:
|
||||||
|
register_interrupt_handler((uint8_t)r.ebx,(isr_t)r.ecx);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
r.eax=port_byte_in((unsigned short)r.ebx);
|
||||||
|
break;
|
||||||
|
break;
|
||||||
|
default: {
|
||||||
|
char num[10];
|
||||||
|
int_to_ascii(r.eax, num);
|
||||||
|
write_string("PANIC: Invalid syscall no ");
|
||||||
|
write_string(num);
|
||||||
|
write_string("\n");
|
||||||
|
asm volatile("hlt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
write_string("Received interrupt no ");
|
||||||
|
char s[3];
|
||||||
|
int_to_ascii(r.int_no, s);
|
||||||
|
write_string(s);
|
||||||
|
write_string(". (");
|
||||||
|
write_string(exception_messages[r.int_no]);
|
||||||
|
write_string(")\n");
|
||||||
|
asm volatile("hlt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -137,7 +163,6 @@ void irq_handler(registers_t r) {
|
|||||||
* or they will not send another interrupt again */
|
* or they will not send another interrupt again */
|
||||||
if (r.int_no >= 40) port_byte_out(0xA0,0x20); /* slave */
|
if (r.int_no >= 40) port_byte_out(0xA0,0x20); /* slave */
|
||||||
port_byte_out(0x20,0x20); /* master */
|
port_byte_out(0x20,0x20); /* master */
|
||||||
|
|
||||||
/* Handle the interrupt in a more modular way */
|
/* Handle the interrupt in a more modular way */
|
||||||
if (interrupt_handlers[r.int_no] != 0) {
|
if (interrupt_handlers[r.int_no] != 0) {
|
||||||
isr_t handler = interrupt_handlers[r.int_no];
|
isr_t handler = interrupt_handlers[r.int_no];
|
||||||
|
@ -36,6 +36,7 @@ extern void isr28();
|
|||||||
extern void isr29();
|
extern void isr29();
|
||||||
extern void isr30();
|
extern void isr30();
|
||||||
extern void isr31();
|
extern void isr31();
|
||||||
|
extern void isr80();
|
||||||
/* IRQ definitions */
|
/* IRQ definitions */
|
||||||
extern void irq0();
|
extern void irq0();
|
||||||
extern void irq1();
|
extern void irq1();
|
||||||
|
@ -42,6 +42,7 @@ void write_string(const char *string) {
|
|||||||
if (c=='\n') {
|
if (c=='\n') {
|
||||||
x=0;
|
x=0;
|
||||||
y++;
|
y++;
|
||||||
|
set_cursor_offset(get_offset(x,y));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (x==80) {
|
if (x==80) {
|
||||||
@ -50,9 +51,9 @@ void write_string(const char *string) {
|
|||||||
}
|
}
|
||||||
if (y==25) {
|
if (y==25) {
|
||||||
for (int i=1;i<VGA_HEIGHT;i++) {
|
for (int i=1;i<VGA_HEIGHT;i++) {
|
||||||
memory_copy(get_offset(0,i)+VIDEO_MEMORY,get_offset(0,i-1)+VIDEO_MEMORY,VGA_WIDTH*2);
|
memory_copy((char*)get_offset(0,i)+VIDEO_MEMORY,(char *)get_offset(0,i-1)+VIDEO_MEMORY,VGA_WIDTH*2);
|
||||||
}
|
}
|
||||||
char *last_line=get_offset(0,VGA_HEIGHT-1)+VIDEO_MEMORY;
|
char* last_line=(char*)get_offset(0,VGA_HEIGHT-1)+VIDEO_MEMORY;
|
||||||
for(int i=0;i<VGA_WIDTH*2;i++) {
|
for(int i=0;i<VGA_WIDTH*2;i++) {
|
||||||
last_line[i]=0;
|
last_line[i]=0;
|
||||||
}
|
}
|
||||||
@ -65,12 +66,21 @@ void write_string(const char *string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void screen_backspace() {
|
||||||
|
if (x>0) {
|
||||||
|
x--;
|
||||||
|
video_memory[get_offset(x,y)]=' ';
|
||||||
|
video_memory[get_offset(x,y)+1]=color;
|
||||||
|
set_cursor_offset(get_offset(x,y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void clear_screen() {
|
void clear_screen() {
|
||||||
int x=0;
|
int x=0;
|
||||||
int y=0;
|
int y=0;
|
||||||
while (y<25) {
|
while (y<25) {
|
||||||
video_memory[get_offset(x,y)]=' ';
|
video_memory[get_offset(x,y)]=' ';
|
||||||
video_memory[get_offset(x,y)]=BLACK;
|
video_memory[get_offset(x,y)+1]=color;
|
||||||
x++;
|
x++;
|
||||||
if(x==80) {
|
if(x==80) {
|
||||||
x=0;
|
x=0;
|
||||||
@ -82,18 +92,19 @@ void clear_screen() {
|
|||||||
set_cursor_offset(0);
|
set_cursor_offset(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int get_cursor_offset() {
|
int get_cursor_offset() {
|
||||||
// port_byte_out(SCREEN_CTRL,14);
|
port_byte_out(SCREEN_CTRL,14);
|
||||||
// int offset=port_byte_in(SCREEN_DATA)<<8;
|
int offset=port_byte_in(SCREEN_DATA)<<8;
|
||||||
// port_byte_out(SCREEN_CTRL,15);
|
port_byte_out(SCREEN_CTRL,15);
|
||||||
// offset+=port_byte_in(SCREEN_DATA);
|
offset+=port_byte_in(SCREEN_DATA);
|
||||||
// return offset*2;
|
return offset*2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_cursor_offset(int offset) {
|
void set_cursor_offset(int offset) {
|
||||||
// offset/=2;
|
offset/=2;
|
||||||
// port_byte_out(SCREEN_CTRL,14);
|
port_byte_out(SCREEN_CTRL,14);
|
||||||
// port_byte_out(SCREEN_DATA,(unsigned char)(offset>>8));
|
port_byte_out(SCREEN_DATA,(unsigned char)(offset>>8));
|
||||||
// port_byte_out(SCREEN_CTRL,15);
|
port_byte_out(SCREEN_CTRL,15);
|
||||||
// port_byte_out(SCREEN_DATA,(unsigned char)(offset&0xff));
|
port_byte_out(SCREEN_DATA,(unsigned char)(offset&0xff));
|
||||||
}
|
}
|
||||||
|
@ -26,5 +26,6 @@ typedef enum {
|
|||||||
void init_vga(VGA_COLOR txt,VGA_COLOR bg);
|
void init_vga(VGA_COLOR txt,VGA_COLOR bg);
|
||||||
void write_string(const char *string);
|
void write_string(const char *string);
|
||||||
void clear_screen();
|
void clear_screen();
|
||||||
|
void screen_backspace();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -2,14 +2,9 @@
|
|||||||
#include "../drivers/isr.h"
|
#include "../drivers/isr.h"
|
||||||
#include "../drivers/idt.h"
|
#include "../drivers/idt.h"
|
||||||
#include "../drivers/gdt.h"
|
#include "../drivers/gdt.h"
|
||||||
/*
|
#include "syscalls.h"
|
||||||
pop %eax; \
|
#include "keyboard.h"
|
||||||
or $0x200,%eax; \
|
|
||||||
push %eax; \
|
|
||||||
*/
|
|
||||||
void switch_to_user_mode() {
|
void switch_to_user_mode() {
|
||||||
// set_kernel_stack(0x80000);
|
|
||||||
// Set up a stack structure for switching to user mode.
|
|
||||||
asm volatile(" \
|
asm volatile(" \
|
||||||
cli; \
|
cli; \
|
||||||
mov $0x23, %ax; \
|
mov $0x23, %ax; \
|
||||||
@ -22,6 +17,9 @@ void switch_to_user_mode() {
|
|||||||
pushl $0x23; \
|
pushl $0x23; \
|
||||||
pushl %eax; \
|
pushl %eax; \
|
||||||
pushf; \
|
pushf; \
|
||||||
|
pop %eax; \
|
||||||
|
or $0x200,%eax; \
|
||||||
|
push %eax; \
|
||||||
pushl $0x1B; \
|
pushl $0x1B; \
|
||||||
push $1f; \
|
push $1f; \
|
||||||
iret; \
|
iret; \
|
||||||
@ -31,13 +29,19 @@ void switch_to_user_mode() {
|
|||||||
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
init_vga(GRAY,BLACK);
|
init_vga(WHITE,BLACK);
|
||||||
write_string("Initialized VGA\n");
|
write_string("Initialized VGA\n");
|
||||||
isr_install();
|
isr_install();
|
||||||
asm volatile("sti");
|
asm volatile("sti");
|
||||||
write_string("Setup interrupts\n");
|
write_string("Setup interrupts\n");
|
||||||
init_gdt();
|
init_gdt();
|
||||||
write_string("Setup new GDT\n");
|
write_string("Setup new GDT\n");
|
||||||
|
init_keyboard();
|
||||||
switch_to_user_mode();
|
switch_to_user_mode();
|
||||||
write_string("User mode!\n");
|
syscall_write_string("User mode!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void user_input(char* str) {
|
||||||
|
syscall_write_string(str);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
6
kernel/kernel.h
Normal file
6
kernel/kernel.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef KERNEL_H
|
||||||
|
#define KERNEL_H
|
||||||
|
|
||||||
|
void user_input(char* str);
|
||||||
|
|
||||||
|
#endif
|
81
kernel/keyboard.c
Normal file
81
kernel/keyboard.c
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
#include "keyboard.h"
|
||||||
|
#include "../drivers/ports.h"
|
||||||
|
#include "../drivers/vga.h"
|
||||||
|
#include "../drivers/isr.h"
|
||||||
|
#include "../libc/string.h"
|
||||||
|
#include "kernel.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define BACKSPACE 0x0E
|
||||||
|
#define ENTER 0x1C
|
||||||
|
#define CAPS 0x3A
|
||||||
|
#define LSHIFT 0x2A
|
||||||
|
#define RSHIFT 0x36
|
||||||
|
#define LSHIFTUP 0xAA
|
||||||
|
#define RSHIFTUP 0xB6
|
||||||
|
static char key_buffer[256];
|
||||||
|
|
||||||
|
const char *sc_name[] = { "ERROR", "Esc", "1", "2", "3", "4", "5", "6",
|
||||||
|
"7", "8", "9", "0", "-", "=", "Backspace", "Tab", "Q", "W", "E",
|
||||||
|
"R", "T", "Y", "U", "I", "O", "P", "[", "]", "Enter", "Lctrl",
|
||||||
|
"A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "'", "`",
|
||||||
|
"LShift", "\\", "Z", "X", "C", "V", "B", "N", "M", ",", ".",
|
||||||
|
"/", "RShift", "Keypad *", "LAlt", "Spacebar"};
|
||||||
|
const char sc_ascii[] = { '?', '?', '1', '2', '3', '4', '5', '6',
|
||||||
|
'7', '8', '9', '0', '-', '=', '?', '?', 'q', 'w', 'e', 'r', 't', 'y',
|
||||||
|
'u', 'i', 'o', 'p', '[', ']', '?', '?', 'a', 's', 'd', 'f', 'g',
|
||||||
|
'h', 'j', 'k', 'l', ';', '\'', '`', '?', '\\', 'z', 'x', 'c', 'v',
|
||||||
|
'b', 'n', 'm', ',', '.', '/', '?', '?', '?', ' '};
|
||||||
|
const char sc_caps_ascii[] = { '?', '?', '1', '2', '3', '4', '5', '6',
|
||||||
|
'7', '8', '9', '0', '-', '=', '?', '?', 'Q', 'W', 'E', 'R', 'T', 'Y',
|
||||||
|
'U', 'I', 'O', 'P', '[', ']', '?', '?', 'A', 'S', 'D', 'F', 'G',
|
||||||
|
'H', 'J', 'K', 'L', ';', '\'', '`', '?', '\\', 'Z', 'X', 'C', 'V',
|
||||||
|
'B', 'N', 'M', ',', '.', '/', '?', '?', '?', ' '};
|
||||||
|
const char sc_shift_ascii[] = { '?', '?', '!', '@', '#', '$', '%', '^',
|
||||||
|
'&', '*', '(', ')', '_', '+', '?', '?', 'Q', 'W', 'E', 'R', 'T', 'Y',
|
||||||
|
'U', 'I', 'O', 'P', '{', '}', '?', '?', 'A', 'S', 'D', 'F', 'G',
|
||||||
|
'H', 'J', 'K', 'L', ':', '"', '~', '?', '|', 'Z', 'X', 'C', 'V',
|
||||||
|
'B', 'N', 'M', '<', '>', '?', '?', '?', '?', ' '};
|
||||||
|
int caps=0;
|
||||||
|
int shift=0;
|
||||||
|
|
||||||
|
static void keyboard_callback(registers_t regs) {
|
||||||
|
/* The PIC leaves us the scancode in port 0x60 */
|
||||||
|
uint8_t scancode=port_byte_in(0x60);
|
||||||
|
// char s[10];
|
||||||
|
// int_to_ascii(scancode,s);
|
||||||
|
// write_string("Scancode ");
|
||||||
|
// write_string(s);
|
||||||
|
// write_string("\n");
|
||||||
|
if (scancode==BACKSPACE) {
|
||||||
|
backspace(key_buffer);
|
||||||
|
screen_backspace();
|
||||||
|
} else if (scancode==CAPS) {
|
||||||
|
caps=!caps;
|
||||||
|
} else if (scancode==LSHIFT || scancode==RSHIFT) {
|
||||||
|
shift=1;
|
||||||
|
} else if (scancode==LSHIFTUP || scancode==RSHIFTUP) {
|
||||||
|
shift=0;
|
||||||
|
} else if (scancode==ENTER) {
|
||||||
|
write_string("\n");
|
||||||
|
append(key_buffer,'\n');
|
||||||
|
user_input(key_buffer);
|
||||||
|
key_buffer[0]='\0';
|
||||||
|
} else if (scancode <=58) {
|
||||||
|
char letter;
|
||||||
|
if (shift) {
|
||||||
|
letter=sc_shift_ascii[(int)scancode];
|
||||||
|
} else if (caps) {
|
||||||
|
letter=sc_caps_ascii[(int)scancode];
|
||||||
|
} else {
|
||||||
|
letter=sc_ascii[(int)scancode];
|
||||||
|
}
|
||||||
|
char str[2]={letter,'\0'};
|
||||||
|
append(key_buffer,letter);
|
||||||
|
write_string(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_keyboard() {
|
||||||
|
register_interrupt_handler(IRQ1, keyboard_callback);
|
||||||
|
}
|
6
kernel/keyboard.h
Normal file
6
kernel/keyboard.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef KEYBOARD_H
|
||||||
|
#define KEYBOARD_H
|
||||||
|
|
||||||
|
void init_keyboard();
|
||||||
|
|
||||||
|
#endif
|
20
kernel/syscalls.c
Normal file
20
kernel/syscalls.c
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#include "../drivers/isr.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void syscall_write_string(char* str) {
|
||||||
|
asm volatile("int $80"::"a"(0),"b"(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
void syscall_screen_backspace() {
|
||||||
|
asm volatile("int $80"::"a"(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void syscall_register_interrupt_handler(uint8_t n,isr_t handler) {
|
||||||
|
asm volatile("int $80"::"a"(2),"b"(n),"c"(isr_handler));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char syscall_port_byte_in(unsigned short port) {
|
||||||
|
unsigned char result;
|
||||||
|
asm volatile("int $80":"=a"(result):"a"(3),"b"(port));
|
||||||
|
return result;
|
||||||
|
}
|
12
kernel/syscalls.h
Normal file
12
kernel/syscalls.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#ifndef SYSCALLS_H
|
||||||
|
#define SYSCALLS_H
|
||||||
|
|
||||||
|
#include "../drivers/isr.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void syscall_write_string(char* str);
|
||||||
|
void syscall_screen_backspace();
|
||||||
|
void syscall_register_interrupt_handler(uint8_t n,isr_t handler);
|
||||||
|
unsigned char syscall_port_byte_in(unsigned short port);
|
||||||
|
|
||||||
|
#endif
|
@ -32,3 +32,14 @@ void int_to_ascii(int n,char* str) {
|
|||||||
str[i]='\0';
|
str[i]='\0';
|
||||||
reverse(str);
|
reverse(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void append(char s[], char n) {
|
||||||
|
int len = strlen(s);
|
||||||
|
s[len] = n;
|
||||||
|
s[len+1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
void backspace(char s[]) {
|
||||||
|
int len = strlen(s);
|
||||||
|
s[len-1] = '\0';
|
||||||
|
}
|
||||||
|
@ -4,5 +4,6 @@
|
|||||||
int strlen(char* str);
|
int strlen(char* str);
|
||||||
void reverse(char* str);
|
void reverse(char* str);
|
||||||
void int_to_ascii(int n,char* str);
|
void int_to_ascii(int n,char* str);
|
||||||
|
void append(char* s, char n);
|
||||||
|
void backspace(char* s);
|
||||||
#endif
|
#endif
|
||||||
|
35
new-gdt.asm
35
new-gdt.asm
@ -1,35 +0,0 @@
|
|||||||
gdt_start: ; don't remove the labels, they're needed to compute sizes and jumps
|
|
||||||
; the GDT starts with a null 8-byte
|
|
||||||
dd 0x0 ; 4 byte
|
|
||||||
dd 0x0 ; 4 byte
|
|
||||||
|
|
||||||
; GDT for code segment. base = 0x00000000, length = 0xfffff
|
|
||||||
; for flags, refer to os-dev.pdf document, page 36
|
|
||||||
gdt_code:
|
|
||||||
dw 0xffff ; segment length, bits 0-15
|
|
||||||
dw 0x0 ; segment base, bits 0-15
|
|
||||||
db 0x0 ; segment base, bits 16-23
|
|
||||||
db 10011010b ; flags (8 bits)
|
|
||||||
db 11001111b ; flags (4 bits) + segment length, bits 16-19
|
|
||||||
db 0x0 ; segment base, bits 24-31
|
|
||||||
|
|
||||||
; GDT for data segment. base and length identical to code segment
|
|
||||||
; some flags changed, again, refer to os-dev.pdf
|
|
||||||
gdt_data:
|
|
||||||
dw 0xffff
|
|
||||||
dw 0x0
|
|
||||||
db 0x0
|
|
||||||
db 10010010b
|
|
||||||
db 11001111b
|
|
||||||
db 0x0
|
|
||||||
|
|
||||||
gdt_end:
|
|
||||||
|
|
||||||
; GDT descriptor
|
|
||||||
gdt_descriptor:
|
|
||||||
dw gdt_end - gdt_start - 1 ; size (16 bit), always one less of its true size
|
|
||||||
dd gdt_start ; address (32 bit)
|
|
||||||
|
|
||||||
; define some constants for later use
|
|
||||||
CODE_SEG equ gdt_code - gdt_start
|
|
||||||
DATA_SEG equ gdt_data - gdt_start
|
|
57
old-gdt.asm
57
old-gdt.asm
@ -1,57 +0,0 @@
|
|||||||
gdt_start: ; don't remove the labels, they're needed to compute sizes and jumps
|
|
||||||
; the GDT starts with a null 8-byte
|
|
||||||
dd 0x0 ; 4 byte
|
|
||||||
dd 0x0 ; 4 byte
|
|
||||||
|
|
||||||
; GDT for kernel code segment. base = 0x00000000, length = 0xfffff
|
|
||||||
; for flags, refer to os-dev.pdf document, page 36
|
|
||||||
gdt_kern_code:
|
|
||||||
dw 0x0000 ; segment length, bits 0-15
|
|
||||||
dw 0x0 ; segment base, bits 0-15
|
|
||||||
db 0x0 ; segment base, bits 16-23
|
|
||||||
db 10011010b ; flags (8 bits)
|
|
||||||
db 11000001b ; flags (4 bits) + segment length, bits 16-19
|
|
||||||
db 0x0 ; segment base, bits 24-31
|
|
||||||
|
|
||||||
; GDT for kernel data segment. base and length identical to code segment
|
|
||||||
; some flags changed, again, refer to os-dev.pdf
|
|
||||||
gdt_kern_data:
|
|
||||||
dw 0x0000
|
|
||||||
dw 0x0
|
|
||||||
db 0x0
|
|
||||||
db 10010010b
|
|
||||||
db 11000001b
|
|
||||||
db 0x0
|
|
||||||
|
|
||||||
; GDT for user code segment. base = 0x01000000, length = 0xfffff
|
|
||||||
; for flags, refer to os-dev.pdf document, page 36
|
|
||||||
gdt_usr_code:
|
|
||||||
dw 0xffff ; segment length, bits 0-15
|
|
||||||
dw 0x0 ; segment base, bits 0-15
|
|
||||||
db 0x0 ; segment base, bits 16-23
|
|
||||||
db 11111010b ; flags (8 bits)
|
|
||||||
db 11001111b ; flags (4 bits) + segment length, bits 16-19
|
|
||||||
db 0x0 ; segment base, bits 24-31
|
|
||||||
|
|
||||||
; GDT for user data segment. base and length identical to code segment
|
|
||||||
; some flags changed, again, refer to os-dev.pdf
|
|
||||||
gdt_usr_data:
|
|
||||||
dw 0xffff
|
|
||||||
dw 0x0
|
|
||||||
db 0x0
|
|
||||||
db 11110010b
|
|
||||||
db 11001111b
|
|
||||||
db 0x0
|
|
||||||
|
|
||||||
gdt_end:
|
|
||||||
|
|
||||||
; GDT descriptor
|
|
||||||
gdt_descriptor:
|
|
||||||
dw gdt_end - gdt_start - 1 ; size (16 bit), always one less of its true size
|
|
||||||
dd gdt_start ; address (32 bit)
|
|
||||||
|
|
||||||
; define some constants for later use
|
|
||||||
CODE_SEG equ gdt_kern_code - gdt_start
|
|
||||||
DATA_SEG equ gdt_kern_data - gdt_start
|
|
||||||
USR_CODE_SEG equ gdt_usr_code - gdt_start
|
|
||||||
USR_DATA_SEG equ gdt_usr_data - gdt_start
|
|
Loading…
x
Reference in New Issue
Block a user