From f1515ad7b58d645fb972fe46de8d09f507020aab Mon Sep 17 00:00:00 2001 From: Nathan Singer Date: Mon, 9 Jun 2025 17:02:46 -0400 Subject: [PATCH] some work with PCI, updated my TODO --- TODO.md | 47 ++++++++++++++++++--------------- kernel/arch/pic/pci.c | 20 +++++++++----- kernel/include/kernel/x86/pci.h | 5 +++- kernel/kmain.c | 5 ++-- libc/stdio/printf.c | 11 ++++++++ libc/stdio/putchar.c | 4 +++ util/bochsrc.txt | 2 +- 7 files changed, 63 insertions(+), 31 deletions(-) diff --git a/TODO.md b/TODO.md index e4fa403..a262528 100644 --- a/TODO.md +++ b/TODO.md @@ -1,34 +1,39 @@ ## What do I need to do? +- Unit testing + (https://wiki.osdev.org/Unit_Testing) + (https://wiki.osdev.org/Troubleshooting#Showing_the_stack_content) + lets implmeent some better testing functions aswell +- Paging & virtual memory + - Setup higher half kernel +- Heap allocator (malloc) + - after this, implment some data structures? cleanup queue? +After the above is done, i want to clean up the code and restructure some stuff +clean up the headers so that we're not exposing kernel functions to the entire c library +and also only make required functions be exposed to the header +Drivers: +PIC - Done +PIT - Done + - Need sleep and timers implemented, ACPI can help with this + - Lets also maybe set up a hardware abstraction for timing interfaces? + +ACPI (use ACPICA?) +PCI, PCIE (i think qemue and bochs dont have legacy PCI, so lets try for PCIE) PS/2 controller --> need to setup some timing device, probably PIT DONE! --> might need to do a PCI controller first, so that i can discover the controllers, to be enabled --> need to setup the USB controller first, so i can disable Legacy USB bios shit --> need to configure ACPI so i can actually detect for the PS/2 controller --> then we can start configuring the PS/2 - --> to properly send data to PS/2 controllers, we need some sort of timing interface, -this way we can timeout if we're being hanged on sending commands to a ps/2 device - - - - -PIT timer, or some sort of timer interface - -perhaps maybe some more things off of the PIC? im not sure - -really after that I want to do more to work towards userspace, so that I can start creating things - -scheduler? -multi processing? threads? -etc +Proper KEYB driver +From here, determine whats needed next for pushing into userspace. +Ideally I would like a shell, and then create some essential userspace posix tools (gnutils?) +POSIX compliant? ### Features I want - A kernel bus - some kind of driver where I can send messages that can eventually be accessed globally by other drives / applications +- modularity in terms of drivers: + - I want drivers to be optional and to not limit functionality + - perhaps this means providing every thing as a hardware abstraction layer, so that when its absent we can have some sort of virtual replacement diff --git a/kernel/arch/pic/pci.c b/kernel/arch/pic/pci.c index 7c2d0a3..a64afa2 100644 --- a/kernel/arch/pic/pci.c +++ b/kernel/arch/pic/pci.c @@ -3,6 +3,12 @@ #include +/** + * None of this is working. I'm assuming that QEMU (and bochs) are using pcie purely memory mapped, without legacy PCI support + * + * so we'll need to setup ACPI first :) + */ + uint16_t pci_config_read_word(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset) { uint32_t address; @@ -15,20 +21,22 @@ uint16_t pci_config_read_word(uint8_t bus, uint8_t slot, uint8_t func, uint8_t o address = (uint32_t) ((lbus << 16) | (lslot << 11) | (lfunc << 8) | (offset & 0xFC) | ((uint32_t) 0x80000000)); + printf("%b\n", address); + outb_32(PCI_CONFIG_ADDRESS, address); - tmp = (uint16_t)((inb(PCI_CONFIG_DATA) >> ((offset & 2) * 8)) * 0xFFFF); + tmp = (uint16_t)((inb(PCI_CONFIG_DATA) >> ((offset & 2) * 8)) & 0xFFFF); return tmp; } -uint16_t pci_check_vendor(uint8_t bus, uint8_t slot) +uint16_t pci_check_vendor(uint8_t bus, uint8_t slot, uint8_t func) { uint16_t vendor, device; - if ((vendor = pci_config_read_word(bus, slot, 0, 0)) != 0xFFFF) { - device = pci_config_read_word(bus, slot, 0, 2); - printf("Device: %d, Vendor: %d\n", device, vendor); + if ((vendor = pci_config_read_word(bus, slot, func, 0)) != 0xFFFF) { + device = pci_config_read_word(bus, slot, func, 2); + // we'll do something here, store all the pcis in memory or something + device++; } return vendor; } - diff --git a/kernel/include/kernel/x86/pci.h b/kernel/include/kernel/x86/pci.h index 9f41c03..992354a 100644 --- a/kernel/include/kernel/x86/pci.h +++ b/kernel/include/kernel/x86/pci.h @@ -8,6 +8,9 @@ uint16_t pci_config_read_word(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset); -uint16_t pci_check_vendor(uint8_t bus, uint8_t slot); +uint16_t pci_check_vendor(uint8_t bus, uint8_t slot, uint8_t func); + +void check_all_busses(void); + #endif diff --git a/kernel/kmain.c b/kernel/kmain.c index c03abbc..8083356 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -10,7 +10,7 @@ #include #include -#include +#include void kmain(void) @@ -31,7 +31,8 @@ void kmain(void) init_pit(0x36, PIT_CHANNEL_0, 0); - printf("%f\n", get_time_from_divisor(10)); + + printf("%d\n", pci_config_read_word(0, 1, 1, 6)); printf("Entering loop...\n"); while (1) { diff --git a/libc/stdio/printf.c b/libc/stdio/printf.c index 5a12156..f1e4a7f 100644 --- a/libc/stdio/printf.c +++ b/libc/stdio/printf.c @@ -161,6 +161,17 @@ int printf(const char* restrict format, ...) { if (!print(buffer, len)) return -1; written += len; + } else if (*format == 'b') { + format++; + uint32_t i = (uint32_t) va_arg(parameters, uint32_t); + u32toa(i, buffer, 2); + size_t len = strlen(buffer); + if (maxrem < len) { + return -1; + } + if (!print(buffer, len)) + return -1; + written += len; } else { format = format_begun_at; size_t len = strlen(format); diff --git a/libc/stdio/putchar.c b/libc/stdio/putchar.c index abbd6e9..8ad97d3 100644 --- a/libc/stdio/putchar.c +++ b/libc/stdio/putchar.c @@ -13,6 +13,10 @@ int putchar(int ic) { terminal_write(&c, sizeof(c)); #ifdef __TESTING__ serial_write(&c, sizeof(c)); + if (c == '\n') { + char tmp = '\r'; + serial_write(&tmp, sizeof(tmp)); + } #endif #else // TODO: Implement stdio and the write system call. diff --git a/util/bochsrc.txt b/util/bochsrc.txt index cdc7dc5..c5be528 100644 --- a/util/bochsrc.txt +++ b/util/bochsrc.txt @@ -8,4 +8,4 @@ log: bochslog.txt clock: sync=realtime, time0=local cpu: count=1, ips=10000000 com1: enabled=1, mode=file, dev=com1.out - +usb_uhci: port1=mouse, port2=disk, options2="path:usbstick.img"