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[ ] USB support: UHCI
|
||||
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 ] 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[ ] lt_dlhandle is 0x7fa5fec76d60
|
||||
00000000000i[ ] lt_dlhandle is 0x7fd0b3e74bd0
|
||||
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[ ] lt_dlhandle is 0x7fa5fec77050
|
||||
00000000000i[ ] lt_dlhandle is 0x7fd0b605b640
|
||||
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[ ] lt_dlhandle is 0x7fa5fef33ad0
|
||||
00000000000i[ ] lt_dlhandle is 0x7fd0b3c44e70
|
||||
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[ ] lt_dlhandle is 0x7fa5fec77dc0
|
||||
00000000000i[ ] lt_dlhandle is 0x7fd0b3c454b0
|
||||
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[ ] lt_dlhandle is 0x7fa5fec78530
|
||||
00000000000i[ ] lt_dlhandle is 0x7fd0b3e74f90
|
||||
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[ ] lt_dlhandle is 0x7fa5fed37690
|
||||
00000000000i[ ] lt_dlhandle is 0x7fd0b605c3c0
|
||||
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[ ] lt_dlhandle is 0x7fa5fec78db0
|
||||
00000000000i[ ] lt_dlhandle is 0x7fd0b3f3b4a0
|
||||
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[ ] lt_dlhandle is 0x7fa5fec79570
|
||||
00000000000i[ ] lt_dlhandle is 0x7fd0b605c680
|
||||
00000000000i[PLUGIN] loaded plugin libbx_pci_ide.so
|
||||
00000000000i[PLUGIN] init_dev of 'pci' plugin device by virtual method
|
||||
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[PLUGIN] init_dev of 'cmos' plugin device by virtual method
|
||||
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[DMA ] channel 4 used by cascade
|
||||
00000000000i[PLUGIN] init_dev of 'pic' plugin device by virtual method
|
||||
@ -220,30 +220,28 @@
|
||||
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 $
|
||||
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
|
||||
00014860467i[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)
|
||||
00015051260i[CPU0 ] WARNING: HLT instruction with IF=0!
|
||||
00482728000i[ ] Ctrl-C detected in signal handler.
|
||||
00482728001i[ ] dbg: Quit
|
||||
00482728001i[CPU0 ] CPU is in protected mode (halted)
|
||||
00482728001i[CPU0 ] CS.mode = 32 bit
|
||||
00482728001i[CPU0 ] SS.mode = 32 bit
|
||||
00482728001i[CPU0 ] EFER = 0x00000000
|
||||
00482728001i[CPU0 ] | EAX=00002000 EBX=00001000 ECX=00000000 EDX=000000a0
|
||||
00482728001i[CPU0 ] | ESP=0008ff78 EBP=0008ff90 ESI=000e0000 EDI=0000ffac
|
||||
00482728001i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt of df if tf sf zf af PF cf
|
||||
00482728001i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
|
||||
00482728001i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 ffffffff 1 1
|
||||
00482728001i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
||||
00482728001i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
||||
00482728001i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
||||
00482728001i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
||||
00482728001i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
||||
00482728001i[CPU0 ] | EIP=000019d4 (000019d4)
|
||||
00482728001i[CPU0 ] | CR0=0x60000011 CR2=0x00000000
|
||||
00482728001i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
|
||||
00482728001i[CMOS ] Last time is 1540052375 (Sat Oct 20 11:19:35 2018)
|
||||
00482728001i[SIM ] quit_sim called with exit code 0
|
||||
00042328074i[CPU0 ] WARNING: HLT instruction with IF=0!
|
||||
00340680000p[SDL2 ] >>PANIC<< User requested shutdown.
|
||||
00340680000i[CPU0 ] CPU is in protected mode (halted)
|
||||
00340680000i[CPU0 ] CS.mode = 32 bit
|
||||
00340680000i[CPU0 ] SS.mode = 32 bit
|
||||
00340680000i[CPU0 ] EFER = 0x00000000
|
||||
00340680000i[CPU0 ] | EAX=00002700 EBX=0007ff3c ECX=00000000 EDX=000003d5
|
||||
00340680000i[CPU0 ] | ESP=0007ffa0 EBP=0007ffb8 ESI=00080000 EDI=0007ff90
|
||||
00340680000i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt of df if tf sf zf af PF cf
|
||||
00340680000i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
|
||||
00340680000i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 ffffffff 1 1
|
||||
00340680000i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
||||
00340680000i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
||||
00340680000i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
||||
00340680000i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
||||
00340680000i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
||||
00340680000i[CPU0 ] | EIP=00001c77 (00001c77)
|
||||
00340680000i[CPU0 ] | CR0=0x60000011 CR2=0x00000000
|
||||
00340680000i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
|
||||
00340680000i[CMOS ] Last time is 1540159327 (Sun Oct 21 17:02:07 2018)
|
||||
00340680000i[SIM ] quit_sim called with exit code 1
|
||||
|
@ -6,6 +6,7 @@
|
||||
//
|
||||
|
||||
#include "gdt.h"
|
||||
#include "../libc/memory.h"
|
||||
#include <stdint.h>
|
||||
|
||||
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;
|
||||
|
||||
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_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);
|
||||
|
||||
// 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.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].sel=KERNEL_CS;
|
||||
idt[n].always0=0;
|
||||
idt[n].flags=0x8E;
|
||||
idt[n].flags=0xEE;
|
||||
idt[n].high_offset=high_16(handler);
|
||||
}
|
||||
|
||||
|
@ -15,8 +15,7 @@ isr_common_stub:
|
||||
mov gs, ax
|
||||
|
||||
; 2. Call C handler
|
||||
call isr_handler
|
||||
|
||||
call isr_handler
|
||||
; 3. Restore state
|
||||
pop eax
|
||||
mov ds, ax
|
||||
@ -90,6 +89,7 @@ global isr28
|
||||
global isr29
|
||||
global isr30
|
||||
global isr31
|
||||
global isr80
|
||||
; IRQs
|
||||
global irq0
|
||||
global irq1
|
||||
@ -326,6 +326,13 @@ isr31:
|
||||
push byte 31
|
||||
jmp isr_common_stub
|
||||
|
||||
; 80: Syscalls
|
||||
isr80:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 80
|
||||
jmp isr_common_stub
|
||||
|
||||
; IRQ handlers
|
||||
irq0:
|
||||
cli
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "../libc/string.h"
|
||||
#include <stdint.h>
|
||||
#include "ports.h"
|
||||
|
||||
void irq_handler(registers_t r);
|
||||
isr_t interrupt_handlers[256];
|
||||
|
||||
/* 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(30,(uint32_t)isr30);
|
||||
set_idt_gate(31,(uint32_t)isr31);
|
||||
|
||||
set_idt_gate(80,(uint32_t)isr80);
|
||||
// Remap the PIC
|
||||
port_byte_out(0x20,0x11);
|
||||
port_byte_out(0xA0,0x11);
|
||||
@ -117,14 +117,40 @@ char *exception_messages[] = {
|
||||
};
|
||||
|
||||
void isr_handler(registers_t r) {
|
||||
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");
|
||||
if (r.int_no==80) {
|
||||
switch (r.eax) {
|
||||
case 0:
|
||||
write_string((char*)r.ebx);
|
||||
break;
|
||||
case 1:
|
||||
screen_backspace();
|
||||
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 */
|
||||
if (r.int_no >= 40) port_byte_out(0xA0,0x20); /* slave */
|
||||
port_byte_out(0x20,0x20); /* master */
|
||||
|
||||
/* Handle the interrupt in a more modular way */
|
||||
if (interrupt_handlers[r.int_no] != 0) {
|
||||
isr_t handler = interrupt_handlers[r.int_no];
|
||||
|
@ -36,6 +36,7 @@ extern void isr28();
|
||||
extern void isr29();
|
||||
extern void isr30();
|
||||
extern void isr31();
|
||||
extern void isr80();
|
||||
/* IRQ definitions */
|
||||
extern void irq0();
|
||||
extern void irq1();
|
||||
|
@ -42,6 +42,7 @@ void write_string(const char *string) {
|
||||
if (c=='\n') {
|
||||
x=0;
|
||||
y++;
|
||||
set_cursor_offset(get_offset(x,y));
|
||||
continue;
|
||||
}
|
||||
if (x==80) {
|
||||
@ -50,9 +51,9 @@ void write_string(const char *string) {
|
||||
}
|
||||
if (y==25) {
|
||||
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++) {
|
||||
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() {
|
||||
int x=0;
|
||||
int y=0;
|
||||
while (y<25) {
|
||||
video_memory[get_offset(x,y)]=' ';
|
||||
video_memory[get_offset(x,y)]=BLACK;
|
||||
video_memory[get_offset(x,y)+1]=color;
|
||||
x++;
|
||||
if(x==80) {
|
||||
x=0;
|
||||
@ -82,18 +92,19 @@ void clear_screen() {
|
||||
set_cursor_offset(0);
|
||||
}
|
||||
|
||||
|
||||
int get_cursor_offset() {
|
||||
// port_byte_out(SCREEN_CTRL,14);
|
||||
// int offset=port_byte_in(SCREEN_DATA)<<8;
|
||||
// port_byte_out(SCREEN_CTRL,15);
|
||||
// offset+=port_byte_in(SCREEN_DATA);
|
||||
// return offset*2;
|
||||
port_byte_out(SCREEN_CTRL,14);
|
||||
int offset=port_byte_in(SCREEN_DATA)<<8;
|
||||
port_byte_out(SCREEN_CTRL,15);
|
||||
offset+=port_byte_in(SCREEN_DATA);
|
||||
return offset*2;
|
||||
}
|
||||
|
||||
void set_cursor_offset(int offset) {
|
||||
// offset/=2;
|
||||
// port_byte_out(SCREEN_CTRL,14);
|
||||
// port_byte_out(SCREEN_DATA,(unsigned char)(offset>>8));
|
||||
// port_byte_out(SCREEN_CTRL,15);
|
||||
// port_byte_out(SCREEN_DATA,(unsigned char)(offset&0xff));
|
||||
offset/=2;
|
||||
port_byte_out(SCREEN_CTRL,14);
|
||||
port_byte_out(SCREEN_DATA,(unsigned char)(offset>>8));
|
||||
port_byte_out(SCREEN_CTRL,15);
|
||||
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 write_string(const char *string);
|
||||
void clear_screen();
|
||||
void screen_backspace();
|
||||
|
||||
#endif
|
||||
|
@ -2,14 +2,9 @@
|
||||
#include "../drivers/isr.h"
|
||||
#include "../drivers/idt.h"
|
||||
#include "../drivers/gdt.h"
|
||||
/*
|
||||
pop %eax; \
|
||||
or $0x200,%eax; \
|
||||
push %eax; \
|
||||
*/
|
||||
#include "syscalls.h"
|
||||
#include "keyboard.h"
|
||||
void switch_to_user_mode() {
|
||||
// set_kernel_stack(0x80000);
|
||||
// Set up a stack structure for switching to user mode.
|
||||
asm volatile(" \
|
||||
cli; \
|
||||
mov $0x23, %ax; \
|
||||
@ -22,6 +17,9 @@ void switch_to_user_mode() {
|
||||
pushl $0x23; \
|
||||
pushl %eax; \
|
||||
pushf; \
|
||||
pop %eax; \
|
||||
or $0x200,%eax; \
|
||||
push %eax; \
|
||||
pushl $0x1B; \
|
||||
push $1f; \
|
||||
iret; \
|
||||
@ -31,13 +29,19 @@ void switch_to_user_mode() {
|
||||
|
||||
|
||||
void main() {
|
||||
init_vga(GRAY,BLACK);
|
||||
init_vga(WHITE,BLACK);
|
||||
write_string("Initialized VGA\n");
|
||||
isr_install();
|
||||
asm volatile("sti");
|
||||
write_string("Setup interrupts\n");
|
||||
init_gdt();
|
||||
write_string("Setup new GDT\n");
|
||||
init_keyboard();
|
||||
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';
|
||||
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);
|
||||
void reverse(char* str);
|
||||
void int_to_ascii(int n,char* str);
|
||||
|
||||
void append(char* s, char n);
|
||||
void backspace(char* s);
|
||||
#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