Syscalls working! Keyboard driver must run in kmode unfortunately :(

This commit is contained in:
pjht 2018-10-21 17:45:12 -05:00
parent ae5b1ad448
commit 00f066fc9b
19 changed files with 265 additions and 206 deletions

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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);
}

View File

@ -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

View File

@ -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];

View File

@ -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();

View File

@ -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));
}

View File

@ -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

View File

@ -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
View File

@ -0,0 +1,6 @@
#ifndef KERNEL_H
#define KERNEL_H
void user_input(char* str);
#endif

81
kernel/keyboard.c Normal file
View 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
View File

@ -0,0 +1,6 @@
#ifndef KEYBOARD_H
#define KEYBOARD_H
void init_keyboard();
#endif

20
kernel/syscalls.c Normal file
View 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
View 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

View File

@ -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';
}

View File

@ -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

View File

@ -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

View File

@ -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