Compare commits

..

2 Commits

Author SHA1 Message Date
dacdc0ae8d im so mad 2024-05-21 21:07:43 -05:00
716fb09a77 im so mad 2024-05-21 21:07:04 -05:00
24 changed files with 938 additions and 73 deletions

View File

@ -1,7 +1,7 @@
CC = i686-elf-gcc
INCLUDE = -I./
CFLAGS = -Wall -Wextra -Werror -ffreestanding $(INCLUDE)
LDFLAGS = -T kernel.ld -ffreestanding -O3 -nostdlib -lgcc -mpreferred-stack-boundary=4
LDFLAGS = -T kernel.ld -ffreestanding -O3 -nostdlib -lgcc
BUILDDIR = build
@ -21,7 +21,7 @@ KERNELIMG := $(BUILDDIR)/kernel.bin
QEMUFLAGS = -d int -s \
-kernel $(KERNELIMG) \
-machine q35 \
-device piix3-ide,id=ide -drive id=disk,file=image.img,format=raw,if=none -device ide-hd,drive=disk,bus=ide.0
-device piix3-ide,id=ide -drive id=disk,file=image.img,format=raw,if=none -device ide-hd,drive=disk,bus=ide.0 \
.PHONY: all kernel qemu clean docs
@ -44,6 +44,8 @@ qemu: kernel
iso: kernel
cp $(BUILDDIR)/kernel.bin iso/boot/kernel.bin
grub-mkrescue -o $(BUILDDIR)/andewOS.iso iso/
bochs: iso
bochs -q
clean:
rm -rf build/*.o build/*.bin iso/boot/*.bin

20
acpi.c
View File

@ -1,6 +1,7 @@
#include <acpi.h>
#include <strcmp.h>
struct rsdp *acpi_search_for_rsdp() {
struct rsdp *acpi_locate_rsdp() {
char *ptr = (char *)BIOS_START;
char *str = RSDP_SIG;
@ -37,3 +38,20 @@ int acpi_validate_sdt_checksum(struct ACPISDTHeader *s) {
return sum == 0;
}
void *acpi_locate_sdt(struct rsdt *rsdt, const char sig[4]) {
int entries = (rsdt->h.Length - sizeof(rsdt->h)) / 4;
for (int i = 0; i < entries; i++)
{
struct ACPISDTHeader *h = (struct ACPISDTHeader *) rsdt->other_sdt[i];
if (!strncmp(h->Signature, sig, 4)) {
if (acpi_validate_sdt_checksum(h))
return (void *) h;
else
return 0;
}
}
return 0;
}

79
acpi.h
View File

@ -51,9 +51,86 @@ struct mcfg {
struct mcfg_entry entries[];
};
struct rsdp *acpi_search_for_rsdp();
struct GenericAddressStructure
{
uint8_t AddressSpace;
uint8_t BitWidth;
uint8_t BitOffset;
uint8_t AccessSize;
uint64_t Address;
};
struct fadt {
struct ACPISDTHeader h;
uint32_t FirmwareCtrl;
uint32_t Dsdt;
// field used in ACPI 1.0; no longer in use, for compatibility only
uint8_t Reserved;
uint8_t PreferredPowerManagementProfile;
uint16_t SCI_Interrupt;
uint32_t SMI_CommandPort;
uint8_t AcpiEnable;
uint8_t AcpiDisable;
uint8_t S4BIOS_REQ;
uint8_t PSTATE_Control;
uint32_t PM1aEventBlock;
uint32_t PM1bEventBlock;
uint32_t PM1aControlBlock;
uint32_t PM1bControlBlock;
uint32_t PM2ControlBlock;
uint32_t PMTimerBlock;
uint32_t GPE0Block;
uint32_t GPE1Block;
uint8_t PM1EventLength;
uint8_t PM1ControlLength;
uint8_t PM2ControlLength;
uint8_t PMTimerLength;
uint8_t GPE0Length;
uint8_t GPE1Length;
uint8_t GPE1Base;
uint8_t CStateControl;
uint16_t WorstC2Latency;
uint16_t WorstC3Latency;
uint16_t FlushSize;
uint16_t FlushStride;
uint8_t DutyOffset;
uint8_t DutyWidth;
uint8_t DayAlarm;
uint8_t MonthAlarm;
uint8_t Century;
// reserved in ACPI 1.0; used since ACPI 2.0+
uint16_t BootArchitectureFlags;
uint8_t Reserved2;
uint32_t Flags;
// 12 byte structure; see below for details
struct GenericAddressStructure ResetReg;
uint8_t ResetValue;
uint8_t Reserved3[3];
// 64bit pointers - Available on ACPI 2.0+
uint64_t X_FirmwareControl;
uint64_t X_Dsdt;
struct GenericAddressStructure X_PM1aEventBlock;
struct GenericAddressStructure X_PM1bEventBlock;
struct GenericAddressStructure X_PM1aControlBlock;
struct GenericAddressStructure X_PM1bControlBlock;
struct GenericAddressStructure X_PM2ControlBlock;
struct GenericAddressStructure X_PMTimerBlock;
struct GenericAddressStructure X_GPE0Block;
struct GenericAddressStructure X_GPE1Block;
};
struct rsdp *acpi_locate_rsdp();
int acpi_validate_rsdp_checksum(struct rsdp *s);
int acpi_validate_sdt_checksum(struct ACPISDTHeader *s);
struct ACPISDTHeader *acpi_find_table(struct rsdt *root, const char *signature);
void *acpi_locate_sdt(struct rsdt *rsdt, const char sig[4]);
#endif

3
bochsrc Normal file
View File

@ -0,0 +1,3 @@
ata0-slave: type=cdrom, path=./build/andewOS.iso, status=inserted
magic_break: enabled=1
boot: cdrom

9
gdt.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef GDT_H_
#define GDT_H_
#define GDT_NULL 0
#define GDT_KERNEL_CODE 1
#define GDT_KERNEL_DATA 2
#define GDT_SEGMENT_SELECTOR(i, p) ((i << 3) | p)
#endif

15
ide.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef IDE_H_
#define IDE_H_
enum IDE_MODE {
ISA_ONLY = 0x00,
PCI_ONLY = 0x05,
ISA_CAN_SWITCH = 0x0a,
PCI_CAN_SWITCH = 0x0f,
ISA_ONLY_BUS_MASTERING = 0x80,
PCI_ONLY_BUS_MASTERING = 0x85,
ISA_CAN_SWITCH_BUS_MASTERING = 0x8a,
PCI_CAN_SWITCH_BUS_MASTERING = 0x8f,
};
#endif

9
idt.c Normal file
View File

@ -0,0 +1,9 @@
#include <idt.h>
void encode_idt_entry(struct idt_entry idt[], int i, uint32_t offset, uint16_t segment_selector, uint8_t attributes) {
idt[i].offset_lo = (uint16_t)(offset & 0xFFFF);
idt[i].seg_select = segment_selector;
idt[i].reserved = 0;
idt[i].attributes = attributes;
idt[i].offset_hi = (uint16_t)(offset >> 16);
}

42
idt.h Normal file
View File

@ -0,0 +1,42 @@
#ifndef ANDEWOS_IDT_H_
#define ANDEWOS_IDT_H_
#include <stdint.h>
#define GDT_SEGMENT_SELECTOR(i, p) ((i << 3) | p)
#define LDT_SEGMENT_SELECTOR(i, p) ((i << 3) | 0x04 | p)
#define IDT_ENTRY_COUNT 256
struct idt_entry {
uint16_t offset_lo;
uint16_t seg_select;
uint8_t reserved;
uint8_t attributes;
uint16_t offset_hi;
} __attribute__ ((packed));
struct idtr {
uint16_t size;
uint32_t base;
} __attribute__ ((packed));
enum IDT_ATTRIBUTES {
TASK_GATE = 0x05,
INT_GATE_16 = 0x06,
TRAP_GATE_16 = 0x07,
INT_GATE_32 = 0x0E,
TRAP_GATE_32 = 0x0F,
INT_RING0 = 0x00,
INT_RING1 = 0x20,
INT_RING2 = 0x40,
INT_RING3 = 0x60,
INT_PRESENT = 0x80,
};
void encode_idt_entry(struct idt_entry idt[], int i, uint32_t offset, uint16_t segment_selector, uint8_t attributes);
void flush_idt(uint32_t idt_pointer);
#endif

5
iso/boot/grub/grub.cfg Normal file
View File

@ -0,0 +1,5 @@
default=0
timeout=0
menuentry "andewOS" {
multiboot /boot/kernel.bin
}

102
kmain.c
View File

@ -1,8 +1,13 @@
#include <multiboot.h>
#include <acpi.h>
#include <vga.h>
#include <pci.h>
#include <printf.h>
#include <strcmp.h>
#include <gdt.h>
#include <idt.h>
#include <pic8259.h>
#include <ps2.h>
struct kernel_context {
struct rsdp *rsdp;
@ -13,58 +18,30 @@ struct kernel_context {
struct kernel_context ctx = {0};
struct idt_entry g_idt[256] = {0};
struct idtr g_idtr = {0};
void *acpi_find_sdt(void *RootSDT, const char sig[4]) {
struct rsdt *rsdt = (struct rsdt *) RootSDT;
int entries = (rsdt->h.Length - sizeof(rsdt->h)) / 4;
extern void exception_handler();
extern void ps2_isr();
for (int i = 0; i < entries; i++)
{
struct ACPISDTHeader *h = (struct ACPISDTHeader *) rsdt->other_sdt[i];
if (!strncmp(h->Signature, sig, 4))
return (void *) h;
}
return 0;
}
uint16_t readw(uint32_t addr, uint32_t offset, uint8_t bus, uint8_t slot, uint8_t func) {
uint32_t lbus = (uint32_t)bus;
uint32_t lslot = (uint32_t)slot;
uint32_t lfunc = (uint32_t)func;
uint32_t address = addr + offset + ((lbus) << 20 | lslot << 15 | lfunc << 12);
return *(uint16_t *)address;
}
uint8_t readb(uint32_t addr, uint32_t offset, uint8_t bus, uint8_t slot, uint8_t func) {
uint32_t lbus = (uint32_t)bus;
uint32_t lslot = (uint32_t)slot;
uint32_t lfunc = (uint32_t)func;
uint32_t address = addr + offset + ((lbus) << 20 | lslot << 15 | lfunc << 12);
return *(uint8_t *)address;
}
uint32_t readd(uint32_t addr, uint32_t offset, uint8_t bus, uint8_t slot, uint8_t func) {
uint32_t lbus = (uint32_t)bus;
uint32_t lslot = (uint32_t)slot;
uint32_t lfunc = (uint32_t)func;
uint32_t address = addr + offset + ((lbus) << 20 | lslot << 15 | lfunc << 12);
return *(uint32_t *)address;
}
#define MAGIC_BREAKPOINT __asm__ volatile("xchgw %bx, %bx");
void kmain(struct multiboot_info *info) {
clear_screen();
// Check if the bootloader gave us the upper and lower memory
if (!(info->flags & 0x1)) goto halt;
struct rsdp *found_rsdp = acpi_search_for_rsdp();
// Create and load an IDT
for (int i = 0; i < 32; i++) {
encode_idt_entry(g_idt, i, (uint32_t)&exception_handler, GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, 0x00), TRAP_GATE_32 | INT_RING0 | INT_PRESENT);
}
g_idtr.size = (sizeof(struct idt_entry) * 256) - 1;
g_idtr.base = (uint32_t) &g_idt;
asm volatile ("lidt %0" :: "m"(g_idtr));
struct rsdp *found_rsdp = acpi_locate_rsdp();
if (!found_rsdp) {
printf("Failed to find RSDP signature\n");
goto halt;
@ -73,7 +50,6 @@ void kmain(struct multiboot_info *info) {
printf("RSDP detected at 0x%X\n", found_rsdp);
if (found_rsdp->Revision == ACPI_VER_1) {
// ACPI v1.0 is being used
if (!acpi_validate_rsdp_checksum(found_rsdp)) {
printf("RSDP has an invalid checksum\n");
goto halt;
@ -100,26 +76,30 @@ void kmain(struct multiboot_info *info) {
printf("Using ACPI v1.0\n");
struct mcfg *mcfg = acpi_find_sdt(ctx.rsdt, "MCFG");
if (!mcfg) {
printf("Failed to find MCFG\n");
struct fadt *fadt = acpi_locate_sdt(ctx.rsdt, "FACP");
if (!fadt) {
printf("Failed to find FADT\n");
goto halt;
}
printf("Found FADT at 0x%x\n", fadt);
if (fadt->Flags & 1)
printf("Legacy devices are supported.\n");
pic_remap(PIC_1_START, PIC_2_START);
// ACPI version 1.0 is so old that we assume that our PC supports the 8042 ps/2 controller
initialize_8042ps2();
encode_idt_entry(g_idt, 0x21, (uint32_t)&ps2_isr, GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, 0x00), INT_GATE_32 | INT_RING0 | INT_PRESENT);
asm volatile ("sti" ::);
printf("Detected MCFG at 0x%X\n", mcfg);
int entries = (mcfg->h.Length - 44) / 16;
for (int i = 0; i < entries; i++) {
uint32_t addr = (uint32_t)mcfg->entries[i].base_addr;
for (int j = 0; j < 256; j++) {
for (int k = 0; k < 8; k++) {
uint32_t word = readd(addr, 8, i, j, k);
if (word != 0xFFFFFFFF && word) {
printf("%08X\n", word >> 8);
}
}
}
}
struct mcfg *mcfg = acpi_locate_sdt(ctx.rsdt, "MCFG");
if (!mcfg) {
printf("failed to find mcfg\n");
} else {
printf("Found MCFG at 0x%x\n", mcfg);
struct pci_config_space *ide = pcie_find_device(mcfg, MASS_STORAGE_CONTROLLER, IDE_INTERFACE);
if (ide) printf("IDE controller detected. Program Interface: %X\n", ide->program_interface);
}
halt:
for (;;) {}
}

View File

@ -28,6 +28,7 @@ _start:
jmp 0x8:.use_code_seg ; Offset to kernel code descriptor
.use_code_seg:
mov esp, stack_bottom
mov ebp, esp
push ebx
extern kmain
call kmain
@ -37,6 +38,19 @@ _start:
halt:
hlt
jmp halt
global exception_handler
exception_handler:
add esp, 4
mov byte [0xb8000], 'X'
iret
global ps2_isr
ps2_isr:
extern ps2_handler
pushad
cld
call ps2_handler
popad
iret
; GDT for a flat memory layout
; We get access to all memory and can utilize paging
@ -63,9 +77,10 @@ gdtp:
dw gdt_end - gdt_start - 1
dd gdt_start
; Reserve 16KiB of kernel stack space
section .bss
align 4
align 16
stack_top:
resb 16384
stack_bottom:

18
pci.c Normal file
View File

@ -0,0 +1,18 @@
#include <pci.h>
struct pci_config_space *pcie_find_device(struct mcfg *mcfg, uint8_t class, uint8_t subclass) {
int entries = (mcfg->h.Length - 44) / 16;
for (int i = 0; i < entries; i++) {
uint32_t addr = (uint32_t)mcfg->entries[i].base_addr;
for (int j = 0; j < 256; j++) {
for (int k = 0; k < 8; k++) {
struct pci_config_space *cfg = (struct pci_config_space *)PCI_ADDR(addr, i, j, k);
if (cfg->class == class && cfg->subclass == subclass) {
return cfg;
}
}
}
}
return 0;
}

56
pci.h Normal file
View File

@ -0,0 +1,56 @@
#ifndef PCI_H_
#define PCI_H_
#include <stdint.h>
#include <acpi.h>
#define PCI_ADDR(addr, bus, device, func) (addr + ((bus) << 20 | device << 15 | func << 12))
enum PCI_CLASS {
UNCLASSIFIED,
MASS_STORAGE_CONTROLLER,
NETWORK_CONTROLLER,
DISPLAY_CONTROLLER,
MULTIMEDIA_CONTROLLER,
MEMORY_CONTROLLER,
BRIDGE,
COMMUNICATION_CONTROLLER,
GENERIC_SYSTEM_PERIPHERAL,
INPUT_DEVICE_CONTROLLER,
DOCKING_STATION,
PROCESSOR,
SERIAL_BUS_CONTROLLER,
WIRELESS_CONTROLLER,
INTELLIGENT_CONTROLLER,
SATELLITE_COMMUNICATIONS_CONTROLLER,
ENCRYPTION_CONTROLLER,
SIGNAL_PROCESSING_CONTROLLER,
PROCESSING_ACCELERATORS,
};
enum PCI_STORAGE_SUBCLASS {
SCSI_STORAGE_CONTROLLER,
IDE_INTERFACE,
FLOPPY_DISK_CONTROLLER,
IPI_BUS_CONTROLLER,
RAID_BUS_CONTROLLER,
ATA_CONTROLLER,
SATA_CONTROLLER,
};
struct pci_config_space {
uint16_t vendor_id;
uint16_t device_id;
uint16_t command;
uint16_t status;
uint8_t revision_id;
uint8_t program_interface;
uint8_t subclass;
uint8_t class;
};
// TODO: Bruteforce all devices once then store all valid devices in memory rather than bruteforcing every time to search
// TODO: Returning multiple devices
struct pci_config_space *pcie_find_device(struct mcfg *mcfg, uint8_t class, uint8_t subclass);
#endif

30
pic8259.c Normal file
View File

@ -0,0 +1,30 @@
#include <pic8259.h>
void pic_send_eoi(uint8_t irq) {
if (irq > 7)
outportb(PIC_2_COMMAND, PIC_EOI);
else
outportb(PIC_1_COMMAND, PIC_EOI);
}
void pic_remap(int pic1_start, int pic2_start) {
// Mask all IRQ lines
outportb(PIC_1_DATA, 0xff);
outportb(PIC_2_DATA, 0xff);
// Initialize master PIC
outportb(PIC_1_COMMAND, ICW4_NEEDED | INIT_BIT);
outportb(PIC_1_DATA, pic1_start);
outportb(PIC_1_DATA, PIC_1_ICW3);
outportb(PIC_1_DATA, 0x01);
// Initialize slave PIC
outportb(PIC_2_COMMAND, ICW4_NEEDED | INIT_BIT);
outportb(PIC_2_DATA, pic2_start);
outportb(PIC_2_DATA, PIC_2_ICW3);
outportb(PIC_2_DATA, 0x01);
// Unmask
outportb(PIC_1_DATA, 0b11111101);
outportb(PIC_2_DATA, 0b11111101);
}

30
pic8259.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef ANDEWOS_PIC8259_H
#define ANDEWOS_PIC8259_H
#define PIC_1_COMMAND 0x20
#define PIC_2_COMMAND 0xA0
#define PIC_1_DATA 0x21
#define PIC_2_DATA 0xA1
#define PIC_EOI 0x20
#define PIC_1_START 32
#define PIC_2_START 40
#define PIC_1_ICW3 0x04
#define PIC_2_ICW3 0x02
#include <io.h>
enum ICW1 {
ICW4_NEEDED = 0x01,
SINGLE_MODE = 0x02,
INTERVAL_4 = 0x04,
LVL_TRIGGER = 0x08,
INIT_BIT = 0x10,
};
void pic_send_eoi(uint8_t irq);
void pic_remap(int pic1_start, int pic2_start);
#endif

View File

@ -866,6 +866,7 @@ int printf_(const char* format, ...)
char buffer[1];
const int ret = _vsnprintf(_out_char, buffer, (size_t)-1, format, va);
va_end(va);
return ret;
}

View File

@ -32,10 +32,6 @@
#ifndef _PRINTF_H_
#define _PRINTF_H_
#define PRINTF_DISABLE_SUPPORT_FLOAT
#define PRINTF_DISABLE_SUPPORT_EXPONENTIAL
#define PRINTF_DISABLE_SUPPORT_LONG_LONG
#include <stdarg.h>
#include <stddef.h>
@ -62,6 +58,7 @@ void _putchar(char character);
* \return The number of characters that are written into the array, not counting the terminating null character
*/
#define printf printf_
//int printf_(const char* format, ...);
int printf_(const char* format, ...);

432
ps2.c Normal file
View File

@ -0,0 +1,432 @@
#include <ps2.h>
#include <io.h>
#include <pic8259.h>
#include <vga.h>
#include <printf.h>
#include <strcmp.h>
#define cpu_relax asm volatile ("pause" ::);
char shell_buffer[512];
int shell_index;
// TODO: Support dual ports
void initialize_8042ps2() {
// disable ps/2 ports so nothing gets messed up
outportb(PS2_8042_COMMAND, 0xAD);
outportb(PS2_8042_COMMAND, 0xA7);
// flush output buffer
inportb(PS2_8042_DATA);
// get config byte
outportb(PS2_8042_COMMAND, 0x20);
uint8_t config = inportb(0x60);
// disable IRQs and translation, also make sure 0 vals are 0
config &= 0b00110100;
// write our config byte back
outportb(PS2_8042_COMMAND, 0x60);
while (inportb(PS2_8042_STATUS) & 0x2) cpu_relax;
outportb(PS2_8042_DATA, config);
// perform self test
outportb(PS2_8042_COMMAND, 0xAA);
while (!(inportb(PS2_8042_STATUS) & 0x1)) cpu_relax;
uint8_t result = inportb(PS2_8042_DATA);
if (result == 0x55) printf("Passed PS/2 self test!\n");
else printf("Failed!\n");
// perform port test
outportb(PS2_8042_COMMAND, 0xAB);
while (!(inportb(PS2_8042_STATUS) & 0x1)) cpu_relax;
result = inportb(PS2_8042_DATA);
if (!result) printf("Passed PS/2 port 1 test!!\n");
else printf("Failed!\n");
// enable ps/2 port
outportb(PS2_8042_COMMAND, 0xAE);
// enable IRQ 1
config = 0b01100101;
outportb(PS2_8042_COMMAND, 0x60);
while (inportb(PS2_8042_STATUS) & 0x2) cpu_relax;
outportb(PS2_8042_DATA, config);
}
void ps2_handler() {
uint8_t scancode = inportb(0x60);
if (scancode > 0x80) goto eoi;
switch(scancode) {
case KBD_ESC:
break;
case KBD_1:
_putchar('1');
shell_buffer[shell_index++] = '1';
break;
case KBD_2:
_putchar('2');
shell_buffer[shell_index++] = '2';
break;
case KBD_3:
_putchar('3');
shell_buffer[shell_index++] = '3';
break;
case KBD_4:
_putchar('4');
shell_buffer[shell_index++] = '4';
break;
case KBD_5:
_putchar('5');
shell_buffer[shell_index++] = '5';
break;
case KBD_6:
_putchar('6');
shell_buffer[shell_index++] = '6';
break;
case KBD_7:
_putchar('7');
shell_buffer[shell_index++] = '7';
break;
case KBD_8:
_putchar('8');
shell_buffer[shell_index++] = '8';
break;
case KBD_9:
_putchar('9');
shell_buffer[shell_index++] = '9';
break;
case KBD_0:
_putchar('0');
shell_buffer[shell_index++] = '0';
break;
case KBD_MINUS:
_putchar('-');
shell_buffer[shell_index++] = '-';
break;
case KBD_EQUALS:
_putchar('=');
shell_buffer[shell_index++] = '=';
break;
case KBD_BACKSPACE:
if (shell_index > 0) {
popchar();
shell_buffer[--shell_index] = 0;
}
break;
case KBD_TAB:
break;
case KBD_Q:
_putchar('Q');
shell_buffer[shell_index++] = 'Q';
break;
case KBD_W:
_putchar('W');
shell_buffer[shell_index++] = 'W';
break;
case KBD_E:
_putchar('E');
shell_buffer[shell_index++] = 'E';
break;
case KBD_R:
_putchar('R');
shell_buffer[shell_index++] = 'R';
break;
case KBD_T:
_putchar('T');
shell_buffer[shell_index++] = 'T';
break;
case KBD_Y:
_putchar('Y');
shell_buffer[shell_index++] = 'Y';
break;
case KBD_U:
_putchar('U');
shell_buffer[shell_index++] = 'U';
break;
case KBD_I:
_putchar('I');
shell_buffer[shell_index++] = 'I';
break;
case KBD_O:
_putchar('O');
shell_buffer[shell_index++] = 'O';
break;
case KBD_P:
_putchar('P');
shell_buffer[shell_index++] = 'P';
break;
case KBD_LBRACKET:
_putchar('[');
shell_buffer[shell_index++] = '[';
break;
case KBD_RBRACKET:
_putchar(']');
shell_buffer[shell_index++] = ']';
break;
case KBD_ENTER:
printf("\n");
if (strcmp(shell_buffer, "PINGAS") == 0) {
printf("andew pingas detected");
} else if (strcmp(shell_buffer, "HELLO") == 0) {
printf("hi");
} else {
printf("unknown command '%s' idiot", shell_buffer);
}
for (int i = 0; i < 512; i++) {
shell_buffer[i] = 0;
}
shell_index = 0;
printf("\n$ ");
break;
case KBD_LCTRL:
// Handle left control key
break;
case KBD_A:
_putchar('A');
shell_buffer[shell_index++] = 'A';
break;
case KBD_S:
_putchar('S');
shell_buffer[shell_index++] = 'S';
break;
case KBD_D:
_putchar('D');
shell_buffer[shell_index++] = 'D';
break;
case KBD_F:
_putchar('F');
shell_buffer[shell_index++] = 'F';
break;
case KBD_G:
_putchar('G');
shell_buffer[shell_index++] = 'G';
break;
case KBD_H:
_putchar('H');
shell_buffer[shell_index++] = 'H';
break;
case KBD_J:
_putchar('J');
shell_buffer[shell_index++] = 'J';
break;
case KBD_K:
_putchar('K');
shell_buffer[shell_index++] = 'K';
break;
case KBD_L:
_putchar('L');
shell_buffer[shell_index++] = 'L';
break;
case KBD_SEMICOLON:
_putchar(';');
shell_buffer[shell_index++] = ';';
break;
case KBD_APOSTROPHE:
_putchar('\'');
shell_buffer[shell_index++] = '\'';
break;
case KBD_GRAVE:
_putchar('`');
shell_buffer[shell_index++] = '`';
break;
case KBD_LSHIFT:
// Handle left shift key
break;
case KBD_BACKSLASH:
_putchar('\\');
shell_buffer[shell_index++] = '\\';
break;
case KBD_Z:
_putchar('Z');
shell_buffer[shell_index++] = 'Z';
break;
case KBD_X:
_putchar('X');
shell_buffer[shell_index++] = 'X';
break;
case KBD_C:
_putchar('C');
shell_buffer[shell_index++] = 'C';
break;
case KBD_V:
_putchar('V');
shell_buffer[shell_index++] = 'V';
break;
case KBD_B:
_putchar('B');
shell_buffer[shell_index++] = 'B';
break;
case KBD_N:
_putchar('N');
shell_buffer[shell_index++] = 'N';
break;
case KBD_M:
_putchar('M');
shell_buffer[shell_index++] = 'M';
break;
case KBD_COMMA:
_putchar(',');
shell_buffer[shell_index++] = ',';
break;
case KBD_PERIOD:
_putchar('.');
shell_buffer[shell_index++] = '.';
break;
case KBD_SLASH:
_putchar('/');
shell_buffer[shell_index++] = '/';
break;
case KBD_RSHIFT:
// Handle right shift key
break;
case KBD_PRINTSCREEN:
// Handle print screen key
break;
case KBD_LALT:
// Handle left alt key
break;
case KBD_SPACE:
_putchar(' ');
shell_buffer[shell_index++] = ' ';
break;
case KBD_CAPSLOCK:
// Handle caps lock key
break;
case KBD_F1:
// Handle F1 key
break;
case KBD_F2:
// Handle F2 key
break;
case KBD_F3:
// Handle F3 key
break;
case KBD_F4:
// Handle F4 key
break;
case KBD_F5:
// Handle F5 key
break;
case KBD_F6:
// Handle F6 key
break;
case KBD_F7:
// Handle F7 key
break;
case KBD_F8:
// Handle F8 key
break;
case KBD_F9:
// Handle F9 key
break;
case KBD_F10:
// Handle F10 key
break;
case KBD_NUMLOCK:
// Handle num lock key
break;
case KBD_SCROLLLOCK:
// Handle scroll lock key
break;
case KBD_HOME:
// Handle home key
break;
case KBD_UP:
// Handle up arrow key
break;
case KBD_PAGEUP:
// Handle page up key
break;
case KBD_KP_MINUS:
// Handle keypad minus key
break;
case KBD_LEFT:
// Handle left arrow key
break;
case KBD_KP_5:
// Handle keypad 5 key
break;
case KBD_RIGHT:
// Handle right arrow key
break;
case KBD_KP_PLUS:
// Handle keypad plus key
break;
case KBD_END:
// Handle end key
break;
case KBD_DOWN:
// Handle down arrow key
break;
case KBD_PAGEDOWN:
// Handle page down key
break;
case KBD_INSERT:
// Handle insert key
break;
case KBD_DELETE:
// Handle delete key
break;
case KBD_SYSRQ:
// Handle system request key
break;
case KBD_F11:
// Handle F11 key
break;
case KBD_F12:
// Handle F12 key
break;
case KBD_KP_ENTER:
break;
case KBD_RCTRL:
// Handle right control key
break;
case KBD_KP_DIVIDE:
// Handle keypad divide key
break;
case KBD_PRINTSCREEN2:
// Handle print screen key (alternate)
break;
case KBD_RALT:
// Handle right alt key
break;
case KBD_HOME2:
// Handle home key (alternate)
break;
case KBD_UP2:
// Handle up arrow key (alternate)
break;
case KBD_PAGEUP2:
// Handle page up key (alternate)
break;
case KBD_LEFT2:
// Handle left arrow key (alternate)
break;
case KBD_RIGHT2:
// Handle right arrow key (alternate)
break;
case KBD_END2:
// Handle end key (alternate)
break;
case KBD_DOWN2:
// Handle down arrow key (alternate)
break;
case KBD_PAGEDOWN2:
// Handle page down key (alternate)
break;
case KBD_INSERT2:
// Handle insert key (alternate)
break;
case KBD_DELETE2:
// Handle delete key (alternate)
break;
default:
// Handle unknown scan codes
printf("Unknown scan code\n");
break;
}
eoi:
pic_send_eoi(1);
}

115
ps2.h Normal file
View File

@ -0,0 +1,115 @@
#ifndef ANDEWOS_PS2_H
#define ANDEWOS_PS2_H
#define PS2_8042_DATA 0x60
#define PS2_8042_STATUS 0x64
#define PS2_8042_COMMAND 0x64
// SCANCODES
#define KBD_ESC 0x01
#define KBD_1 0x02
#define KBD_2 0x03
#define KBD_3 0x04
#define KBD_4 0x05
#define KBD_5 0x06
#define KBD_6 0x07
#define KBD_7 0x08
#define KBD_8 0x09
#define KBD_9 0x0A
#define KBD_0 0x0B
#define KBD_MINUS 0x0C
#define KBD_EQUALS 0x0D
#define KBD_BACKSPACE 0x0E
#define KBD_TAB 0x0F
#define KBD_Q 0x10
#define KBD_W 0x11
#define KBD_E 0x12
#define KBD_R 0x13
#define KBD_T 0x14
#define KBD_Y 0x15
#define KBD_U 0x16
#define KBD_I 0x17
#define KBD_O 0x18
#define KBD_P 0x19
#define KBD_LBRACKET 0x1A
#define KBD_RBRACKET 0x1B
#define KBD_ENTER 0x1C
#define KBD_LCTRL 0x1D
#define KBD_A 0x1E
#define KBD_S 0x1F
#define KBD_D 0x20
#define KBD_F 0x21
#define KBD_G 0x22
#define KBD_H 0x23
#define KBD_J 0x24
#define KBD_K 0x25
#define KBD_L 0x26
#define KBD_SEMICOLON 0x27
#define KBD_APOSTROPHE 0x28
#define KBD_GRAVE 0x29
#define KBD_LSHIFT 0x2A
#define KBD_BACKSLASH 0x2B
#define KBD_Z 0x2C
#define KBD_X 0x2D
#define KBD_C 0x2E
#define KBD_V 0x2F
#define KBD_B 0x30
#define KBD_N 0x31
#define KBD_M 0x32
#define KBD_COMMA 0x33
#define KBD_PERIOD 0x34
#define KBD_SLASH 0x35
#define KBD_RSHIFT 0x36
#define KBD_PRINTSCREEN 0x37
#define KBD_LALT 0x38
#define KBD_SPACE 0x39
#define KBD_CAPSLOCK 0x3A
#define KBD_F1 0x3B
#define KBD_F2 0x3C
#define KBD_F3 0x3D
#define KBD_F4 0x3E
#define KBD_F5 0x3F
#define KBD_F6 0x40
#define KBD_F7 0x41
#define KBD_F8 0x42
#define KBD_F9 0x43
#define KBD_F10 0x44
#define KBD_NUMLOCK 0x45
#define KBD_SCROLLLOCK 0x46
#define KBD_HOME 0x47
#define KBD_UP 0x48
#define KBD_PAGEUP 0x49
#define KBD_KP_MINUS 0x4A
#define KBD_LEFT 0x4B
#define KBD_KP_5 0x4C
#define KBD_RIGHT 0x4D
#define KBD_KP_PLUS 0x4E
#define KBD_END 0x4F
#define KBD_DOWN 0x50
#define KBD_PAGEDOWN 0x51
#define KBD_INSERT 0x52
#define KBD_DELETE 0x53
#define KBD_SYSRQ 0x54
#define KBD_F11 0x57
#define KBD_F12 0x58
#define KBD_KP_ENTER 0x9C
#define KBD_RCTRL 0x9D
#define KBD_KP_DIVIDE 0xB5
#define KBD_PRINTSCREEN2 0xB7
#define KBD_RALT 0xB8
#define KBD_HOME2 0xC7
#define KBD_UP2 0xC8
#define KBD_PAGEUP2 0xC9
#define KBD_LEFT2 0xCB
#define KBD_RIGHT2 0xCD
#define KBD_END2 0xCF
#define KBD_DOWN2 0xD0
#define KBD_PAGEDOWN2 0xD1
#define KBD_INSERT2 0xD2
#define KBD_DELETE2 0xD3
void initialize_8042ps2();
extern void ps2_isr();
void ps2_handler();
#endif

View File

@ -1,5 +1,15 @@
#include <strcmp.h>
int strcmp(const char *s1, const char *s2)
{
while(*s1 && (*s1 == *s2))
{
s1++;
s2++;
}
return *(const unsigned char*)s1 - *(const unsigned char*)s2;
}
int strncmp( const char * s1, const char * s2, int n ) {
while ( n && *s1 && ( *s1 == *s2 ) )
{

View File

@ -1,6 +1,7 @@
#ifndef RK_STRCMP_
#define RK_STRCMP_
int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, int n);
#endif

2
vga.c
View File

@ -55,7 +55,7 @@ void _putchar(char character) {
set_cursor_pos(next_line);
} else {
video_memory[0] = character;
video_memory[1] = WHITE_ON_BLACK;
//video_memory[1] = WHITE_ON_BLACK;
set_cursor_pos(pos + 1);
}
}