From 6a1867b5d2bf9a6af6ebc83b77bc2656e796b67b Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Thu, 31 Aug 2017 12:33:37 -0500 Subject: [PATCH 001/171] created files needed --- .../PCI/USB/HostController/HostController.cpp | 18 ++++++++++++++++++ .../PCI/USB/HostController/HostController.h | 17 +++++++++++++++++ src/drivers/PCI/USB/HostController/OHCI.cpp | 18 ++++++++++++++++++ src/drivers/PCI/USB/HostController/OHCI.h | 19 +++++++++++++++++++ src/drivers/PCI/USB/HostController/makefile | 3 +++ src/drivers/PCI/USB/makefile | 2 +- 6 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 src/drivers/PCI/USB/HostController/HostController.cpp create mode 100644 src/drivers/PCI/USB/HostController/HostController.h create mode 100644 src/drivers/PCI/USB/HostController/OHCI.cpp create mode 100644 src/drivers/PCI/USB/HostController/OHCI.h create mode 100644 src/drivers/PCI/USB/HostController/makefile diff --git a/src/drivers/PCI/USB/HostController/HostController.cpp b/src/drivers/PCI/USB/HostController/HostController.cpp new file mode 100644 index 000000000..f98ec6434 --- /dev/null +++ b/src/drivers/PCI/USB/HostController/HostController.cpp @@ -0,0 +1,18 @@ +/* + * HostController.cpp + * + * Created on: Aug 31, 2017 + * Author: garrett + */ + +#include "HostController.h" + +HostController::HostController( ) { + // TODO Auto-generated constructor stub + +} + +HostController::~HostController( ) { + // TODO Auto-generated destructor stub +} + diff --git a/src/drivers/PCI/USB/HostController/HostController.h b/src/drivers/PCI/USB/HostController/HostController.h new file mode 100644 index 000000000..0e6def28c --- /dev/null +++ b/src/drivers/PCI/USB/HostController/HostController.h @@ -0,0 +1,17 @@ +/* + * HostController.h + * + * Created on: Aug 31, 2017 + * Author: garrett + */ + +#ifndef SRC_DRIVERS_PCI_USB_HOSTCONTROLLER_HOSTCONTROLLER_H_ +#define SRC_DRIVERS_PCI_USB_HOSTCONTROLLER_HOSTCONTROLLER_H_ + +class HostController { + public: + HostController( ); + virtual ~HostController( ); +}; + +#endif /* SRC_DRIVERS_PCI_USB_HOSTCONTROLLER_HOSTCONTROLLER_H_ */ diff --git a/src/drivers/PCI/USB/HostController/OHCI.cpp b/src/drivers/PCI/USB/HostController/OHCI.cpp new file mode 100644 index 000000000..c1da94aa0 --- /dev/null +++ b/src/drivers/PCI/USB/HostController/OHCI.cpp @@ -0,0 +1,18 @@ +/* + * OHCI.cpp + * + * Created on: Aug 31, 2017 + * Author: garrett + */ + +#include "OHCI.h" + +OHCI::OHCI( ) { + // TODO Auto-generated constructor stub + +} + +OHCI::~OHCI( ) { + // TODO Auto-generated destructor stub +} + diff --git a/src/drivers/PCI/USB/HostController/OHCI.h b/src/drivers/PCI/USB/HostController/OHCI.h new file mode 100644 index 000000000..60402c4b4 --- /dev/null +++ b/src/drivers/PCI/USB/HostController/OHCI.h @@ -0,0 +1,19 @@ +/* + * OHCI.h + * + * Created on: Aug 31, 2017 + * Author: garrett + */ + +#ifndef SRC_DRIVERS_PCI_USB_HOSTCONTROLLER_OHCI_H_ +#define SRC_DRIVERS_PCI_USB_HOSTCONTROLLER_OHCI_H_ + +#include "HostController.h" + +class OHCI: public HostController { + public: + OHCI( ); + virtual ~OHCI( ); +}; + +#endif /* SRC_DRIVERS_PCI_USB_HOSTCONTROLLER_OHCI_H_ */ diff --git a/src/drivers/PCI/USB/HostController/makefile b/src/drivers/PCI/USB/HostController/makefile new file mode 100644 index 000000000..957883fd2 --- /dev/null +++ b/src/drivers/PCI/USB/HostController/makefile @@ -0,0 +1,3 @@ +SUBDIRS = +OBS = OHCI.o HostController.o +include ../../../../../makefile.inc \ No newline at end of file diff --git a/src/drivers/PCI/USB/makefile b/src/drivers/PCI/USB/makefile index 0aa843d37..73adc61d3 100644 --- a/src/drivers/PCI/USB/makefile +++ b/src/drivers/PCI/USB/makefile @@ -1,4 +1,4 @@ -SUBDIRS = +SUBDIRS = HostController OBS = USB.o USBController.o include ../../../../makefile.inc \ No newline at end of file From 5ad277ef7aef98a1d43ee2f16713cc62b089e3eb Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 4 Sep 2017 09:42:26 -0500 Subject: [PATCH 002/171] read registers for OHCI device --- src/drivers/PCI/PCIDevices/PCIDevice.h | 4 +- .../PCI/USB/HostController/HostController.h | 21 ++++++ src/drivers/PCI/USB/HostController/OHCI.h | 67 +++++++++++++++++++ 3 files changed, 89 insertions(+), 3 deletions(-) diff --git a/src/drivers/PCI/PCIDevices/PCIDevice.h b/src/drivers/PCI/PCIDevices/PCIDevice.h index aba98d74f..5e07d3153 100644 --- a/src/drivers/PCI/PCIDevices/PCIDevice.h +++ b/src/drivers/PCI/PCIDevices/PCIDevice.h @@ -20,9 +20,7 @@ class PCIDevice { public: PCIDevice( ); PCIDevice(uint8_t bus, uint8_t device, uint8_t function, bool page); - virtual ~PCIDevice( ){ - - } + virtual ~PCIDevice( )=0; uint16_t deviceID(); uint16_t venderID(); uint16_t status(); diff --git a/src/drivers/PCI/USB/HostController/HostController.h b/src/drivers/PCI/USB/HostController/HostController.h index 0e6def28c..bd9d63eed 100644 --- a/src/drivers/PCI/USB/HostController/HostController.h +++ b/src/drivers/PCI/USB/HostController/HostController.h @@ -9,8 +9,29 @@ #define SRC_DRIVERS_PCI_USB_HOSTCONTROLLER_HOSTCONTROLLER_H_ class HostController { + protected: + void* _BAR0; + void* _BAR1; + void* _BAR2; + void* _BAR3; + void* _BAR4; public: HostController( ); + HostController(void** baseAddresses) { + _BAR0 = baseAddresses[0]; + _BAR1 = baseAddresses[1]; + _BAR2 = baseAddresses[2]; + _BAR3 = baseAddresses[3]; + _BAR4 = baseAddresses[4]; + } + HostController(void* BAR0, void* BAR1 = nullptr, void* BAR2 = nullptr, + void* BAR3 = nullptr, void* BAR4 = nullptr) { + _BAR0 = BAR0; + _BAR1 = BAR1; + _BAR2 = BAR2; + _BAR3 = BAR3; + _BAR4 = BAR4; + } virtual ~HostController( ); }; diff --git a/src/drivers/PCI/USB/HostController/OHCI.h b/src/drivers/PCI/USB/HostController/OHCI.h index 60402c4b4..ce675d592 100644 --- a/src/drivers/PCI/USB/HostController/OHCI.h +++ b/src/drivers/PCI/USB/HostController/OHCI.h @@ -8,12 +8,79 @@ #ifndef SRC_DRIVERS_PCI_USB_HOSTCONTROLLER_OHCI_H_ #define SRC_DRIVERS_PCI_USB_HOSTCONTROLLER_OHCI_H_ +#include "../../../../global.h" #include "HostController.h" class OHCI: public HostController { public: OHCI( ); + OHCI(void* BAR0) : + HostController(BAR0) { + + } virtual ~OHCI( ); + uint32_t revision( ) { + return * ((uint32_t*) _BAR0); + } + uint32_t commandStatus( ) { + return * ((uint32_t*) _BAR0 + 1); + } + uint32_t interruptStatus( ) { + return * ((uint32_t*) _BAR0 +2 ); + } + uint32_t interruptEnable( ) { + return * ((uint32_t*) _BAR0+3); + } + uint32_t interruptDisable( ) { + return * ((uint32_t*) _BAR0+4); + } + uint32_t HCCA( ) { + return * ((uint32_t*) _BAR0+5); + } + uint32_t periodCurrent( ) { + return * ((uint32_t*) _BAR0+6); + } + uint32_t controlHead( ) { + return * ((uint32_t*) _BAR0+7); + } + uint32_t controlCurrent( ) { + return * ((uint32_t*) _BAR0+8); + } + uint32_t bulkHead( ) { + return * ((uint32_t*) _BAR0+9); + } + uint32_t bulkCurrent( ) { + return * ((uint32_t*) _BAR0+10); + } + uint32_t doneHead( ) { + return * ((uint32_t*) _BAR0+11); + } + uint32_t fmInterval( ) { + return * ((uint32_t*) _BAR0+12); + } + uint32_t fmRemaining( ) { + return * ((uint32_t*) _BAR0+13); + + } + uint32_t fmNumber( ) { + return * ((uint32_t*) _BAR0+14); + } + uint32_t periodicStart( ) { + return * ((uint32_t*) _BAR0+15); + } + uint32_t lsThreshold( ) { + return * ((uint32_t*) _BAR0+16); + } + uint32_t rhDescriptorA( ) { + return * ((uint32_t*) _BAR0+17); + + } + uint32_t rhDescriptorB( ) { + return * ((uint32_t*) _BAR0+18); + } + uint32_t rhStatus( ) { + return * ((uint32_t*) _BAR0+19); + } }; #endif /* SRC_DRIVERS_PCI_USB_HOSTCONTROLLER_OHCI_H_ */ From 9b518a81e099f3af5b45f9bb16fc6ebabc2697f2 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 5 Sep 2017 11:23:44 -0500 Subject: [PATCH 003/171] small fix to PCI device base class. didn't impliment the destrctor --- makefile.inc | 2 +- src/drivers/PCI/PCIDevices/PCIDevice.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/makefile.inc b/makefile.inc index 38cd8ac1e..e92f0251f 100644 --- a/makefile.inc +++ b/makefile.inc @@ -2,7 +2,7 @@ AS = /home/garrett/opt/cross/bin/i686-elf-as GPP = /home/garrett/opt/cross/bin/i686-elf-g++ GCC = /home/garrett/opt/cross/bin/i686-elf-gcc OS_CPP = /home/garrett/workspace/ExOS -BUILD_TO = /run/media/garrett/disk/boot/kernel.bin +BUILD_TO = /run/media/garrett/EXOS/boot/kernel.bin CFLAGS = -c -ffreestanding -O2 -Wall -Wextra -fno-rtti -fno-exceptions OBJ_DIR = $(OS_CPP)/build diff --git a/src/drivers/PCI/PCIDevices/PCIDevice.cpp b/src/drivers/PCI/PCIDevices/PCIDevice.cpp index 00ea4e848..00dd74b66 100644 --- a/src/drivers/PCI/PCIDevices/PCIDevice.cpp +++ b/src/drivers/PCI/PCIDevices/PCIDevice.cpp @@ -11,6 +11,9 @@ PCIDevice::PCIDevice( ) { // TODO Auto-generated constructor stub +} +PCIDevice::~PCIDevice(){ + } PCIDevice::PCIDevice(uint8_t bus, uint8_t device, uint8_t function, bool page) { _bus = bus; From 8063e0ac9bd9611bbede4f2af20d49c972dedfd9 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 12 Sep 2017 13:05:32 -0500 Subject: [PATCH 004/171] builds and runs (#30) * Changed the way includes are handled GCC now searches in $(OS_CPP)/src for the includes, so you can specify the directory directly (haha I'm funny, now laugh) instead of using realtive paths. Example: "Global.h" instead of "../../../Global.h" * fixed renames --- makefile | 4 ++-- makefile.inc | 6 +++--- src/{global.h => Global.h} | 0 src/boot/{boot.s => Boot.s} | 0 src/clib_misc/Abort.c | 4 ++-- src/clib_misc/Abort.h | 2 +- src/drivers/Keyboard.cpp | 2 +- src/drivers/Keyboard.h | 2 +- src/drivers/PCI/PCI.c | 2 +- src/drivers/PCI/PCI.h | 2 +- src/drivers/PCI/PCIDeviceList.cpp | 12 ++++++------ src/drivers/PCI/PCIDeviceList.h | 4 ++-- src/drivers/PCI/PCI_devices/PCIBridgeDevice.cpp | 2 +- src/drivers/PCI/PCI_devices/PCIBridgeDevice.h | 4 ++-- src/drivers/PCI/PCI_devices/PCICardBusDevice.cpp | 2 +- src/drivers/PCI/PCI_devices/PCICardBusDevice.h | 4 ++-- src/drivers/PCI/PCI_devices/PCIDevice.cpp | 4 ++-- src/drivers/PCI/PCI_devices/PCIDevice.h | 2 +- src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp | 4 ++-- src/drivers/PCI/PCI_devices/PCIStandardDevice.h | 4 ++-- src/drivers/PCI/USB/USB.c | 2 +- src/drivers/PCI/USB/USB.h | 2 +- src/drivers/PCI/USB/USBController.cpp | 2 +- src/drivers/PCI/USB/USBController.h | 2 +- src/drivers/ProgrammableInterruptController.cpp | 2 +- src/drivers/ProgrammableInterruptController.h | 2 +- src/drivers/TTY/Console.cpp | 14 ++++++++------ src/drivers/TTY/Console.h | 2 +- src/interrupts/InterruptDescriptorTable.cpp | 2 +- src/interrupts/InterruptDescriptorTable.h | 2 +- src/interrupts/InterruptHandler.cpp | 10 +++++----- src/interrupts/InterruptHandler.h | 2 +- src/memory/Mem.cpp | 4 ++-- src/memory/Mem.h | 6 +++--- src/memory/alloc/Malloc.c | 8 ++++---- src/memory/alloc/Malloc.h | 2 +- src/memory/alloc/New.cpp | 2 +- src/memory/alloc/New.h | 2 +- src/memory/alloc/PageFrameAllocator.cpp | 6 +++--- src/memory/alloc/PageFrameAllocator.h | 2 +- src/memory/structures/GlobalDescriptorTable.cpp | 4 ++-- src/memory/structures/GlobalDescriptorTable.h | 2 +- src/memory/structures/PageTable.cpp | 2 +- src/memory/structures/PageTable.h | 2 +- src/multiboot_spec/{multiboot.h => Multiboot.h} | 0 .../Linked_List => utils/linked_list}/LinkedList.h | 4 ++-- .../linked_list}/LinkedListNode.h | 0 .../Linked_List => utils/linked_list}/makefile | 0 src/{Utils => utils}/makefile | 0 src/utils/printf/Printf.cpp | 4 ++-- .../printf/printf.h => utils/printf/Printf.h} | 0 src/{Utils => utils}/printf/makefile | 0 52 files changed, 81 insertions(+), 79 deletions(-) rename src/{global.h => Global.h} (100%) rename src/boot/{boot.s => Boot.s} (100%) rename src/multiboot_spec/{multiboot.h => Multiboot.h} (100%) rename src/{Utils/Linked_List => utils/linked_list}/LinkedList.h (91%) rename src/{Utils/Linked_List => utils/linked_list}/LinkedListNode.h (100%) rename src/{Utils/Linked_List => utils/linked_list}/makefile (100%) rename src/{Utils => utils}/makefile (100%) rename src/{Utils/printf/printf.h => utils/printf/Printf.h} (100%) rename src/{Utils => utils}/printf/makefile (100%) diff --git a/makefile b/makefile index d0ee47d4f..fae5c1fbe 100644 --- a/makefile +++ b/makefile @@ -5,8 +5,8 @@ SUBDIRS = src include makefile.inc kernel.bin: $(SUBDIRS) - @$(GCC) -T $(OS_CPP)/linker.ld -o $(BUILD_TO) -ffreestanding -O2 -fno-rtti -fno-exceptions -nostartfiles -nostdlib $(OBJ_DIR)/*.o -lgcc + @$(GCC) -T $(OS_CPP)/linker.ld -o $(BUILD_TO) -ffreestanding -O2 -fno-rtti -fno-exceptions -nostartfiles -nostdlib $(OBJ_DIR)/*.o -lgcc @sync clean: - rm $(OBJ_DIR)/*.o \ No newline at end of file + rm $(OBJ_DIR)/*.o diff --git a/makefile.inc b/makefile.inc index 425c9712a..984f162ec 100644 --- a/makefile.inc +++ b/makefile.inc @@ -1,9 +1,9 @@ AS = i686-elf-as GPP = i686-elf-g++ GCC = i686-elf-gcc -OS_CPP = /media/sdcard/ExOS -BUILD_TO = /mnt/boot/kernel.bin -CFLAGS = -c -ffreestanding -O2 -Wall -Wextra -fno-rtti -fno-exceptions -std=gnu++14 +OS_CPP = /home/garrett/workspace/ExOS +BUILD_TO = /run/media/garrett/EXOS/boot/kernel.bin +CFLAGS = -c -ffreestanding -O2 -Wall -Wextra -fno-rtti -fno-exceptions -std=gnu++14 -I$(OS_CPP)/src OBJ_DIR = $(OS_CPP)/build %.o: %.c diff --git a/src/global.h b/src/Global.h similarity index 100% rename from src/global.h rename to src/Global.h diff --git a/src/boot/boot.s b/src/boot/Boot.s similarity index 100% rename from src/boot/boot.s rename to src/boot/Boot.s diff --git a/src/clib_misc/Abort.c b/src/clib_misc/Abort.c index e92a47ff7..9da693f30 100644 --- a/src/clib_misc/Abort.c +++ b/src/clib_misc/Abort.c @@ -5,8 +5,8 @@ * Created on: Aug 14, 2017 * Author: garrett */ -#include "abort.h" -#include "../drivers/TTY/Console.h" +#include "clib_misc/Abort.h" +#include "drivers/TTY/Console.h" extern "C" void /*__cxxabiv1::*/__cxa_pure_virtual(void) { diff --git a/src/clib_misc/Abort.h b/src/clib_misc/Abort.h index 0f8d1cf66..3d04a2390 100644 --- a/src/clib_misc/Abort.h +++ b/src/clib_misc/Abort.h @@ -8,7 +8,7 @@ #ifndef SRC_CLIBMISC_ABORT_H_ #define SRC_CLIBMISC_ABORT_H_ -#include "../global.h" +#include "Global.h" #if defined(__cplusplus) extern "C" {/* Use C linkage for kernel_main. */ diff --git a/src/drivers/Keyboard.cpp b/src/drivers/Keyboard.cpp index 38ec07d5c..2efa76a38 100644 --- a/src/drivers/Keyboard.cpp +++ b/src/drivers/Keyboard.cpp @@ -5,7 +5,7 @@ * Author: garrett */ -#include "Keyboard.h" +#include "drivers/Keyboard.h" Keyboard::Keyboard( ) { diff --git a/src/drivers/Keyboard.h b/src/drivers/Keyboard.h index e5f740e07..755108683 100644 --- a/src/drivers/Keyboard.h +++ b/src/drivers/Keyboard.h @@ -8,7 +8,7 @@ #ifndef KEYBOARD_H_ #define KEYBOARD_H_ -#include "../Global.h" +#include "Global.h" /** * the possible scan code sets */ diff --git a/src/drivers/PCI/PCI.c b/src/drivers/PCI/PCI.c index 9fd36c6c7..42b060534 100644 --- a/src/drivers/PCI/PCI.c +++ b/src/drivers/PCI/PCI.c @@ -5,7 +5,7 @@ * Author: garrett */ -#include "PCI.h" +#include "drivers/PCI/PCI.h" //TODO clean up a lot diff --git a/src/drivers/PCI/PCI.h b/src/drivers/PCI/PCI.h index 865aad3d1..b779a352b 100644 --- a/src/drivers/PCI/PCI.h +++ b/src/drivers/PCI/PCI.h @@ -8,7 +8,7 @@ #ifndef SRC_DRIVERS_PCI_PCI_H_ #define SRC_DRIVERS_PCI_PCI_H_ -#include "../../Global.h" +#include "Global.h" extern int8_t MAX_PCI_FUNCTIONS; /** diff --git a/src/drivers/PCI/PCIDeviceList.cpp b/src/drivers/PCI/PCIDeviceList.cpp index cb4728844..4f343eb04 100644 --- a/src/drivers/PCI/PCIDeviceList.cpp +++ b/src/drivers/PCI/PCIDeviceList.cpp @@ -6,12 +6,12 @@ * Author: garrett */ -#include "PCIDeviceList.h" -#include "PCI.h" -#include "PCI_devices/PCIStandardDevice.h" -#include "PCI_devices/PCIBridgeDevice.h" -#include "PCI_devices/PCICardBusDevice.h" -#include "../TTY/Console.h" +#include "drivers/PCI/PCIDeviceList.h" +#include "drivers/PCI/PCI.h" +#include "drivers/PCI/PCI_devices/PCIStandardDevice.h" +#include "drivers/PCI/PCI_devices/PCIBridgeDevice.h" +#include "drivers/PCI/PCI_devices/PCICardBusDevice.h" +#include "drivers/TTY/Console.h" PCIDeviceList::PCIDeviceList( ) { _list = new LinkedList; diff --git a/src/drivers/PCI/PCIDeviceList.h b/src/drivers/PCI/PCIDeviceList.h index b3a323b09..a5fc5ad94 100644 --- a/src/drivers/PCI/PCIDeviceList.h +++ b/src/drivers/PCI/PCIDeviceList.h @@ -8,8 +8,8 @@ #ifndef SRC_DRIVERS_PCI_PCIDEVICELIST_H_ #define SRC_DRIVERS_PCI_PCIDEVICELIST_H_ -#include "../../Global.h" -#include "../../utils/linked_list/LinkedList.h" +#include "Global.h" +#include "utils/linked_list/LinkedList.h" class PCIDevice; diff --git a/src/drivers/PCI/PCI_devices/PCIBridgeDevice.cpp b/src/drivers/PCI/PCI_devices/PCIBridgeDevice.cpp index 9e8659657..6a5a17e7d 100644 --- a/src/drivers/PCI/PCI_devices/PCIBridgeDevice.cpp +++ b/src/drivers/PCI/PCI_devices/PCIBridgeDevice.cpp @@ -4,7 +4,7 @@ * Created on: Aug 16, 2017 * Author: garrett */ -#include "PCIBridgeDevice.h" +#include "drivers/PCI/PCI_devices/PCIBridgeDevice.h" PCIBridgeDevice::PCIBridgeDevice( ) { // TODO Auto-generated constructor stub diff --git a/src/drivers/PCI/PCI_devices/PCIBridgeDevice.h b/src/drivers/PCI/PCI_devices/PCIBridgeDevice.h index 2c28a2ad5..b43c306c5 100644 --- a/src/drivers/PCI/PCI_devices/PCIBridgeDevice.h +++ b/src/drivers/PCI/PCI_devices/PCIBridgeDevice.h @@ -8,8 +8,8 @@ #ifndef SRC_DRIVERS_PCI_PCIDEVICES_PCIBRIDGEDEVICE_H_ #define SRC_DRIVERS_PCI_PCIDEVICES_PCIBRIDGEDEVICE_H_ -#include "PCIDevice.h" -#include "../../../Global.h" +#include "drivers/PCI/PCI_devices/PCIDevice.h" +#include "Global.h" class PCIBridgeDevice: public PCIDevice { public: diff --git a/src/drivers/PCI/PCI_devices/PCICardBusDevice.cpp b/src/drivers/PCI/PCI_devices/PCICardBusDevice.cpp index 36eaf8895..550836605 100644 --- a/src/drivers/PCI/PCI_devices/PCICardBusDevice.cpp +++ b/src/drivers/PCI/PCI_devices/PCICardBusDevice.cpp @@ -4,7 +4,7 @@ * Created on: Aug 16, 2017 * Author: garrett */ -#include "PCICardBusDevice.h" +#include "drivers/PCI/PCI_devices/PCICardBusDevice.h" PCICardBusDevice::PCICardBusDevice( ) { // TODO Auto-generated constructor stub diff --git a/src/drivers/PCI/PCI_devices/PCICardBusDevice.h b/src/drivers/PCI/PCI_devices/PCICardBusDevice.h index 46ba3cf7e..8ebe4f608 100644 --- a/src/drivers/PCI/PCI_devices/PCICardBusDevice.h +++ b/src/drivers/PCI/PCI_devices/PCICardBusDevice.h @@ -8,8 +8,8 @@ #ifndef SRC_DRIVERS_PCI_PCIDEVICES_PCICARDBUSDEVICE_H_ #define SRC_DRIVERS_PCI_PCIDEVICES_PCICARDBUSDEVICE_H_ -#include "PCIDevice.h" -#include "../../../Global.h" +#include "drivers/PCI/PCI_devices/PCIDevice.h" +#include "Global.h" class PCICardBusDevice: public PCIDevice { public: diff --git a/src/drivers/PCI/PCI_devices/PCIDevice.cpp b/src/drivers/PCI/PCI_devices/PCIDevice.cpp index 00ea4e848..9aec5d883 100644 --- a/src/drivers/PCI/PCI_devices/PCIDevice.cpp +++ b/src/drivers/PCI/PCI_devices/PCIDevice.cpp @@ -5,8 +5,8 @@ * Author: garrett */ -#include "PCIDevice.h" -#include "../PCI.h" +#include "drivers/PCI/PCI_devices/PCIDevice.h" +#include "drivers/PCI/PCI.h" PCIDevice::PCIDevice( ) { // TODO Auto-generated constructor stub diff --git a/src/drivers/PCI/PCI_devices/PCIDevice.h b/src/drivers/PCI/PCI_devices/PCIDevice.h index 87f048540..56000d426 100644 --- a/src/drivers/PCI/PCI_devices/PCIDevice.h +++ b/src/drivers/PCI/PCI_devices/PCIDevice.h @@ -8,7 +8,7 @@ #ifndef SRC_DRIVERS_PCI_PCIDEVICE_H_ #define SRC_DRIVERS_PCI_PCIDEVICE_H_ -#include "../../../Global.h" +#include "Global.h" class PCIDevice { diff --git a/src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp b/src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp index 2770dd9cc..10b9e0b4c 100644 --- a/src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp +++ b/src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp @@ -5,8 +5,8 @@ * Author: garrett */ -#include "PCIStandardDevice.h" -#include "../PCI.h" +#include "drivers/PCI/PCI_devices/PCIStandardDevice.h" +#include "drivers/PCI/PCI.h" PCIStandardDevice::PCIStandardDevice( ) : PCIDevice( ) { diff --git a/src/drivers/PCI/PCI_devices/PCIStandardDevice.h b/src/drivers/PCI/PCI_devices/PCIStandardDevice.h index 1a9910ff0..13339ec39 100644 --- a/src/drivers/PCI/PCI_devices/PCIStandardDevice.h +++ b/src/drivers/PCI/PCI_devices/PCIStandardDevice.h @@ -8,8 +8,8 @@ #ifndef PCISTANDARDDEVICE_H_ #define PCISTANDARDDEVICE_H_ -#include "../../../global.h" -#include "PCIDevice.h" +#include "Global.h" +#include "drivers/PCI/PCI_devices/PCIDevice.h" //class PCIDevice; diff --git a/src/drivers/PCI/USB/USB.c b/src/drivers/PCI/USB/USB.c index 7acfd6a39..e9cb4b5d2 100644 --- a/src/drivers/PCI/USB/USB.c +++ b/src/drivers/PCI/USB/USB.c @@ -5,7 +5,7 @@ * Author: garrett */ -#include "USB.h" +#include "drivers/PCI/USB/USB.h" uint8_t maxUSBVersion = 0; USBController* uSBControllers; diff --git a/src/drivers/PCI/USB/USB.h b/src/drivers/PCI/USB/USB.h index 4a8ca016b..78786cc50 100644 --- a/src/drivers/PCI/USB/USB.h +++ b/src/drivers/PCI/USB/USB.h @@ -8,7 +8,7 @@ #ifndef SRC_DRIVERS_PCI_USB_USB_H_ #define SRC_DRIVERS_PCI_USB_USB_H_ -#include "../../../Global.h" +#include "Global.h" class USBController; extern uint8_t maxUSBVersion; diff --git a/src/drivers/PCI/USB/USBController.cpp b/src/drivers/PCI/USB/USBController.cpp index 1c4c9d97b..9f0c55fa1 100644 --- a/src/drivers/PCI/USB/USBController.cpp +++ b/src/drivers/PCI/USB/USBController.cpp @@ -5,7 +5,7 @@ * Author: garrett */ -#include "USBController.h" +#include "drivers/PCI/USB/USBController.h" USBController::USBController( ) { // TODO Auto-generated constructor stub diff --git a/src/drivers/PCI/USB/USBController.h b/src/drivers/PCI/USB/USBController.h index 64fbc72be..e0bd6873e 100644 --- a/src/drivers/PCI/USB/USBController.h +++ b/src/drivers/PCI/USB/USBController.h @@ -8,7 +8,7 @@ #ifndef USBCONTROLLER_H_ #define USBCONTROLLER_H_ -#include "../../../Global.h" +#include "Global.h" class USBController { public: diff --git a/src/drivers/ProgrammableInterruptController.cpp b/src/drivers/ProgrammableInterruptController.cpp index f6efa470b..a5ef83f81 100755 --- a/src/drivers/ProgrammableInterruptController.cpp +++ b/src/drivers/ProgrammableInterruptController.cpp @@ -5,7 +5,7 @@ * Author: garrett */ -#include "ProgrammableInterruptController.h" +#include "drivers/ProgrammableInterruptController.h" //TODO comment diff --git a/src/drivers/ProgrammableInterruptController.h b/src/drivers/ProgrammableInterruptController.h index 60732383b..f21b915ee 100755 --- a/src/drivers/ProgrammableInterruptController.h +++ b/src/drivers/ProgrammableInterruptController.h @@ -8,7 +8,7 @@ #ifndef PROGRAMMABLEINTERRUPTCONTROLLER_H_ #define PROGRAMMABLEINTERRUPTCONTROLLER_H_ -#include "../Global.h" +#include "Global.h" /* diff --git a/src/drivers/TTY/Console.cpp b/src/drivers/TTY/Console.cpp index 15e7f50a0..ed6809b54 100644 --- a/src/drivers/TTY/Console.cpp +++ b/src/drivers/TTY/Console.cpp @@ -6,11 +6,11 @@ * Oskari */ -#include "Console.h" -#include "../../Kernel.h" -#include "../Keyboard.h" -#include "../../memory/structures/PageTable.h" -#include "../../memory/Mem.h" +#include "drivers/TTY/Console.h" +#include "Kernel.h" +#include "drivers/Keyboard.h" +#include "memory/structures/PageTable.h" +#include "memory/Mem.h" /** * Function prototype for the internal use newline() @@ -293,7 +293,9 @@ void writeIntBase(uint64_t num, uint64_t base) { /* Skip to the first non null char */ int pos; - for (pos = 0; !out[pos]; pos++); + for (pos = 0; !out[pos]; pos++){ + + } terminalWriteString((const char*)(out + pos)); } diff --git a/src/drivers/TTY/Console.h b/src/drivers/TTY/Console.h index 1281b5883..066a37ec0 100644 --- a/src/drivers/TTY/Console.h +++ b/src/drivers/TTY/Console.h @@ -9,7 +9,7 @@ #ifndef CONSOLE_H_ #define CONSOLE_H_ -#include "../../Global.h" +#include "Global.h" /** * Dimensions of the VGA console diff --git a/src/interrupts/InterruptDescriptorTable.cpp b/src/interrupts/InterruptDescriptorTable.cpp index ae84874eb..fe800bd05 100644 --- a/src/interrupts/InterruptDescriptorTable.cpp +++ b/src/interrupts/InterruptDescriptorTable.cpp @@ -5,7 +5,7 @@ * Author: garrett */ -#include "InterruptDescriptorTable.h" +#include "interrupts/InterruptDescriptorTable.h" //TODO comment what each interrupt is InterruptDescriptorTable::InterruptDescriptorTable( ) { diff --git a/src/interrupts/InterruptDescriptorTable.h b/src/interrupts/InterruptDescriptorTable.h index 237b0400b..36a42e246 100644 --- a/src/interrupts/InterruptDescriptorTable.h +++ b/src/interrupts/InterruptDescriptorTable.h @@ -8,7 +8,7 @@ #ifndef INTERRUPTDESCRIPTORTABLE_H_ #define INTERRUPTDESCRIPTORTABLE_H_ -#include "../Global.h" +#include "Global.h" /** * structure used by the cpu to handler interrupts diff --git a/src/interrupts/InterruptHandler.cpp b/src/interrupts/InterruptHandler.cpp index f5eb52eed..e7958ece3 100644 --- a/src/interrupts/InterruptHandler.cpp +++ b/src/interrupts/InterruptHandler.cpp @@ -5,11 +5,11 @@ * Author: garrett */ -#include "InterruptHandler.h" -#include "../Kernel.h" -#include "../drivers/Keyboard.h" -#include "../drivers/TTY/Console.h" -#include "../drivers/ProgrammableInterruptController.h" +#include "interrupts/InterruptHandler.h" +#include "Kernel.h" +#include "drivers/Keyboard.h" +#include "drivers/TTY/Console.h" +#include "drivers/ProgrammableInterruptController.h" #if defined(__cplusplus) extern "C" {/* Use C linkage for kernel_main. */ #endif diff --git a/src/interrupts/InterruptHandler.h b/src/interrupts/InterruptHandler.h index a4c5d9cf7..5768021f6 100755 --- a/src/interrupts/InterruptHandler.h +++ b/src/interrupts/InterruptHandler.h @@ -8,7 +8,7 @@ #ifndef INTERRUPTHANDLER_H_ #define INTERRUPTHANDLER_H_ -#include "../Global.h" +#include "Global.h" //#include "../drivers/Keyboard.h" #endif /* INTERRUPTHANDLER_H_ */ diff --git a/src/memory/Mem.cpp b/src/memory/Mem.cpp index 56617271b..f80f0f7b4 100644 --- a/src/memory/Mem.cpp +++ b/src/memory/Mem.cpp @@ -5,8 +5,8 @@ * Author: garrett */ -#include "Mem.h" -#include "structures/PageTable.h" +#include "memory/Mem.h" +#include "memory/structures/PageTable.h" MultibootMemoryMap memMap[256]; /** * read the multiboot mem map diff --git a/src/memory/Mem.h b/src/memory/Mem.h index 3c6c64631..a77fd8dc4 100644 --- a/src/memory/Mem.h +++ b/src/memory/Mem.h @@ -8,9 +8,9 @@ #ifndef MEM_H_ #define MEM_H_ -#include "../Global.h" -#include "../Kernel.h" -#include "../multiboot_spec/Multiboot.h" +#include "Global.h" +#include "Kernel.h" +#include "multiboot_spec/Multiboot.h" struct MultibootMemoryMap{ diff --git a/src/memory/alloc/Malloc.c b/src/memory/alloc/Malloc.c index f8e632f0d..8245b397b 100644 --- a/src/memory/alloc/Malloc.c +++ b/src/memory/alloc/Malloc.c @@ -5,10 +5,10 @@ * Author: garrett */ -#include "Malloc.h" -#include "../../Kernel.h" -#include "../structures/PageTable.h" -#include "PageFrameAllocator.h" +#include "memory/alloc/Malloc.h" +#include "Kernel.h" +#include "memory/structures/PageTable.h" +#include "memory/alloc/PageFrameAllocator.h" /** * top of the paged in mem diff --git a/src/memory/alloc/Malloc.h b/src/memory/alloc/Malloc.h index a5bdba806..20d2d0ca8 100644 --- a/src/memory/alloc/Malloc.h +++ b/src/memory/alloc/Malloc.h @@ -8,7 +8,7 @@ #ifndef MALLOC_H_ #define MALLOC_H_ -#include "../../Global.h" +#include "Global.h" /** * top of the paged in mem diff --git a/src/memory/alloc/New.cpp b/src/memory/alloc/New.cpp index ff160e1e3..dfc7f7014 100644 --- a/src/memory/alloc/New.cpp +++ b/src/memory/alloc/New.cpp @@ -5,7 +5,7 @@ * Author: garrett */ -#include "New.h" +#include "memory/alloc/New.h" //TODO fix this file diff --git a/src/memory/alloc/New.h b/src/memory/alloc/New.h index ecc10876f..f776d8689 100644 --- a/src/memory/alloc/New.h +++ b/src/memory/alloc/New.h @@ -8,7 +8,7 @@ #ifndef NEW_H_ #define NEW_H_ -#include "../../Global.h" +#include "Global.h" void * operator new(size_t size); void operator delete(void * p); diff --git a/src/memory/alloc/PageFrameAllocator.cpp b/src/memory/alloc/PageFrameAllocator.cpp index 04d9022d2..9f3e9a5d0 100755 --- a/src/memory/alloc/PageFrameAllocator.cpp +++ b/src/memory/alloc/PageFrameAllocator.cpp @@ -4,9 +4,9 @@ * Created on: Apr 29, 2017 * Author: garrett */ -#include "PageFrameAllocator.h" -#include "../Mem.h" -#include "../structures/PageTable.h" +#include "memory/alloc/PageFrameAllocator.h" +#include "memory/Mem.h" +#include "memory/structures/PageTable.h" PageFrameAllocator::PageFrameAllocator( ) { // TODO Auto-generated constructor stub diff --git a/src/memory/alloc/PageFrameAllocator.h b/src/memory/alloc/PageFrameAllocator.h index 86e449294..ab5985662 100755 --- a/src/memory/alloc/PageFrameAllocator.h +++ b/src/memory/alloc/PageFrameAllocator.h @@ -8,7 +8,7 @@ #ifndef PAGEFRAMEALLOCATOR_H_ #define PAGEFRAMEALLOCATOR_H_ -#include "../../Global.h" +#include "Global.h" //#include "../../kernel.h" //#include "../structures/PageTable.h" diff --git a/src/memory/structures/GlobalDescriptorTable.cpp b/src/memory/structures/GlobalDescriptorTable.cpp index 35715c66c..03ddec58c 100755 --- a/src/memory/structures/GlobalDescriptorTable.cpp +++ b/src/memory/structures/GlobalDescriptorTable.cpp @@ -5,8 +5,8 @@ * Author: garrett */ -#include "GlobalDescriptorTable.h" -#include "../../drivers/TTY/Console.h" +#include "memory/structures/GlobalDescriptorTable.h" +#include "drivers/TTY/Console.h" //this code nver runs, should be replaced with the stuff in ::build() when we get start files and shit GlobalDescriptorTable::GlobalDescriptorTable( ) { diff --git a/src/memory/structures/GlobalDescriptorTable.h b/src/memory/structures/GlobalDescriptorTable.h index b0a53242c..8b0760d8b 100755 --- a/src/memory/structures/GlobalDescriptorTable.h +++ b/src/memory/structures/GlobalDescriptorTable.h @@ -8,7 +8,7 @@ #ifndef GLOBALDESCRIPTORTABLE_H_ #define GLOBALDESCRIPTORTABLE_H_ //#include "../../drivers/Console.h" -#include "../../Global.h" +#include "Global.h" diff --git a/src/memory/structures/PageTable.cpp b/src/memory/structures/PageTable.cpp index c974dfe24..e26e92830 100755 --- a/src/memory/structures/PageTable.cpp +++ b/src/memory/structures/PageTable.cpp @@ -5,7 +5,7 @@ * Author: garrett */ -#include "PageTable.h" +#include "memory/structures/PageTable.h" PageTable::PageTable( ) { } diff --git a/src/memory/structures/PageTable.h b/src/memory/structures/PageTable.h index c27944f38..30415c028 100755 --- a/src/memory/structures/PageTable.h +++ b/src/memory/structures/PageTable.h @@ -8,7 +8,7 @@ #ifndef PAGETABLE_H_ #define PAGETABLE_H_ -#include"../../Global.h" +#include"Global.h" struct PageDirEntry { char present :1; diff --git a/src/multiboot_spec/multiboot.h b/src/multiboot_spec/Multiboot.h similarity index 100% rename from src/multiboot_spec/multiboot.h rename to src/multiboot_spec/Multiboot.h diff --git a/src/Utils/Linked_List/LinkedList.h b/src/utils/linked_list/LinkedList.h similarity index 91% rename from src/Utils/Linked_List/LinkedList.h rename to src/utils/linked_list/LinkedList.h index 7951b0b1d..0f5596084 100644 --- a/src/Utils/Linked_List/LinkedList.h +++ b/src/utils/linked_list/LinkedList.h @@ -8,8 +8,8 @@ #ifndef SRC_UTILS_LINKEDLIST_H_ #define SRC_UTILS_LINKEDLIST_H_ -#include "../../Global.h" -#include "../linked_list/LinkedListNode.h" +#include "Global.h" +#include "utils/linked_list/LinkedListNode.h" template class LinkedList { diff --git a/src/Utils/Linked_List/LinkedListNode.h b/src/utils/linked_list/LinkedListNode.h similarity index 100% rename from src/Utils/Linked_List/LinkedListNode.h rename to src/utils/linked_list/LinkedListNode.h diff --git a/src/Utils/Linked_List/makefile b/src/utils/linked_list/makefile similarity index 100% rename from src/Utils/Linked_List/makefile rename to src/utils/linked_list/makefile diff --git a/src/Utils/makefile b/src/utils/makefile similarity index 100% rename from src/Utils/makefile rename to src/utils/makefile diff --git a/src/utils/printf/Printf.cpp b/src/utils/printf/Printf.cpp index dde4be360..51fd926d0 100644 --- a/src/utils/printf/Printf.cpp +++ b/src/utils/printf/Printf.cpp @@ -8,8 +8,8 @@ /* stdarg.h is for variadics */ #include -#include "../../drivers/TTY/Console.h" -#include "../printf/printf.h" +#include "drivers/TTY/Console.h" +#include "utils/printf/Printf.h" /** * A simple printf implementation * @param format string diff --git a/src/Utils/printf/printf.h b/src/utils/printf/Printf.h similarity index 100% rename from src/Utils/printf/printf.h rename to src/utils/printf/Printf.h diff --git a/src/Utils/printf/makefile b/src/utils/printf/makefile similarity index 100% rename from src/Utils/printf/makefile rename to src/utils/printf/makefile From 69ecd11cb21e76f5a9ec46848f273e4b7c38e376 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 12 Sep 2017 13:09:58 -0500 Subject: [PATCH 005/171] fixed stuff from changes in refactor --- src/drivers/PCI/USB/HostController/HostController.h | 2 ++ src/drivers/PCI/USB/HostController/OHCI.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/drivers/PCI/USB/HostController/HostController.h b/src/drivers/PCI/USB/HostController/HostController.h index bd9d63eed..f1ac2c9d7 100644 --- a/src/drivers/PCI/USB/HostController/HostController.h +++ b/src/drivers/PCI/USB/HostController/HostController.h @@ -8,6 +8,8 @@ #ifndef SRC_DRIVERS_PCI_USB_HOSTCONTROLLER_HOSTCONTROLLER_H_ #define SRC_DRIVERS_PCI_USB_HOSTCONTROLLER_HOSTCONTROLLER_H_ +#include "Global.h" + class HostController { protected: void* _BAR0; diff --git a/src/drivers/PCI/USB/HostController/OHCI.h b/src/drivers/PCI/USB/HostController/OHCI.h index ce675d592..d481857d5 100644 --- a/src/drivers/PCI/USB/HostController/OHCI.h +++ b/src/drivers/PCI/USB/HostController/OHCI.h @@ -8,7 +8,7 @@ #ifndef SRC_DRIVERS_PCI_USB_HOSTCONTROLLER_OHCI_H_ #define SRC_DRIVERS_PCI_USB_HOSTCONTROLLER_OHCI_H_ -#include "../../../../global.h" +#include "Global.h" #include "HostController.h" class OHCI: public HostController { From a33206fc5210fec757d56beb217ea44a618e63d9 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Wed, 13 Sep 2017 13:28:00 -0500 Subject: [PATCH 006/171] removed unneeded files --- src/drivers/PCI/USB/USBController.cpp | 15 --------------- src/drivers/PCI/USB/USBController.h | 18 ------------------ src/drivers/PCI/USB/makefile | 2 +- 3 files changed, 1 insertion(+), 34 deletions(-) delete mode 100644 src/drivers/PCI/USB/USBController.cpp delete mode 100644 src/drivers/PCI/USB/USBController.h diff --git a/src/drivers/PCI/USB/USBController.cpp b/src/drivers/PCI/USB/USBController.cpp deleted file mode 100644 index 9f0c55fa1..000000000 --- a/src/drivers/PCI/USB/USBController.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/* - * USBController.cpp - * - * Created on: Jul 12, 2017 - * Author: garrett - */ - -#include "drivers/PCI/USB/USBController.h" - -USBController::USBController( ) { - // TODO Auto-generated constructor stub - -} - - diff --git a/src/drivers/PCI/USB/USBController.h b/src/drivers/PCI/USB/USBController.h deleted file mode 100644 index e0bd6873e..000000000 --- a/src/drivers/PCI/USB/USBController.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * USBController.h - * - * Created on: Jul 12, 2017 - * Author: garrett - */ - -#ifndef USBCONTROLLER_H_ -#define USBCONTROLLER_H_ - -#include "Global.h" - -class USBController { - public: - USBController( ); -}; - -#endif /* USBCONTROLLER_H_ */ diff --git a/src/drivers/PCI/USB/makefile b/src/drivers/PCI/USB/makefile index 73adc61d3..d29e3c709 100644 --- a/src/drivers/PCI/USB/makefile +++ b/src/drivers/PCI/USB/makefile @@ -1,4 +1,4 @@ SUBDIRS = HostController -OBS = USB.o USBController.o +OBS = USB.o include ../../../../makefile.inc \ No newline at end of file From 47e9e1a6ba47833e2b05eb3da17c4a10f3d4ce09 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Thu, 21 Sep 2017 20:07:41 -0500 Subject: [PATCH 007/171] better link flags in makefile --- .settings/language.settings.xml | 16 ++++++++-------- makefile | 2 +- makefile.inc | 1 + 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml index d896b5737..3bd2729cb 100755 --- a/.settings/language.settings.xml +++ b/.settings/language.settings.xml @@ -5,7 +5,7 @@ - + @@ -16,7 +16,7 @@ - + @@ -27,7 +27,7 @@ - + @@ -38,7 +38,7 @@ - + @@ -49,7 +49,7 @@ - + @@ -60,7 +60,7 @@ - + @@ -71,7 +71,7 @@ - + @@ -82,7 +82,7 @@ - + diff --git a/makefile b/makefile index fae5c1fbe..6783231be 100644 --- a/makefile +++ b/makefile @@ -5,7 +5,7 @@ SUBDIRS = src include makefile.inc kernel.bin: $(SUBDIRS) - @$(GCC) -T $(OS_CPP)/linker.ld -o $(BUILD_TO) -ffreestanding -O2 -fno-rtti -fno-exceptions -nostartfiles -nostdlib $(OBJ_DIR)/*.o -lgcc + @$(GCC) -T $(OS_CPP)/linker.ld -o $(BUILD_TO) $(LINK_FLAGS) $(OBJ_DIR)/*.o -lgcc @sync clean: diff --git a/makefile.inc b/makefile.inc index 984f162ec..5914506e6 100644 --- a/makefile.inc +++ b/makefile.inc @@ -5,6 +5,7 @@ OS_CPP = /home/garrett/workspace/ExOS BUILD_TO = /run/media/garrett/EXOS/boot/kernel.bin CFLAGS = -c -ffreestanding -O2 -Wall -Wextra -fno-rtti -fno-exceptions -std=gnu++14 -I$(OS_CPP)/src OBJ_DIR = $(OS_CPP)/build +LINK_FLAGS = -ffreestanding -O2 -fno-rtti -fno-exceptions -nostartfiles -nostdlib %.o: %.c @ $(GPP) $(CFLAGS) $^ -o $(OBJ_DIR)/$@ From 078f3e8b7a4537a8e08f971a37440946ee0dce67 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Thu, 21 Sep 2017 20:38:59 -0500 Subject: [PATCH 008/171] Update README.MD --- README.MD | 68 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/README.MD b/README.MD index 099d45686..d4e1a5947 100755 --- a/README.MD +++ b/README.MD @@ -2,7 +2,7 @@ ExOS extends the [MIT exokernel](https://pdos.csail.mit.edu/archive/exo/) by removing the necessity to relink. Removing this process will allow consumers with no advanced computer knowledge better access to the OS. To achive this, the executable is scanned to identify system calls. Once they are identified, the native OS system calls are replaced with the appropriate ExOS userland system calls (from the LibOS). This replacement process is known as "live relinking". -***Before Working on ExOS, you should have a strong knoledge of the MIT Exokernel.*** +***Before Working on ExOS, you should have a strong knowledge of the MIT Exokernel.*** ## Goals @@ -13,32 +13,50 @@ ExOS extends the [MIT exokernel](https://pdos.csail.mit.edu/archive/exo/) by rem * Mac OS X * Live relinking to allow unmodified programs to be run -## Current Status +## Short term work +* Garrett + - [ ] Read USB spec + - [ ] USB abstract class + - [ ] OHCI driver + - [ ] UHCI driver + - [ ] EHCI driver + - [ ] XHCI driver + +* Oskari + - [ ] Floppy drive driver + +* Jacob + - [ ] Fixing PCI enumeration bug -I'm working with a friend on the PCI stuff. It is currently bugged and scanning returns no devices. I'm reading about the USB protocol and figuring out how I'm going to impliment it in the kernel. -### What's Left +* Ben + - [ ] Fat12 file system driver + +## Long term work +* Load files from floppy drives +* Some basic file systems support +* libC + * probably from NewLib +* Decide on a format for the libOS +* live relinking or something +* Linux libOS +* Windows libOS + * Possibly based on [ReactOS](https://www.reactos.org/) +* Mac OS X libOS -* ~~Bus enumeration~~ -* Device scanning (it may not work. atleast my test code found 0 devices. this needs to be worked on) -* ~~PCI Config space reading~~ (i can read the important one, header 0 for standard devices. could extend to more) - -## Next Steps - -* libc (maybe later) (newlib is hard) -* libc++ (maybe later) (needs libc and an os toolchain) -* PCI support (~~waiting for libc(++)~~) (I dont need those so were back to this) -* primitive USB support -* floppy support -* Loading and running programs from disk -* SATA HDD support -* IDE HDD support -* LibOS format -* Live relinking -* Linux LibOS -* Multitasking -* Windows LibOS - * Possibly based on [ReactOS's](https://www.reactos.org/) code -* Mac OS X LibOS +## Major systems to support +- [ ] PCI +- [ ] PCI Express +- [ ] USB +- [ ] Text Graphics +- [ ] Regular Graphics +- [ ] Sound +- [ ] Ethernet +- [ ] WIFi +- [ ] SATA +- [ ] IDE +- [ ] SCSI (maybe probably) +- [ ] SAS +- [ ] M.2 ## Building From ca693386c9ab35d41db26cef15b743d7dce912fa Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sat, 23 Sep 2017 17:14:17 -0500 Subject: [PATCH 009/171] Update README.MD --- README.MD | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.MD b/README.MD index d4e1a5947..1c2973451 100755 --- a/README.MD +++ b/README.MD @@ -58,6 +58,15 @@ ExOS extends the [MIT exokernel](https://pdos.csail.mit.edu/archive/exo/) by rem - [ ] SAS - [ ] M.2 +## Helping out + +### contacting us +* [slack](https://join.slack.com/t/exos-dev/shared_invite/enQtMjI2OTE2NjYzOTU4LTJhZTIyOTNkYmY2MjcxN2RjZTUzZjhkYTAzZTNlOThkODZkZmE5ODI3ODA0MjBlNDY3Mjg3OWNjODQ0ZGM3NDU) +* Email + * Garrett: exos@garrettbattaglia.info + * Oskari: Coming soon + + ## Building ### Precompilation steps From 7f071108ddf81e43eca89d60b5d0cffb8c75d25f Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sat, 23 Sep 2017 17:22:05 -0500 Subject: [PATCH 010/171] Update README.MD --- README.MD | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.MD b/README.MD index 1c2973451..2bbad60ce 100755 --- a/README.MD +++ b/README.MD @@ -60,12 +60,16 @@ ExOS extends the [MIT exokernel](https://pdos.csail.mit.edu/archive/exo/) by rem ## Helping out -### contacting us +### Contacting us * [slack](https://join.slack.com/t/exos-dev/shared_invite/enQtMjI2OTE2NjYzOTU4LTJhZTIyOTNkYmY2MjcxN2RjZTUzZjhkYTAzZTNlOThkODZkZmE5ODI3ODA0MjBlNDY3Mjg3OWNjODQ0ZGM3NDU) * Email * Garrett: exos@garrettbattaglia.info * Oskari: Coming soon +### But, what can ***I** do??? +The best thing you can do is write code. If you know a system like the ones listed above, write a driver for it. If there's a bug that catches your fancy try and patch it. + +If you can't code theres still stuff for you. If you can write our readme or wiki might intrest you. You can run this and test it out. If you have an issue open a bug. ## Building From fe1c818fa40dcbe3f3fa46df611ecf124a0e5412 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sat, 23 Sep 2017 17:22:31 -0500 Subject: [PATCH 011/171] Update README.MD --- README.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.MD b/README.MD index 2bbad60ce..5f9d3eb71 100755 --- a/README.MD +++ b/README.MD @@ -66,7 +66,7 @@ ExOS extends the [MIT exokernel](https://pdos.csail.mit.edu/archive/exo/) by rem * Garrett: exos@garrettbattaglia.info * Oskari: Coming soon -### But, what can ***I** do??? +### But, what can ***I*** do??? The best thing you can do is write code. If you know a system like the ones listed above, write a driver for it. If there's a bug that catches your fancy try and patch it. If you can't code theres still stuff for you. If you can write our readme or wiki might intrest you. You can run this and test it out. If you have an issue open a bug. From 874b9d9e15e81bbd4d0c34a3129ffee336a6af19 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Fri, 13 Oct 2017 10:06:09 -0500 Subject: [PATCH 012/171] Update README.MD --- README.MD | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.MD b/README.MD index 5f9d3eb71..77670a523 100755 --- a/README.MD +++ b/README.MD @@ -15,7 +15,7 @@ ExOS extends the [MIT exokernel](https://pdos.csail.mit.edu/archive/exo/) by rem ## Short term work * Garrett - - [ ] Read USB spec + - [ ] Read USB spec - still going, its long - [ ] USB abstract class - [ ] OHCI driver - [ ] UHCI driver @@ -26,7 +26,8 @@ ExOS extends the [MIT exokernel](https://pdos.csail.mit.edu/archive/exo/) by rem - [ ] Floppy drive driver * Jacob - - [ ] Fixing PCI enumeration bug + + - [ ] replace current PCI enum. strat. The new strat will get all devices at boot. When a device is requested it will be found in the list of devices. * Ben - [ ] Fat12 file system driver From 5367329ebb452a6d76a177c796483c23d52f7f6c Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 24 Oct 2017 21:06:59 -0500 Subject: [PATCH 013/171] Update README.MD --- README.MD | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.MD b/README.MD index 77670a523..d89c7a66c 100755 --- a/README.MD +++ b/README.MD @@ -85,7 +85,8 @@ If you can't code theres still stuff for you. If you can write our readme or wik * You can also use an emulator such as [Bochs](http://wiki.osdev.org/Bochs) or [QEMU](http://wiki.osdev.org/Qemu) to boot from a disk image. * If you're contributing ***please test on real hardware*** not just an emulator. 3. Set up a ***multiboot compliant*** bootloader - * I'm using [grub legacy](http://wiki.osdev.org/GRUB_Legacy) as my bootloader but you can use whatever as long as it's ***multiboot compliant***. + * I'm using [grub legacy](http://wiki.osdev.org/GRUB_Legacy) as my bootloader but you can use whatever as long as it's ***multiboot compliant***. + * I'm not 100% sure that all of them work the more i look into it. I will try grub and see. 4. Test the bootloader installation * Just boot to the bootloader's menu screen to make sure it works. 5. Configure the makefile (makefile.inc) From 8b023f398b81fff93d82988f6d867814a1da9183 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 24 Oct 2017 21:08:34 -0500 Subject: [PATCH 014/171] Update CODE_OF_CONDUCT.md --- CODE_OF_CONDUCT.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index c74ca6104..83e24e8e9 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -13,6 +13,7 @@ Examples of behavior that contributes to creating a positive environment include * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members +***Note that mild NSFW language is allowed*** Examples of unacceptable behavior by participants include: From c13216a51dc0b9bf4dc679568ab8d8cd679c4c4b Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 24 Oct 2017 21:09:33 -0500 Subject: [PATCH 015/171] Update CODE_OF_CONDUCT.md --- CODE_OF_CONDUCT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index c74ca6104..b0fde9b9a 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -34,7 +34,7 @@ This Code of Conduct applies both within project spaces and in public spaces whe ## Enforcement -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at garrett@garrettbattaglia.info. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at exos@garrettbattaglia.info. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. From 8593b4ce23e6cc487d3d0ef9fa00684083ffcaba Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 16 Jan 2018 11:10:24 -0600 Subject: [PATCH 016/171] basic structure of usb poll --- makefile.inc | 2 +- .../PCI/USB/HostController/HostController.cpp | 8 ++++++++ .../PCI/USB/HostController/HostController.h | 3 ++- src/drivers/PCI/USB/USBEvent.cpp | 17 +++++++++++++++++ src/drivers/PCI/USB/USBEvent.h | 17 +++++++++++++++++ src/drivers/PCI/USB/makefile | 2 +- 6 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 src/drivers/PCI/USB/USBEvent.cpp create mode 100644 src/drivers/PCI/USB/USBEvent.h diff --git a/makefile.inc b/makefile.inc index 5914506e6..9220cb733 100644 --- a/makefile.inc +++ b/makefile.inc @@ -2,7 +2,7 @@ AS = i686-elf-as GPP = i686-elf-g++ GCC = i686-elf-gcc OS_CPP = /home/garrett/workspace/ExOS -BUILD_TO = /run/media/garrett/EXOS/boot/kernel.bin +BUILD_TO = /run/media/garrett/disk/boot/kernel.bin CFLAGS = -c -ffreestanding -O2 -Wall -Wextra -fno-rtti -fno-exceptions -std=gnu++14 -I$(OS_CPP)/src OBJ_DIR = $(OS_CPP)/build LINK_FLAGS = -ffreestanding -O2 -fno-rtti -fno-exceptions -nostartfiles -nostdlib diff --git a/src/drivers/PCI/USB/HostController/HostController.cpp b/src/drivers/PCI/USB/HostController/HostController.cpp index f98ec6434..7297e3c14 100644 --- a/src/drivers/PCI/USB/HostController/HostController.cpp +++ b/src/drivers/PCI/USB/HostController/HostController.cpp @@ -16,3 +16,11 @@ HostController::~HostController( ) { // TODO Auto-generated destructor stub } +USBEvent* HostController::poll(){ + //new usbevent array , default size = 5 + //for each host controller + //check each known hub for info + //for each known hub + //check each device for info + //retunr array +} diff --git a/src/drivers/PCI/USB/HostController/HostController.h b/src/drivers/PCI/USB/HostController/HostController.h index f1ac2c9d7..512bdd9af 100644 --- a/src/drivers/PCI/USB/HostController/HostController.h +++ b/src/drivers/PCI/USB/HostController/HostController.h @@ -9,7 +9,7 @@ #define SRC_DRIVERS_PCI_USB_HOSTCONTROLLER_HOSTCONTROLLER_H_ #include "Global.h" - +#include "drivers/PCI/USB/USBEvent.h" class HostController { protected: void* _BAR0; @@ -35,6 +35,7 @@ class HostController { _BAR4 = BAR4; } virtual ~HostController( ); + USBEvent* poll(); }; #endif /* SRC_DRIVERS_PCI_USB_HOSTCONTROLLER_HOSTCONTROLLER_H_ */ diff --git a/src/drivers/PCI/USB/USBEvent.cpp b/src/drivers/PCI/USB/USBEvent.cpp new file mode 100644 index 000000000..13aab57f6 --- /dev/null +++ b/src/drivers/PCI/USB/USBEvent.cpp @@ -0,0 +1,17 @@ +/* + * USBEvent.cpp + * + * Created on: Jan 16, 2018 + * Author: garrett + */ +#include "USBEvent.h" + +USBEvent::USBEvent( ) { + // TODO Auto-generated constructor stub + +} + +USBEvent::~USBEvent( ) { + // TODO Auto-generated destructor stub +} + diff --git a/src/drivers/PCI/USB/USBEvent.h b/src/drivers/PCI/USB/USBEvent.h new file mode 100644 index 000000000..836e52971 --- /dev/null +++ b/src/drivers/PCI/USB/USBEvent.h @@ -0,0 +1,17 @@ +/* + * USBEvent.h + * + * Created on: Jan 16, 2018 + * Author: garrett + */ + +#ifndef SRC_DRIVERS_PCI_USB_USBEVENT_H_ +#define SRC_DRIVERS_PCI_USB_USBEVENT_H_ + +class USBEvent { + public: + USBEvent( ); + virtual ~USBEvent( ); +}; + +#endif /* SRC_DRIVERS_PCI_USB_USBEVENT_H_ */ diff --git a/src/drivers/PCI/USB/makefile b/src/drivers/PCI/USB/makefile index d29e3c709..41d7f4e74 100644 --- a/src/drivers/PCI/USB/makefile +++ b/src/drivers/PCI/USB/makefile @@ -1,4 +1,4 @@ SUBDIRS = HostController -OBS = USB.o +OBS = USB.o USBEvent.o include ../../../../makefile.inc \ No newline at end of file From 741d40ac3fd20b78e3fe998e925cfa7297ea8804 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 16 Jan 2018 18:38:41 -0600 Subject: [PATCH 017/171] added to git ignore also starting fat12 driver --- .gitignore | 2 ++ src/drivers/filesys/fat/fat12/.keep | 0 2 files changed, 2 insertions(+) create mode 100644 src/drivers/filesys/fat/fat12/.keep diff --git a/.gitignore b/.gitignore index 62bd89bc3..da2047d31 100755 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ .~lock.* *.swp *.swo +.idea/ +cmake-build-debug/ diff --git a/src/drivers/filesys/fat/fat12/.keep b/src/drivers/filesys/fat/fat12/.keep new file mode 100644 index 000000000..e69de29bb From bcb52dbe48ffc354e8026578a46c2a4392800803 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 16 Jan 2018 19:19:13 -0600 Subject: [PATCH 018/171] FAT BIOS Parameter Block --- src/drivers/filesys/fat/FatStructs.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/drivers/filesys/fat/FatStructs.h diff --git a/src/drivers/filesys/fat/FatStructs.h b/src/drivers/filesys/fat/FatStructs.h new file mode 100644 index 000000000..d02f4ff0b --- /dev/null +++ b/src/drivers/filesys/fat/FatStructs.h @@ -0,0 +1,25 @@ +// +// Created by Garrett Battaglia on 1/16/18. +// + +#ifndef EXOS_FATSTRUCTS_H +#define EXOS_FATSTRUCTS_H + +struct FatBPB{ + uint8_t jmp[3]; + uint8_t oemIdent[8]; + uint16_t bytePerSec; + uint8_t secPerCluster; + uint16_t resSec; + uint8_t FATs; + uint16_t dirEntryCount; + uint16_t secCount; + uint8_t mediaType; + uint16_t secPerFAT; + uint16_t secPerTrack; + uint16_t heads; + uint32_t hiddenSec; + uint32_t largeSecCount; +}; + +#endif //EXOS_FATSTRUCTS_H From 66ff66e9c330f57894b4d1d0a0f4b789e06f01ac Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 16 Jan 2018 20:30:38 -0600 Subject: [PATCH 019/171] file open sig --- src/drivers/filesys/File.cpp | 5 +++++ src/drivers/filesys/File.h | 10 ++++++++++ src/drivers/filesys/fat/fat12/.keep | 0 src/drivers/filesys/fat/fat12/Fat12FS.cpp | 10 ++++++++++ src/drivers/filesys/fat/fat12/Fat12FS.h | 18 ++++++++++++++++++ src/drivers/filesys/fat/fat12/Fat12File.cpp | 5 +++++ src/drivers/filesys/fat/fat12/Fat12File.h | 14 ++++++++++++++ 7 files changed, 62 insertions(+) create mode 100644 src/drivers/filesys/File.cpp create mode 100644 src/drivers/filesys/File.h delete mode 100644 src/drivers/filesys/fat/fat12/.keep create mode 100644 src/drivers/filesys/fat/fat12/Fat12FS.cpp create mode 100644 src/drivers/filesys/fat/fat12/Fat12FS.h create mode 100644 src/drivers/filesys/fat/fat12/Fat12File.cpp create mode 100644 src/drivers/filesys/fat/fat12/Fat12File.h diff --git a/src/drivers/filesys/File.cpp b/src/drivers/filesys/File.cpp new file mode 100644 index 000000000..283ddcbf7 --- /dev/null +++ b/src/drivers/filesys/File.cpp @@ -0,0 +1,5 @@ +// +// Created by Garrett Battaglia on 1/16/18. +// + +#include "File.h" diff --git a/src/drivers/filesys/File.h b/src/drivers/filesys/File.h new file mode 100644 index 000000000..1519165f9 --- /dev/null +++ b/src/drivers/filesys/File.h @@ -0,0 +1,10 @@ +// +// Created by Garrett Battaglia on 1/16/18. +// + +#ifndef EXOS_FILE_H +#define EXOS_FILE_H +class File{ + +}; +#endif //EXOS_FILE_H diff --git a/src/drivers/filesys/fat/fat12/.keep b/src/drivers/filesys/fat/fat12/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.cpp b/src/drivers/filesys/fat/fat12/Fat12FS.cpp new file mode 100644 index 000000000..864b2a027 --- /dev/null +++ b/src/drivers/filesys/fat/fat12/Fat12FS.cpp @@ -0,0 +1,10 @@ +// +// Created by Garrett Battaglia on 1/16/18. +// + +#include "Fat12FS.h" + +File* Fat12FS::open(char* path, int flags, int mode){ + Fat12File* ret = new Fat12File(); + return ret; +} \ No newline at end of file diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.h b/src/drivers/filesys/fat/fat12/Fat12FS.h new file mode 100644 index 000000000..cb49090e1 --- /dev/null +++ b/src/drivers/filesys/fat/fat12/Fat12FS.h @@ -0,0 +1,18 @@ +// +// Created by Garrett Battaglia on 1/16/18. +// + +#ifndef EXOS_FAT12_H +#define EXOS_FAT12_H + +#include "Fat12File.h" + +class Fat12FS{ + public: + //TODO void* -> filedesc* + File* open(char* path, int flags, int mode); + +}; + + +#endif //EXOS_FAT12_H diff --git a/src/drivers/filesys/fat/fat12/Fat12File.cpp b/src/drivers/filesys/fat/fat12/Fat12File.cpp new file mode 100644 index 000000000..bbdf2bc58 --- /dev/null +++ b/src/drivers/filesys/fat/fat12/Fat12File.cpp @@ -0,0 +1,5 @@ +// +// Created by Garrett Battaglia on 1/16/18. +// + +#include "Fat12File.h" diff --git a/src/drivers/filesys/fat/fat12/Fat12File.h b/src/drivers/filesys/fat/fat12/Fat12File.h new file mode 100644 index 000000000..5b7fd9181 --- /dev/null +++ b/src/drivers/filesys/fat/fat12/Fat12File.h @@ -0,0 +1,14 @@ +// +// Created by Garrett Battaglia on 1/16/18. +// + +#ifndef EXOS_FAT12FILE_H +#define EXOS_FAT12FILE_H + +#include "drivers/filesys/File.h" + +class Fat12File: public File{ + +}; + +#endif //EXOS_FAT12FILE_H From cff30398c41f9972af78aa1351083004f86d8d37 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 16 Jan 2018 20:35:17 -0600 Subject: [PATCH 020/171] makefile updates --- src/drivers/filesys/fat/fat12/makefile | 3 +++ src/drivers/filesys/makefile | 4 ++++ src/drivers/makefile | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 src/drivers/filesys/fat/fat12/makefile create mode 100644 src/drivers/filesys/makefile diff --git a/src/drivers/filesys/fat/fat12/makefile b/src/drivers/filesys/fat/fat12/makefile new file mode 100644 index 000000000..4ade4a8a4 --- /dev/null +++ b/src/drivers/filesys/fat/fat12/makefile @@ -0,0 +1,3 @@ +OBS = Fat12FS.o Fat12File.o + +include ../../../../makefile.inc diff --git a/src/drivers/filesys/makefile b/src/drivers/filesys/makefile new file mode 100644 index 000000000..3e97f4454 --- /dev/null +++ b/src/drivers/filesys/makefile @@ -0,0 +1,4 @@ +SUBDIRS = fat +OBS = File.o + +include ../../../makefile.inc diff --git a/src/drivers/makefile b/src/drivers/makefile index 0766b9328..cc4f78aa7 100644 --- a/src/drivers/makefile +++ b/src/drivers/makefile @@ -1,4 +1,4 @@ -SUBDIRS = PCI TTY +SUBDIRS = PCI TTY filesys OBS= Keyboard.o ProgrammableInterruptController.o include ../../makefile.inc From 357303f3cced09afd9143b1bfc35eace64e4ec2b Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 16 Jan 2018 20:38:38 -0600 Subject: [PATCH 021/171] forgot a level --- src/drivers/filesys/fat/makefile | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/drivers/filesys/fat/makefile diff --git a/src/drivers/filesys/fat/makefile b/src/drivers/filesys/fat/makefile new file mode 100644 index 000000000..fda571e12 --- /dev/null +++ b/src/drivers/filesys/fat/makefile @@ -0,0 +1,3 @@ +SUBDIRS = fat12 + +include ../../../makefile.inc From ca6e0f5a0923437dddca8df70e8f69ac2d8affdc Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 16 Jan 2018 20:40:13 -0600 Subject: [PATCH 022/171] fuck --- src/drivers/filesys/fat/makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/filesys/fat/makefile b/src/drivers/filesys/fat/makefile index fda571e12..e1caa33fe 100644 --- a/src/drivers/filesys/fat/makefile +++ b/src/drivers/filesys/fat/makefile @@ -1,3 +1,3 @@ SUBDIRS = fat12 -include ../../../makefile.inc +include ../../../../makefile.inc From 2dc3968f6e5d8fdce3f0528425c95efdb3a8c730 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 16 Jan 2018 20:41:11 -0600 Subject: [PATCH 023/171] makefiles are hard --- src/drivers/filesys/fat/fat12/makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/filesys/fat/fat12/makefile b/src/drivers/filesys/fat/fat12/makefile index 4ade4a8a4..4f7c32c94 100644 --- a/src/drivers/filesys/fat/fat12/makefile +++ b/src/drivers/filesys/fat/fat12/makefile @@ -1,3 +1,3 @@ OBS = Fat12FS.o Fat12File.o -include ../../../../makefile.inc +include ../../../../../makefile.inc From 9d369b167075c2978fbb6c1f1256038bf05f7ba3 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Wed, 17 Jan 2018 08:33:35 -0600 Subject: [PATCH 024/171] class vars that we probly need --- src/drivers/filesys/File.h | 6 +++++- src/drivers/filesys/fat/fat12/Fat12FS.cpp | 4 ++-- src/drivers/filesys/fat/fat12/Fat12FS.h | 6 ++++-- src/drivers/filesys/fat/fat12/Fat12File.cpp | 4 ++++ src/drivers/filesys/fat/fat12/Fat12File.h | 7 ++++++- 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/drivers/filesys/File.h b/src/drivers/filesys/File.h index 1519165f9..a378a45d7 100644 --- a/src/drivers/filesys/File.h +++ b/src/drivers/filesys/File.h @@ -5,6 +5,10 @@ #ifndef EXOS_FILE_H #define EXOS_FILE_H class File{ - + private: + //TODO void* -> process* + void* process; + public: + size_t read(char* buffer, size_t size) = 0; }; #endif //EXOS_FILE_H diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.cpp b/src/drivers/filesys/fat/fat12/Fat12FS.cpp index 864b2a027..ea117c7d4 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12FS.cpp @@ -4,7 +4,7 @@ #include "Fat12FS.h" -File* Fat12FS::open(char* path, int flags, int mode){ +Fat12File* Fat12FS::open(char* path, int flags, int mode){ Fat12File* ret = new Fat12File(); return ret; -} \ No newline at end of file +} diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.h b/src/drivers/filesys/fat/fat12/Fat12FS.h index cb49090e1..ea58a90d8 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.h +++ b/src/drivers/filesys/fat/fat12/Fat12FS.h @@ -6,11 +6,13 @@ #define EXOS_FAT12_H #include "Fat12File.h" +#include "drivers/filesys/fat/FatStructs.h" class Fat12FS{ + private: + FatBPB FSInfo; public: - //TODO void* -> filedesc* - File* open(char* path, int flags, int mode); + Fat12File* open(char* path, int flags, int mode); }; diff --git a/src/drivers/filesys/fat/fat12/Fat12File.cpp b/src/drivers/filesys/fat/fat12/Fat12File.cpp index bbdf2bc58..a7f81b2cb 100644 --- a/src/drivers/filesys/fat/fat12/Fat12File.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12File.cpp @@ -3,3 +3,7 @@ // #include "Fat12File.h" + +size_t Fat12File::read(char* buffer, size_t size){ +//TODO +} \ No newline at end of file diff --git a/src/drivers/filesys/fat/fat12/Fat12File.h b/src/drivers/filesys/fat/fat12/Fat12File.h index 5b7fd9181..6f0af3e63 100644 --- a/src/drivers/filesys/fat/fat12/Fat12File.h +++ b/src/drivers/filesys/fat/fat12/Fat12File.h @@ -6,9 +6,14 @@ #define EXOS_FAT12FILE_H #include "drivers/filesys/File.h" +#include "Fat12FS.h" class Fat12File: public File{ - + private: + size_t lastCluster; + Fat12FS device; + public: + size_t read(char* buffer, size_t size); }; #endif //EXOS_FAT12FILE_H From 59dd5ea246c95fff4a50540890f59f15557e5b42 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Wed, 17 Jan 2018 16:16:17 -0600 Subject: [PATCH 025/171] read from file note: after reading from disk, no code to read from disk yet --- src/drivers/filesys/fat/fat12/Fat12FS.cpp | 5 +++-- src/drivers/filesys/fat/fat12/Fat12FS.h | 11 +++++++--- src/drivers/filesys/fat/fat12/Fat12File.cpp | 23 +++++++++++++++++++-- src/drivers/filesys/fat/fat12/Fat12File.h | 11 ++++++++-- 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.cpp b/src/drivers/filesys/fat/fat12/Fat12FS.cpp index ea117c7d4..a41623520 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12FS.cpp @@ -4,7 +4,8 @@ #include "Fat12FS.h" -Fat12File* Fat12FS::open(char* path, int flags, int mode){ - Fat12File* ret = new Fat12File(); +Fat12File *Fat12FS::open(char *path, int flags, int mode) +{ + Fat12File *ret = new Fat12File(); return ret; } diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.h b/src/drivers/filesys/fat/fat12/Fat12FS.h index ea58a90d8..bcf13b3ba 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.h +++ b/src/drivers/filesys/fat/fat12/Fat12FS.h @@ -8,12 +8,17 @@ #include "Fat12File.h" #include "drivers/filesys/fat/FatStructs.h" -class Fat12FS{ +class Fat12FS +{ private: - FatBPB FSInfo; + FatBPB _FSInfo; public: - Fat12File* open(char* path, int flags, int mode); + Fat12File *open(char *path, int flags, int mode); + FatBPB *FSInfo() + { + return _FSInfo; + } }; diff --git a/src/drivers/filesys/fat/fat12/Fat12File.cpp b/src/drivers/filesys/fat/fat12/Fat12File.cpp index a7f81b2cb..f6a88ee93 100644 --- a/src/drivers/filesys/fat/fat12/Fat12File.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12File.cpp @@ -4,6 +4,25 @@ #include "Fat12File.h" -size_t Fat12File::read(char* buffer, size_t size){ -//TODO +size_t Fat12File::read(char *buffer, size_t size) +{ + size_t bytesRead = 0; + while (bytesRead < size) { + if (size < (_fileLocSize - _lastByteRead)) { + memcpy(buffer + bytesRead, _fileLoc + (_lastByteRead - _fileLocStartInFile), size); + bytesRead += size; + } else { + memcpy(buffer + bytesRead, _fileLoc + (_lastByteRead - _fileLocStartInFile), + _lastByteLoaded - _lastByteRead); + bytesRead += _lastByteLoaded - _lastByteRead; + if (readFromDisk()) { + //error + } + } + } +} + +bool readFromDisk() +{ + } \ No newline at end of file diff --git a/src/drivers/filesys/fat/fat12/Fat12File.h b/src/drivers/filesys/fat/fat12/Fat12File.h index 6f0af3e63..a904a71d9 100644 --- a/src/drivers/filesys/fat/fat12/Fat12File.h +++ b/src/drivers/filesys/fat/fat12/Fat12File.h @@ -10,10 +10,17 @@ class Fat12File: public File{ private: - size_t lastCluster; - Fat12FS device; + size_t _lastCluster; + Fat12FS _device; + uint32_t _lastByteRead; + uint32_t _lastByteLoaded; + void* _fileLoc; + size_t _fileLocSize; + uint32_t _fileLocStartInFile; public: size_t read(char* buffer, size_t size); + + bool readFromDisk(); }; #endif //EXOS_FAT12FILE_H From 0badad6e5eb4c10a0b0f0364fc74b5e71a32e52c Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Thu, 18 Jan 2018 11:35:55 -0600 Subject: [PATCH 026/171] read from disk --- src/drivers/filesys/fat/fat12/Fat12FS.cpp | 4 ++++ src/drivers/filesys/fat/fat12/Fat12FS.h | 1 + src/drivers/filesys/fat/fat12/Fat12File.cpp | 23 ++++++++++++++++++--- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.cpp b/src/drivers/filesys/fat/fat12/Fat12FS.cpp index a41623520..df935afa7 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12FS.cpp @@ -9,3 +9,7 @@ Fat12File *Fat12FS::open(char *path, int flags, int mode) Fat12File *ret = new Fat12File(); return ret; } + +bool Fat12FS::readCluster(uint16_t cluser, void* fileLoc, size_t fileLocSize){ + +} \ No newline at end of file diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.h b/src/drivers/filesys/fat/fat12/Fat12FS.h index bcf13b3ba..0156d9389 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.h +++ b/src/drivers/filesys/fat/fat12/Fat12FS.h @@ -19,6 +19,7 @@ class Fat12FS { return _FSInfo; } + bool readCluster(uint16_t cluser, void* fileLoc, size_t fileLocSize); }; diff --git a/src/drivers/filesys/fat/fat12/Fat12File.cpp b/src/drivers/filesys/fat/fat12/Fat12File.cpp index f6a88ee93..b8d2436a2 100644 --- a/src/drivers/filesys/fat/fat12/Fat12File.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12File.cpp @@ -15,14 +15,31 @@ size_t Fat12File::read(char *buffer, size_t size) memcpy(buffer + bytesRead, _fileLoc + (_lastByteRead - _fileLocStartInFile), _lastByteLoaded - _lastByteRead); bytesRead += _lastByteLoaded - _lastByteRead; - if (readFromDisk()) { - //error + if (!readFromDisk()) { + return bytesRead; } } } } +//TODO naming and types and general structure, taken from osdev wiki bool readFromDisk() { - + uint16_t firstFatSec = _device.FSInfo()->resSec; + unsigned char FAT_table[_device.FSInfo()->bytePerSec]; + unsigned int fat_offset = active_cluster + (active_cluster / 2);// multiply by 1.5 + unsigned int fat_sector = first_fat_sector + (fat_offset / bytePerSec); + unsigned int ent_offset = fat_offset % bytePerSec; + + unsigned short table_value = *(unsigned short*)&FAT_table[ent_offset]; + + if(active_cluster & 0x0001) + table_value = table_value >> 4; + else + table_value = table_value & 0x0FFF; + if (table_value >= 0xFF8){ + return false; + } else { + bool ret =_device.readCluster(table_value, _fileLoc, _fileLocSize); + } } \ No newline at end of file From 5a685ad487a28bff4b2ea842198816a3a735763c Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Thu, 18 Jan 2018 11:48:08 -0600 Subject: [PATCH 027/171] fixed some issues --- makefile.inc | 2 +- src/drivers/filesys/File.h | 6 ++++-- src/drivers/filesys/fat/fat12/Fat12FS.h | 11 +++++------ src/drivers/filesys/fat/fat12/Fat12File.cpp | 21 +++++++++++---------- src/drivers/filesys/fat/fat12/Fat12File.h | 4 +++- 5 files changed, 24 insertions(+), 20 deletions(-) diff --git a/makefile.inc b/makefile.inc index 984f162ec..b86af72cd 100644 --- a/makefile.inc +++ b/makefile.inc @@ -2,7 +2,7 @@ AS = i686-elf-as GPP = i686-elf-g++ GCC = i686-elf-gcc OS_CPP = /home/garrett/workspace/ExOS -BUILD_TO = /run/media/garrett/EXOS/boot/kernel.bin +BUILD_TO = /run/media/garrett/disk/boot/kernel.bin CFLAGS = -c -ffreestanding -O2 -Wall -Wextra -fno-rtti -fno-exceptions -std=gnu++14 -I$(OS_CPP)/src OBJ_DIR = $(OS_CPP)/build diff --git a/src/drivers/filesys/File.h b/src/drivers/filesys/File.h index a378a45d7..dd395ab04 100644 --- a/src/drivers/filesys/File.h +++ b/src/drivers/filesys/File.h @@ -4,11 +4,13 @@ #ifndef EXOS_FILE_H #define EXOS_FILE_H -class File{ +#include "Global.h" + +class File { private: //TODO void* -> process* void* process; public: - size_t read(char* buffer, size_t size) = 0; + virtual size_t read(char* buffer, size_t size) = 0; }; #endif //EXOS_FILE_H diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.h b/src/drivers/filesys/fat/fat12/Fat12FS.h index 0156d9389..c915539ae 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.h +++ b/src/drivers/filesys/fat/fat12/Fat12FS.h @@ -8,19 +8,18 @@ #include "Fat12File.h" #include "drivers/filesys/fat/FatStructs.h" -class Fat12FS -{ +class Fat12File; + +class Fat12FS { private: - FatBPB _FSInfo; + FatBPB* _FSInfo; public: Fat12File *open(char *path, int flags, int mode); - FatBPB *FSInfo() - { + FatBPB *FSInfo( ) { return _FSInfo; } bool readCluster(uint16_t cluser, void* fileLoc, size_t fileLocSize); }; - #endif //EXOS_FAT12_H diff --git a/src/drivers/filesys/fat/fat12/Fat12File.cpp b/src/drivers/filesys/fat/fat12/Fat12File.cpp index b8d2436a2..a8ff69f09 100644 --- a/src/drivers/filesys/fat/fat12/Fat12File.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12File.cpp @@ -3,6 +3,7 @@ // #include "Fat12File.h" +#include "memory/Mem.h" size_t Fat12File::read(char *buffer, size_t size) { @@ -12,7 +13,7 @@ size_t Fat12File::read(char *buffer, size_t size) memcpy(buffer + bytesRead, _fileLoc + (_lastByteRead - _fileLocStartInFile), size); bytesRead += size; } else { - memcpy(buffer + bytesRead, _fileLoc + (_lastByteRead - _fileLocStartInFile), + memcpy(buffer + bytesRead, _fileLoc + ((uint8_t*)_lastByteRead - (uint8_t*)_fileLocStartInFile), _lastByteLoaded - _lastByteRead); bytesRead += _lastByteLoaded - _lastByteRead; if (!readFromDisk()) { @@ -23,23 +24,23 @@ size_t Fat12File::read(char *buffer, size_t size) } //TODO naming and types and general structure, taken from osdev wiki -bool readFromDisk() +bool Fat12File::readFromDisk() { - uint16_t firstFatSec = _device.FSInfo()->resSec; - unsigned char FAT_table[_device.FSInfo()->bytePerSec]; - unsigned int fat_offset = active_cluster + (active_cluster / 2);// multiply by 1.5 - unsigned int fat_sector = first_fat_sector + (fat_offset / bytePerSec); - unsigned int ent_offset = fat_offset % bytePerSec; + uint16_t firstFatSec = _device->FSInfo()->resSec; + unsigned char FAT_table[_device->FSInfo()->bytePerSec]; + unsigned int fat_offset = _lastCluster + (_lastCluster / 2);// multiply by 1.5 + unsigned int fat_sector = firstFatSec + (fat_offset / _device->FSInfo()->bytePerSec); + unsigned int ent_offset = fat_offset % _device->FSInfo()->bytePerSec; unsigned short table_value = *(unsigned short*)&FAT_table[ent_offset]; - if(active_cluster & 0x0001) + if(_lastCluster & 0x0001) table_value = table_value >> 4; else table_value = table_value & 0x0FFF; if (table_value >= 0xFF8){ return false; } else { - bool ret =_device.readCluster(table_value, _fileLoc, _fileLocSize); + bool ret = _device->readCluster(table_value, _fileLoc, _fileLocSize); } -} \ No newline at end of file +} diff --git a/src/drivers/filesys/fat/fat12/Fat12File.h b/src/drivers/filesys/fat/fat12/Fat12File.h index a904a71d9..195a76ede 100644 --- a/src/drivers/filesys/fat/fat12/Fat12File.h +++ b/src/drivers/filesys/fat/fat12/Fat12File.h @@ -8,10 +8,12 @@ #include "drivers/filesys/File.h" #include "Fat12FS.h" +class Fat12FS; + class Fat12File: public File{ private: size_t _lastCluster; - Fat12FS _device; + Fat12FS* _device; uint32_t _lastByteRead; uint32_t _lastByteLoaded; void* _fileLoc; From 12edb6302483b3063458fad39de089e82bc9a361 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Thu, 18 Jan 2018 16:43:16 -0600 Subject: [PATCH 028/171] assert --- src/clib_misc/assert.c | 13 +++++++++++++ src/clib_misc/assert.h | 13 +++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 src/clib_misc/assert.c create mode 100644 src/clib_misc/assert.h diff --git a/src/clib_misc/assert.c b/src/clib_misc/assert.c new file mode 100644 index 000000000..b6fb98c1a --- /dev/null +++ b/src/clib_misc/assert.c @@ -0,0 +1,13 @@ +// +// Created by Garrett Battaglia on 1/18/18. +// + +#include "assert.h" + +extern "c"{ +void assert(uint8_t expression){ + if(!expression){ + //TODO kernel panic... + } +} +}; \ No newline at end of file diff --git a/src/clib_misc/assert.h b/src/clib_misc/assert.h new file mode 100644 index 000000000..e537785d6 --- /dev/null +++ b/src/clib_misc/assert.h @@ -0,0 +1,13 @@ +// +// Created by Garrett Battaglia on 1/18/18. +// + +#ifndef EXOS_ASSERT_H +#define EXOS_ASSERT_H + +extern "c"{ +void assert(uint8_t expression); +}; + + +#endif //EXOS_ASSERT_H From 60140bb41551595d41fcb4c86c67608c9d45b301 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Thu, 18 Jan 2018 16:49:30 -0600 Subject: [PATCH 029/171] file reading loop to fill buffer --- src/drivers/filesys/fat/fat12/Fat12FS.cpp | 3 ++- src/drivers/filesys/fat/fat12/Fat12File.cpp | 27 ++++++++++++--------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.cpp b/src/drivers/filesys/fat/fat12/Fat12FS.cpp index df935afa7..7ca2dd77f 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12FS.cpp @@ -11,5 +11,6 @@ Fat12File *Fat12FS::open(char *path, int flags, int mode) } bool Fat12FS::readCluster(uint16_t cluser, void* fileLoc, size_t fileLocSize){ - + assert(fileLocSize >= (_FSInfo->secPerCluster * _FSInfo->bytePerSec)); + //TODO read from disk } \ No newline at end of file diff --git a/src/drivers/filesys/fat/fat12/Fat12File.cpp b/src/drivers/filesys/fat/fat12/Fat12File.cpp index a8ff69f09..0e77de3a0 100644 --- a/src/drivers/filesys/fat/fat12/Fat12File.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12File.cpp @@ -28,19 +28,22 @@ bool Fat12File::readFromDisk() { uint16_t firstFatSec = _device->FSInfo()->resSec; unsigned char FAT_table[_device->FSInfo()->bytePerSec]; - unsigned int fat_offset = _lastCluster + (_lastCluster / 2);// multiply by 1.5 - unsigned int fat_sector = firstFatSec + (fat_offset / _device->FSInfo()->bytePerSec); - unsigned int ent_offset = fat_offset % _device->FSInfo()->bytePerSec; + while(read < _fileLocSize && _fileLocSize-read >= (_FSInfo->secPerCluster * _FSInfo->bytePerSec)) { + unsigned int fat_offset = _lastCluster + (_lastCluster / 2);// multiply by 1.5 + unsigned int fat_sector = firstFatSec + (fat_offset / _device->FSInfo()->bytePerSec); + unsigned int ent_offset = fat_offset % _device->FSInfo()->bytePerSec; - unsigned short table_value = *(unsigned short*)&FAT_table[ent_offset]; + unsigned short table_value = *(unsigned short *) &FAT_table[ent_offset]; - if(_lastCluster & 0x0001) - table_value = table_value >> 4; - else - table_value = table_value & 0x0FFF; - if (table_value >= 0xFF8){ - return false; - } else { - bool ret = _device->readCluster(table_value, _fileLoc, _fileLocSize); + if (_lastCluster & 0x0001) + table_value = table_value >> 4; + else + table_value = table_value & 0x0FFF; + if (table_value >= 0xFF8) { + return false; + } else { + bool ret = _device->readCluster(table_value, _fileLoc + read, _fileLocSize - read); + read += (_device.FSInfo()->secPerCluster * _device * FSInfo()->bytePerSec); + } } } From 227e771bdd5a2422aabe2c72522fe2973698f8db Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Fri, 19 Jan 2018 13:40:10 -0600 Subject: [PATCH 030/171] part of the fix for issue #38 --- src/drivers/filesys/fat/fat12/Fat12File.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/drivers/filesys/fat/fat12/Fat12File.cpp b/src/drivers/filesys/fat/fat12/Fat12File.cpp index 0e77de3a0..6d5c0f749 100644 --- a/src/drivers/filesys/fat/fat12/Fat12File.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12File.cpp @@ -40,10 +40,15 @@ bool Fat12File::readFromDisk() else table_value = table_value & 0x0FFF; if (table_value >= 0xFF8) { - return false; + free(_fileLoc + read); + return true; } else { bool ret = _device->readCluster(table_value, _fileLoc + read, _fileLocSize - read); + if (!ret){ + return false; + } read += (_device.FSInfo()->secPerCluster * _device * FSInfo()->bytePerSec); } } + return true; } From fd14e25499bed2bebaffe81ca3968a739ef8ef23 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Fri, 19 Jan 2018 19:48:22 -0600 Subject: [PATCH 031/171] read from fat12FS --- src/drivers/filesys/fat/fat12/Fat12FS.cpp | 10 +++++++++- src/drivers/filesys/fat/fat12/Fat12FS.h | 2 ++ src/drivers/filesys/fat/fat12/Fat12File.cpp | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.cpp b/src/drivers/filesys/fat/fat12/Fat12FS.cpp index 7ca2dd77f..dea04f369 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12FS.cpp @@ -10,7 +10,15 @@ Fat12File *Fat12FS::open(char *path, int flags, int mode) return ret; } +//todo names, var sizes, structure taken from osdev wiki bool Fat12FS::readCluster(uint16_t cluser, void* fileLoc, size_t fileLocSize){ assert(fileLocSize >= (_FSInfo->secPerCluster * _FSInfo->bytePerSec)); - //TODO read from disk + uint32_t fat_size = (_FSInfo->secCount != 0)? _FSInfo->secCount : _FSInfo->largeSecCount; + uint32_t root_dir_sectors = ((_FSInfo->dirEntryCount * 32) + (_FSInfo->bytePerSec - 1)) / _FSInfo->bytePerSec; + uint32_t first_data_sector = _FSInfo->resSec + (_FSInfo->FATs * fat_size) + root_dir_sectors; + uint32_t first_sector_of_cluster = ((cluster - 2) * _FSInfo->secPerCluster) + first_data_sector; + for (uint32_t i =0; i < _FSInfo->secPerCluster; i++){ + _device->read(first_sector_of_cluster); + first_sector_of_cluster++; + } } \ No newline at end of file diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.h b/src/drivers/filesys/fat/fat12/Fat12FS.h index c915539ae..cb148cc9b 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.h +++ b/src/drivers/filesys/fat/fat12/Fat12FS.h @@ -13,6 +13,8 @@ class Fat12File; class Fat12FS { private: FatBPB* _FSInfo; + //TODO replace with device. + void* _device; public: Fat12File *open(char *path, int flags, int mode); diff --git a/src/drivers/filesys/fat/fat12/Fat12File.cpp b/src/drivers/filesys/fat/fat12/Fat12File.cpp index 6d5c0f749..25e27552e 100644 --- a/src/drivers/filesys/fat/fat12/Fat12File.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12File.cpp @@ -40,6 +40,7 @@ bool Fat12File::readFromDisk() else table_value = table_value & 0x0FFF; if (table_value >= 0xFF8) { + //TODO make sure this frees everything free(_fileLoc + read); return true; } else { From ae8f16d983f77c1bc05c4fd82596525f496cdc41 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Fri, 19 Jan 2018 19:54:15 -0600 Subject: [PATCH 032/171] fixed more of issue #38 --- src/drivers/filesys/fat/fat12/Fat12File.cpp | 3 +++ src/drivers/filesys/fat/fat12/Fat12File.h | 1 + 2 files changed, 4 insertions(+) diff --git a/src/drivers/filesys/fat/fat12/Fat12File.cpp b/src/drivers/filesys/fat/fat12/Fat12File.cpp index 25e27552e..7336f0d1f 100644 --- a/src/drivers/filesys/fat/fat12/Fat12File.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12File.cpp @@ -42,6 +42,7 @@ bool Fat12File::readFromDisk() if (table_value >= 0xFF8) { //TODO make sure this frees everything free(_fileLoc + read); + _fileLocSize=read; return true; } else { bool ret = _device->readCluster(table_value, _fileLoc + read, _fileLocSize - read); @@ -49,7 +50,9 @@ bool Fat12File::readFromDisk() return false; } read += (_device.FSInfo()->secPerCluster * _device * FSInfo()->bytePerSec); + _lastCluster = table_value; } } + _lastByteLoaded += read; return true; } diff --git a/src/drivers/filesys/fat/fat12/Fat12File.h b/src/drivers/filesys/fat/fat12/Fat12File.h index 195a76ede..3f6118d61 100644 --- a/src/drivers/filesys/fat/fat12/Fat12File.h +++ b/src/drivers/filesys/fat/fat12/Fat12File.h @@ -18,6 +18,7 @@ class Fat12File: public File{ uint32_t _lastByteLoaded; void* _fileLoc; size_t _fileLocSize; + //TODO what is this for uint32_t _fileLocStartInFile; public: size_t read(char* buffer, size_t size); From 8e8b0ac768afe035ff57d38a3acbe03487c94f96 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Fri, 19 Jan 2018 20:03:51 -0600 Subject: [PATCH 033/171] Fat12File constructor --- src/drivers/filesys/fat/fat12/Fat12FS.cpp | 3 ++- src/drivers/filesys/fat/fat12/Fat12File.h | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.cpp b/src/drivers/filesys/fat/fat12/Fat12FS.cpp index dea04f369..fb1343298 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12FS.cpp @@ -6,7 +6,8 @@ Fat12File *Fat12FS::open(char *path, int flags, int mode) { - Fat12File *ret = new Fat12File(); + //TODO find file + Fat12File *ret = new Fat12File(0); return ret; } diff --git a/src/drivers/filesys/fat/fat12/Fat12File.h b/src/drivers/filesys/fat/fat12/Fat12File.h index 3f6118d61..fc5f6cf0f 100644 --- a/src/drivers/filesys/fat/fat12/Fat12File.h +++ b/src/drivers/filesys/fat/fat12/Fat12File.h @@ -21,6 +21,11 @@ class Fat12File: public File{ //TODO what is this for uint32_t _fileLocStartInFile; public: + Fat12File(size_t firstCluster){ + _lastCluster = firstCluster; + void* _fileLoc = malloc((_device->FSInfo()->bytePerSec)*(_device->FSInfo()->secPerCluster)); + _device->readCluster(firstCluster, _fileLoc, (_device->FSInfo()->bytePerSec)*(_device->FSInfo()->secPerCluster)); + } size_t read(char* buffer, size_t size); bool readFromDisk(); From 965bccec509ff6912a6e505666efbc038c13e65a Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sat, 20 Jan 2018 10:26:50 -0600 Subject: [PATCH 034/171] slight refactor --- src/drivers/filesys/{ => general}/File.cpp | 0 src/drivers/filesys/{ => general}/File.h | 0 src/drivers/filesys/general/makefile | 3 +++ src/drivers/filesys/makefile | 3 +-- 4 files changed, 4 insertions(+), 2 deletions(-) rename src/drivers/filesys/{ => general}/File.cpp (100%) rename src/drivers/filesys/{ => general}/File.h (100%) create mode 100644 src/drivers/filesys/general/makefile diff --git a/src/drivers/filesys/File.cpp b/src/drivers/filesys/general/File.cpp similarity index 100% rename from src/drivers/filesys/File.cpp rename to src/drivers/filesys/general/File.cpp diff --git a/src/drivers/filesys/File.h b/src/drivers/filesys/general/File.h similarity index 100% rename from src/drivers/filesys/File.h rename to src/drivers/filesys/general/File.h diff --git a/src/drivers/filesys/general/makefile b/src/drivers/filesys/general/makefile new file mode 100644 index 000000000..251a469f5 --- /dev/null +++ b/src/drivers/filesys/general/makefile @@ -0,0 +1,3 @@ +OBS = File.o + +include ../../../../makefile.inc \ No newline at end of file diff --git a/src/drivers/filesys/makefile b/src/drivers/filesys/makefile index 3e97f4454..1ade5d7c5 100644 --- a/src/drivers/filesys/makefile +++ b/src/drivers/filesys/makefile @@ -1,4 +1,3 @@ -SUBDIRS = fat -OBS = File.o +SUBDIRS = fat general include ../../../makefile.inc From eeb811b0bfcf66c12bff35b7399b93c13df9fa08 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sat, 20 Jan 2018 10:34:09 -0600 Subject: [PATCH 035/171] basic node class for a file system --- src/drivers/filesys/general/FSNode.cpp | 5 +++++ src/drivers/filesys/general/FSNode.h | 23 +++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 src/drivers/filesys/general/FSNode.cpp create mode 100644 src/drivers/filesys/general/FSNode.h diff --git a/src/drivers/filesys/general/FSNode.cpp b/src/drivers/filesys/general/FSNode.cpp new file mode 100644 index 000000000..37803356e --- /dev/null +++ b/src/drivers/filesys/general/FSNode.cpp @@ -0,0 +1,5 @@ +// +// Created by Garrett Battaglia on 1/20/18. +// + +#include "FSNode.h" diff --git a/src/drivers/filesys/general/FSNode.h b/src/drivers/filesys/general/FSNode.h new file mode 100644 index 000000000..e308cce8c --- /dev/null +++ b/src/drivers/filesys/general/FSNode.h @@ -0,0 +1,23 @@ +// +// Created by Garrett Battaglia on 1/20/18. +// + +#ifndef EXOS_FSNODE_H +#define EXOS_FSNODE_H + +enum Type{ + FILE, DIR, LINK +}; + +class FSNode{ + private: + char* _name; + uint32_t _size; + FSNode** _children; + Type _type; + public: + uint32_t startSector(); + Permissions permissons(); +}; + +#endif //EXOS_FSNODE_H From defdbe79c065bb6fe4d6abad725251f408982b2a Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sat, 20 Jan 2018 10:34:57 -0600 Subject: [PATCH 036/171] new base class for file systems --- src/drivers/filesys/fat/fat12/Fat12FS.h | 2 +- src/drivers/filesys/general/FS.cpp | 5 +++++ src/drivers/filesys/general/FS.h | 13 +++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 src/drivers/filesys/general/FS.cpp create mode 100644 src/drivers/filesys/general/FS.h diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.h b/src/drivers/filesys/fat/fat12/Fat12FS.h index cb148cc9b..6da1d8697 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.h +++ b/src/drivers/filesys/fat/fat12/Fat12FS.h @@ -10,7 +10,7 @@ class Fat12File; -class Fat12FS { +class Fat12FS : public FS{ private: FatBPB* _FSInfo; //TODO replace with device. diff --git a/src/drivers/filesys/general/FS.cpp b/src/drivers/filesys/general/FS.cpp new file mode 100644 index 000000000..8bf640fe4 --- /dev/null +++ b/src/drivers/filesys/general/FS.cpp @@ -0,0 +1,5 @@ +// +// Created by Garrett Battaglia on 1/20/18. +// + +#include "FS.h" diff --git a/src/drivers/filesys/general/FS.h b/src/drivers/filesys/general/FS.h new file mode 100644 index 000000000..7f4f21d8c --- /dev/null +++ b/src/drivers/filesys/general/FS.h @@ -0,0 +1,13 @@ +// +// Created by Garrett Battaglia on 1/20/18. +// + +#ifndef EXOS_FS_H +#define EXOS_FS_H +class FS{ + private: + FSNode _root; + public: + File* open(char *path, int flags, int mode); +}; +#endif //EXOS_FS_H From 2c97acd4aa10140d1fa15eb3ea5102601ddd7057 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sat, 20 Jan 2018 10:55:58 -0600 Subject: [PATCH 037/171] fixed some compile errors its hard to work w/o a compiler --- src/Global.h | 1 + src/clib_misc/Assert.c | 13 ++++++ src/clib_misc/{assert.h => Assert.h} | 4 +- src/clib_misc/assert.c | 13 ------ src/clib_misc/makefile | 2 +- src/drivers/filesys/fat/FatStructs.h | 2 + src/drivers/filesys/fat/fat12/Fat12FS.cpp | 9 ++-- src/drivers/filesys/fat/fat12/Fat12FS.h | 3 +- src/drivers/filesys/fat/fat12/Fat12File.cpp | 46 ++++++++++++--------- src/drivers/filesys/fat/fat12/Fat12File.h | 5 ++- src/drivers/filesys/general/FS.h | 5 +++ src/drivers/filesys/general/FSNode.h | 4 +- src/drivers/filesys/general/makefile | 2 +- 13 files changed, 67 insertions(+), 42 deletions(-) create mode 100644 src/clib_misc/Assert.c rename src/clib_misc/{assert.h => Assert.h} (82%) delete mode 100644 src/clib_misc/assert.c diff --git a/src/Global.h b/src/Global.h index c12d0a687..7c8f20a8e 100755 --- a/src/Global.h +++ b/src/Global.h @@ -18,6 +18,7 @@ #include "memory/alloc/Malloc.h" #include "memory/alloc/New.h" #include "clib_misc/Abort.h" +#include "clib_misc/Assert.h" //bochs breakpoing ASM #define BREAKPOINT asm("xchgw %%bx, %%bx" : : : "%bx"); diff --git a/src/clib_misc/Assert.c b/src/clib_misc/Assert.c new file mode 100644 index 000000000..19b54748b --- /dev/null +++ b/src/clib_misc/Assert.c @@ -0,0 +1,13 @@ +// +// Created by Garrett Battaglia on 1/18/18. +// + +#include "Assert.h" + +extern "C" { + void assert(uint8_t expression) { + if(!expression) { + //TODO kernel panic... + } + } +}; diff --git a/src/clib_misc/assert.h b/src/clib_misc/Assert.h similarity index 82% rename from src/clib_misc/assert.h rename to src/clib_misc/Assert.h index e537785d6..a6799ca72 100644 --- a/src/clib_misc/assert.h +++ b/src/clib_misc/Assert.h @@ -5,7 +5,9 @@ #ifndef EXOS_ASSERT_H #define EXOS_ASSERT_H -extern "c"{ +#include "Global.h" + +extern "C"{ void assert(uint8_t expression); }; diff --git a/src/clib_misc/assert.c b/src/clib_misc/assert.c deleted file mode 100644 index b6fb98c1a..000000000 --- a/src/clib_misc/assert.c +++ /dev/null @@ -1,13 +0,0 @@ -// -// Created by Garrett Battaglia on 1/18/18. -// - -#include "assert.h" - -extern "c"{ -void assert(uint8_t expression){ - if(!expression){ - //TODO kernel panic... - } -} -}; \ No newline at end of file diff --git a/src/clib_misc/makefile b/src/clib_misc/makefile index bcf90eda8..4f5a0e22c 100644 --- a/src/clib_misc/makefile +++ b/src/clib_misc/makefile @@ -1,4 +1,4 @@ SUBDIRS = -OBS = Abort.o +OBS = Abort.o Assert.o include ../../makefile.inc diff --git a/src/drivers/filesys/fat/FatStructs.h b/src/drivers/filesys/fat/FatStructs.h index d02f4ff0b..60747a6ce 100644 --- a/src/drivers/filesys/fat/FatStructs.h +++ b/src/drivers/filesys/fat/FatStructs.h @@ -5,6 +5,8 @@ #ifndef EXOS_FATSTRUCTS_H #define EXOS_FATSTRUCTS_H +#include "Global.h" + struct FatBPB{ uint8_t jmp[3]; uint8_t oemIdent[8]; diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.cpp b/src/drivers/filesys/fat/fat12/Fat12FS.cpp index fb1343298..f69c14b9a 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12FS.cpp @@ -3,6 +3,7 @@ // #include "Fat12FS.h" +#include "Fat12File.h" Fat12File *Fat12FS::open(char *path, int flags, int mode) { @@ -12,14 +13,16 @@ Fat12File *Fat12FS::open(char *path, int flags, int mode) } //todo names, var sizes, structure taken from osdev wiki -bool Fat12FS::readCluster(uint16_t cluser, void* fileLoc, size_t fileLocSize){ +bool Fat12FS::readCluster(uint16_t cluster, void* fileLoc, size_t fileLocSize){ assert(fileLocSize >= (_FSInfo->secPerCluster * _FSInfo->bytePerSec)); uint32_t fat_size = (_FSInfo->secCount != 0)? _FSInfo->secCount : _FSInfo->largeSecCount; uint32_t root_dir_sectors = ((_FSInfo->dirEntryCount * 32) + (_FSInfo->bytePerSec - 1)) / _FSInfo->bytePerSec; uint32_t first_data_sector = _FSInfo->resSec + (_FSInfo->FATs * fat_size) + root_dir_sectors; uint32_t first_sector_of_cluster = ((cluster - 2) * _FSInfo->secPerCluster) + first_data_sector; for (uint32_t i =0; i < _FSInfo->secPerCluster; i++){ - _device->read(first_sector_of_cluster); + //TODO after _device isnt void* uncommetn below + //bool ret = _device->read(first_sector_of_cluster, fileLoc); + //TODO return on read error first_sector_of_cluster++; } -} \ No newline at end of file +} diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.h b/src/drivers/filesys/fat/fat12/Fat12FS.h index 6da1d8697..b17e3a074 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.h +++ b/src/drivers/filesys/fat/fat12/Fat12FS.h @@ -5,8 +5,9 @@ #ifndef EXOS_FAT12_H #define EXOS_FAT12_H -#include "Fat12File.h" #include "drivers/filesys/fat/FatStructs.h" +#include "Global.h" +#include "drivers/filesys/general/FS.h" class Fat12File; diff --git a/src/drivers/filesys/fat/fat12/Fat12File.cpp b/src/drivers/filesys/fat/fat12/Fat12File.cpp index 7336f0d1f..afa81f472 100644 --- a/src/drivers/filesys/fat/fat12/Fat12File.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12File.cpp @@ -5,18 +5,20 @@ #include "Fat12File.h" #include "memory/Mem.h" -size_t Fat12File::read(char *buffer, size_t size) -{ +size_t Fat12File::read(char *buffer, size_t size) { size_t bytesRead = 0; while (bytesRead < size) { if (size < (_fileLocSize - _lastByteRead)) { - memcpy(buffer + bytesRead, _fileLoc + (_lastByteRead - _fileLocStartInFile), size); + memcpy(buffer + bytesRead, + (uint8_t*) _fileLoc + (_lastByteRead - _fileLocStartInFile), + size); bytesRead += size; } else { - memcpy(buffer + bytesRead, _fileLoc + ((uint8_t*)_lastByteRead - (uint8_t*)_fileLocStartInFile), - _lastByteLoaded - _lastByteRead); + memcpy(buffer + bytesRead, + (uint8_t*) _fileLoc + (_lastByteRead - _fileLocStartInFile), + _lastByteLoaded - _lastByteRead); bytesRead += _lastByteLoaded - _lastByteRead; - if (!readFromDisk()) { + if ( !readFromDisk( )) { return bytesRead; } } @@ -24,14 +26,18 @@ size_t Fat12File::read(char *buffer, size_t size) } //TODO naming and types and general structure, taken from osdev wiki -bool Fat12File::readFromDisk() -{ - uint16_t firstFatSec = _device->FSInfo()->resSec; - unsigned char FAT_table[_device->FSInfo()->bytePerSec]; - while(read < _fileLocSize && _fileLocSize-read >= (_FSInfo->secPerCluster * _FSInfo->bytePerSec)) { - unsigned int fat_offset = _lastCluster + (_lastCluster / 2);// multiply by 1.5 - unsigned int fat_sector = firstFatSec + (fat_offset / _device->FSInfo()->bytePerSec); - unsigned int ent_offset = fat_offset % _device->FSInfo()->bytePerSec; +bool Fat12File::readFromDisk( ) { + uint16_t firstFatSec = _device->FSInfo( )->resSec; + unsigned char FAT_table[_device->FSInfo( )->bytePerSec]; + uint32_t read = 0; + while (read < _fileLocSize + && _fileLocSize - read + >= (_device->FSInfo( )->secPerCluster + * _device->FSInfo( )->bytePerSec)) { + unsigned int fat_offset = _lastCluster + (_lastCluster / 2); // multiply by 1.5 + unsigned int fat_sector = firstFatSec + + (fat_offset / _device->FSInfo( )->bytePerSec); + unsigned int ent_offset = fat_offset % _device->FSInfo( )->bytePerSec; unsigned short table_value = *(unsigned short *) &FAT_table[ent_offset]; @@ -41,15 +47,17 @@ bool Fat12File::readFromDisk() table_value = table_value & 0x0FFF; if (table_value >= 0xFF8) { //TODO make sure this frees everything - free(_fileLoc + read); - _fileLocSize=read; + free((uint8_t*)_fileLoc + read); + _fileLocSize = read; return true; } else { - bool ret = _device->readCluster(table_value, _fileLoc + read, _fileLocSize - read); - if (!ret){ + bool ret = _device->readCluster(table_value, (uint8_t*)_fileLoc + read, + _fileLocSize - read); + if ( !ret) { return false; } - read += (_device.FSInfo()->secPerCluster * _device * FSInfo()->bytePerSec); + read += (_device->FSInfo( )->secPerCluster + * _device->FSInfo( )->bytePerSec); _lastCluster = table_value; } } diff --git a/src/drivers/filesys/fat/fat12/Fat12File.h b/src/drivers/filesys/fat/fat12/Fat12File.h index fc5f6cf0f..3c10e1a4d 100644 --- a/src/drivers/filesys/fat/fat12/Fat12File.h +++ b/src/drivers/filesys/fat/fat12/Fat12File.h @@ -5,10 +5,11 @@ #ifndef EXOS_FAT12FILE_H #define EXOS_FAT12FILE_H -#include "drivers/filesys/File.h" +#include "drivers/filesys/general/File.h" #include "Fat12FS.h" +#include "Global.h" -class Fat12FS; +//class Fat12FS; class Fat12File: public File{ private: diff --git a/src/drivers/filesys/general/FS.h b/src/drivers/filesys/general/FS.h index 7f4f21d8c..0d8fc5233 100644 --- a/src/drivers/filesys/general/FS.h +++ b/src/drivers/filesys/general/FS.h @@ -4,6 +4,11 @@ #ifndef EXOS_FS_H #define EXOS_FS_H + +#include "Global.h" +#include "FSNode.h" +#include "File.h" + class FS{ private: FSNode _root; diff --git a/src/drivers/filesys/general/FSNode.h b/src/drivers/filesys/general/FSNode.h index e308cce8c..a6e943c3b 100644 --- a/src/drivers/filesys/general/FSNode.h +++ b/src/drivers/filesys/general/FSNode.h @@ -5,6 +5,8 @@ #ifndef EXOS_FSNODE_H #define EXOS_FSNODE_H +#include "Global.h" + enum Type{ FILE, DIR, LINK }; @@ -17,7 +19,7 @@ class FSNode{ Type _type; public: uint32_t startSector(); - Permissions permissons(); + //Permissions permissons(); }; #endif //EXOS_FSNODE_H diff --git a/src/drivers/filesys/general/makefile b/src/drivers/filesys/general/makefile index 251a469f5..851bb5fa7 100644 --- a/src/drivers/filesys/general/makefile +++ b/src/drivers/filesys/general/makefile @@ -1,3 +1,3 @@ -OBS = File.o +OBS = File.o FS.o FSNode.h include ../../../../makefile.inc \ No newline at end of file From 27fa492fd21138851be485d75d3f814c5a28affa Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sat, 20 Jan 2018 18:07:47 -0600 Subject: [PATCH 038/171] building fat12 dir structure --- src/drivers/filesys/fat/fat12/Fat12FS.cpp | 35 +++++++++++++++++------ src/drivers/filesys/fat/fat12/Fat12FS.h | 5 ++-- src/drivers/filesys/general/FS.h | 8 ++++-- src/drivers/filesys/general/FSNode.h | 15 +++++++++- 4 files changed, 48 insertions(+), 15 deletions(-) diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.cpp b/src/drivers/filesys/fat/fat12/Fat12FS.cpp index f69c14b9a..b7c58d2ea 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12FS.cpp @@ -5,24 +5,43 @@ #include "Fat12FS.h" #include "Fat12File.h" -Fat12File *Fat12FS::open(char *path, int flags, int mode) -{ +File *Fat12FS::open(char *path, int flags, int mode) { //TODO find file Fat12File *ret = new Fat12File(0); return ret; } //todo names, var sizes, structure taken from osdev wiki -bool Fat12FS::readCluster(uint16_t cluster, void* fileLoc, size_t fileLocSize){ +bool Fat12FS::readCluster(uint16_t cluster, void* fileLoc, size_t fileLocSize) { assert(fileLocSize >= (_FSInfo->secPerCluster * _FSInfo->bytePerSec)); - uint32_t fat_size = (_FSInfo->secCount != 0)? _FSInfo->secCount : _FSInfo->largeSecCount; - uint32_t root_dir_sectors = ((_FSInfo->dirEntryCount * 32) + (_FSInfo->bytePerSec - 1)) / _FSInfo->bytePerSec; - uint32_t first_data_sector = _FSInfo->resSec + (_FSInfo->FATs * fat_size) + root_dir_sectors; - uint32_t first_sector_of_cluster = ((cluster - 2) * _FSInfo->secPerCluster) + first_data_sector; - for (uint32_t i =0; i < _FSInfo->secPerCluster; i++){ + uint32_t fat_size = + (_FSInfo->secCount != 0) ? + _FSInfo->secCount : _FSInfo->largeSecCount; + uint32_t root_dir_sectors = ( (_FSInfo->dirEntryCount * 32) + + (_FSInfo->bytePerSec - 1)) / _FSInfo->bytePerSec; + uint32_t first_data_sector = _FSInfo->resSec + (_FSInfo->FATs * fat_size) + + root_dir_sectors; + uint32_t first_sector_of_cluster = ( (cluster - 2) * _FSInfo->secPerCluster) + + first_data_sector; + for (uint32_t i = 0; i < _FSInfo->secPerCluster; i++) { //TODO after _device isnt void* uncommetn below //bool ret = _device->read(first_sector_of_cluster, fileLoc); //TODO return on read error first_sector_of_cluster++; } } +//TODO check var sizes +void Fat12FS::buildDirStructure( ) { + _root = new FSNode( ); + uint8_t* tempCluster = (uint8_t*) malloc(_FSInfo->bytePerSec); + uint16_t startSector = (_FSInfo->resSec) + + (_FSInfo->FATs * _FSInfo->secPerFAT); + uint16_t rootDirSize = (float) _FSInfo->dirEntryCount + / (float) _FSInfo->bytePerSec + + (_FSInfo->dirEntryCount % _FSInfo->bytePerSec != 0); + for (size_t i = 0; i < rootDirSize; i++) { + //_device->read(startSectot+i, tempCluster) + parseEntry(tempCluster); + } + +} diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.h b/src/drivers/filesys/fat/fat12/Fat12FS.h index b17e3a074..dfbd2fa72 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.h +++ b/src/drivers/filesys/fat/fat12/Fat12FS.h @@ -14,15 +14,14 @@ class Fat12File; class Fat12FS : public FS{ private: FatBPB* _FSInfo; - //TODO replace with device. - void* _device; public: - Fat12File *open(char *path, int flags, int mode); + File *open(char *path, int flags, int mode); FatBPB *FSInfo( ) { return _FSInfo; } bool readCluster(uint16_t cluser, void* fileLoc, size_t fileLocSize); + void buildDirStructure(); }; #endif //EXOS_FAT12_H diff --git a/src/drivers/filesys/general/FS.h b/src/drivers/filesys/general/FS.h index 0d8fc5233..7fe3f6328 100644 --- a/src/drivers/filesys/general/FS.h +++ b/src/drivers/filesys/general/FS.h @@ -10,9 +10,11 @@ #include "File.h" class FS{ - private: - FSNode _root; + protected: + FSNode* _root; + void* _device; public: - File* open(char *path, int flags, int mode); + virtual File* open(char *path, int flags, int mode) = 0; + virtual void buildDirStructure() = 0; }; #endif //EXOS_FS_H diff --git a/src/drivers/filesys/general/FSNode.h b/src/drivers/filesys/general/FSNode.h index a6e943c3b..d1d172432 100644 --- a/src/drivers/filesys/general/FSNode.h +++ b/src/drivers/filesys/general/FSNode.h @@ -17,8 +17,21 @@ class FSNode{ uint32_t _size; FSNode** _children; Type _type; + size_t _childernCount; public: - uint32_t startSector(); + FSNode(){ + _name="root"; + _size =0; + _type=DIR; + } + FSNode(char* name, uint32_t size, Type type){ + _name=name; + _size = size; + _type =type; + _children = nullptr; + _childernCount = 0; + } + virtual uint32_t startSector() = 0; //Permissions permissons(); }; From 1cc6a9316c05226155764428509c9556cf07f9ec Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sat, 20 Jan 2018 18:14:08 -0600 Subject: [PATCH 039/171] FSNode for fat --- src/drivers/filesys/fat/fat12/Fat12FS.cpp | 3 ++- src/drivers/filesys/fat/fat12/Fat12FSNode.cpp | 16 ++++++++++++++ src/drivers/filesys/fat/fat12/Fat12FSNode.h | 22 +++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 src/drivers/filesys/fat/fat12/Fat12FSNode.cpp create mode 100644 src/drivers/filesys/fat/fat12/Fat12FSNode.h diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.cpp b/src/drivers/filesys/fat/fat12/Fat12FS.cpp index b7c58d2ea..cd64368f7 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12FS.cpp @@ -4,6 +4,7 @@ #include "Fat12FS.h" #include "Fat12File.h" +#include "Fat12FSNode.h" File *Fat12FS::open(char *path, int flags, int mode) { //TODO find file @@ -32,7 +33,7 @@ bool Fat12FS::readCluster(uint16_t cluster, void* fileLoc, size_t fileLocSize) { } //TODO check var sizes void Fat12FS::buildDirStructure( ) { - _root = new FSNode( ); + _root = new Fat12FSNode( ); uint8_t* tempCluster = (uint8_t*) malloc(_FSInfo->bytePerSec); uint16_t startSector = (_FSInfo->resSec) + (_FSInfo->FATs * _FSInfo->secPerFAT); diff --git a/src/drivers/filesys/fat/fat12/Fat12FSNode.cpp b/src/drivers/filesys/fat/fat12/Fat12FSNode.cpp new file mode 100644 index 000000000..aabb27546 --- /dev/null +++ b/src/drivers/filesys/fat/fat12/Fat12FSNode.cpp @@ -0,0 +1,16 @@ +/* + * Fat12FSNode.cpp + * + * Created on: Jan 20, 2018 + * Author: garrett + */ + +Fat12FSNode::Fat12FSNode( ) { + // TODO Auto-generated constructor stub + +} + +Fat12FSNode::~Fat12FSNode( ) { + // TODO Auto-generated destructor stub +} + diff --git a/src/drivers/filesys/fat/fat12/Fat12FSNode.h b/src/drivers/filesys/fat/fat12/Fat12FSNode.h new file mode 100644 index 000000000..209b42ddb --- /dev/null +++ b/src/drivers/filesys/fat/fat12/Fat12FSNode.h @@ -0,0 +1,22 @@ +/* + * Fat12FSNode.h + * + * Created on: Jan 20, 2018 + * Author: garrett + */ + +#ifndef SRC_DRIVERS_FILESYS_FAT_FAT12_FAT12FSNODE_H_ +#define SRC_DRIVERS_FILESYS_FAT_FAT12_FAT12FSNODE_H_ +#include "Global.h" + +class Fat12FSNode: public FSNode { + private: + uint32_t startCluster; + public: + virtual uint32_t startSector(){ + + } + virtual ~Fat12FSNode( ); +}; + +#endif /* SRC_DRIVERS_FILESYS_FAT_FAT12_FAT12FSNODE_H_ */ From 1181f6b0ac1a30b438dc1b712c846b12dfcb50ab Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sat, 20 Jan 2018 18:35:33 -0600 Subject: [PATCH 040/171] few small issue fixes --- src/drivers/filesys/fat/fat12/Fat12FS.cpp | 7 +++++-- src/drivers/filesys/fat/fat12/Fat12FS.h | 1 + src/drivers/filesys/fat/fat12/Fat12FSNode.h | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.cpp b/src/drivers/filesys/fat/fat12/Fat12FS.cpp index cd64368f7..6567208cf 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12FS.cpp @@ -34,7 +34,7 @@ bool Fat12FS::readCluster(uint16_t cluster, void* fileLoc, size_t fileLocSize) { //TODO check var sizes void Fat12FS::buildDirStructure( ) { _root = new Fat12FSNode( ); - uint8_t* tempCluster = (uint8_t*) malloc(_FSInfo->bytePerSec); + uint8_t* tempSector = (uint8_t*) malloc(_FSInfo->bytePerSec); uint16_t startSector = (_FSInfo->resSec) + (_FSInfo->FATs * _FSInfo->secPerFAT); uint16_t rootDirSize = (float) _FSInfo->dirEntryCount @@ -42,7 +42,10 @@ void Fat12FS::buildDirStructure( ) { + (_FSInfo->dirEntryCount % _FSInfo->bytePerSec != 0); for (size_t i = 0; i < rootDirSize; i++) { //_device->read(startSectot+i, tempCluster) - parseEntry(tempCluster); + parseEntry(tempSector); } +} + +void Fat12FS::parseEntry(uint8_t* sector){ } diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.h b/src/drivers/filesys/fat/fat12/Fat12FS.h index dfbd2fa72..cc4ce6b44 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.h +++ b/src/drivers/filesys/fat/fat12/Fat12FS.h @@ -22,6 +22,7 @@ class Fat12FS : public FS{ } bool readCluster(uint16_t cluser, void* fileLoc, size_t fileLocSize); void buildDirStructure(); + void parseEntry(uint8_t* sector); }; #endif //EXOS_FAT12_H diff --git a/src/drivers/filesys/fat/fat12/Fat12FSNode.h b/src/drivers/filesys/fat/fat12/Fat12FSNode.h index 209b42ddb..6089c26f6 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FSNode.h +++ b/src/drivers/filesys/fat/fat12/Fat12FSNode.h @@ -16,7 +16,9 @@ class Fat12FSNode: public FSNode { virtual uint32_t startSector(){ } - virtual ~Fat12FSNode( ); + virtual ~Fat12FSNode( ){ + + } }; #endif /* SRC_DRIVERS_FILESYS_FAT_FAT12_FAT12FSNODE_H_ */ From 236fefcd4d97b7a77d49a1c1cf88ac34297d5fcf Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 22 Jan 2018 13:57:07 -0600 Subject: [PATCH 041/171] removed old malloc also added some stuff to the git ignore --- .gitignore | 2 ++ src/memory/alloc/Malloc.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 62bd89bc3..3b5f350cb 100755 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ .~lock.* *.swp *.swo +bx_enh_dbg.ini +.vscode/ \ No newline at end of file diff --git a/src/memory/alloc/Malloc.c b/src/memory/alloc/Malloc.c index 8245b397b..ba6d89474 100644 --- a/src/memory/alloc/Malloc.c +++ b/src/memory/alloc/Malloc.c @@ -35,7 +35,7 @@ extern "C" {/* Use C linkage for kernel_main. */ * @param size to alloc */ void* malloc(size_t size) { - size_t space = (size_t) top - (size_t) base; + /*size_t space = (size_t) top - (size_t) base; if (space > size) { //if there is space in the current phys mem allocated void* oldBase = base; @@ -49,7 +49,7 @@ void* malloc(size_t size) { size_t sizeOfNewMem = ((size-space)/FOUR_KB + ( ((size-space) & 0xFFF) != 0)) * FOUR_KB; top = (void*) ((size_t) top + sizeOfNewMem + ((size_t)startOfNewMem - (size_t)top) ); return malloc(size); - } + }*/ } /** * free mem From b0f19b700793650ac8099a8313216fde4aa66827 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 22 Jan 2018 16:27:43 -0600 Subject: [PATCH 042/171] malloc init code This should compile --- .gitignore | 4 +++- linker.ld | 2 +- src/memory/alloc/Malloc.c | 35 ++++++++++++++++++++++------------- src/memory/alloc/Malloc.h | 13 +++++-------- 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/.gitignore b/.gitignore index 3b5f350cb..2af05c8a1 100755 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,6 @@ *.swp *.swo bx_enh_dbg.ini -.vscode/ \ No newline at end of file +.vscode/ +.idea/ +cmake-build-debug/ \ No newline at end of file diff --git a/linker.ld b/linker.ld index b829c5b54..fd0f5913c 100755 --- a/linker.ld +++ b/linker.ld @@ -24,6 +24,6 @@ SECTIONS { *(.bss) _ebss = .; } - kernelEnd = .; kernelSize = . - kernelStart; + kernelEnd = .; } \ No newline at end of file diff --git a/src/memory/alloc/Malloc.c b/src/memory/alloc/Malloc.c index ba6d89474..774e305c3 100644 --- a/src/memory/alloc/Malloc.c +++ b/src/memory/alloc/Malloc.c @@ -10,32 +10,37 @@ #include "memory/structures/PageTable.h" #include "memory/alloc/PageFrameAllocator.h" -/** - * top of the paged in mem - */ -void* top; -/** - * base of free mem - */ -void* base; +int topPaged; /** * set up the vars needed for malloc */ -void mallocInit( ) { +void mallocInit() +{ + topPaged = (((size_t)(&kernelSize) + (uint32_t) & kernelStart - vKernelStart) / FOUR_KB + 1) * FOUR_KB + + FOUR_KB - 1; + &kernelEnd->used = false; + &kernelEnd->next = nullptr; + + /* base = &kernelEnd; top = (void*) ( (size_t)( &kernelSize) + (uint32_t) & kernelStart + FOUR_KB); + */ } + #if defined(__cplusplus) extern "C" {/* Use C linkage for kernel_main. */ #endif + /** * mem alloc * @param size to alloc */ -void* malloc(size_t size) { - /*size_t space = (size_t) top - (size_t) base; +void *malloc(size_t size) +{ + /* + size_t space = (size_t) top - (size_t) base; if (space > size) { //if there is space in the current phys mem allocated void* oldBase = base; @@ -49,15 +54,19 @@ void* malloc(size_t size) { size_t sizeOfNewMem = ((size-space)/FOUR_KB + ( ((size-space) & 0xFFF) != 0)) * FOUR_KB; top = (void*) ((size_t) top + sizeOfNewMem + ((size_t)startOfNewMem - (size_t)top) ); return malloc(size); - }*/ + } + */ } + /** * free mem * @param ptr to the mem to free */ -void free(void *ptr){ +void free(void *ptr) +{ //TODO } + #if defined(__cplusplus) }/* Use C linkage for kernel_main. */ #endif diff --git a/src/memory/alloc/Malloc.h b/src/memory/alloc/Malloc.h index 20d2d0ca8..273f04a87 100644 --- a/src/memory/alloc/Malloc.h +++ b/src/memory/alloc/Malloc.h @@ -10,19 +10,16 @@ #include "Global.h" -/** - * top of the paged in mem - */ -extern void* top; -/** - * base of free mem - */ -extern void* base; /** * end of the kernel */ extern uint32_t kernelEnd; +struct memHeader{ + bool used; + memHeader *next; +}; + /** * set up the vars needed for malloc */ From e952ff92b607107459d0177d617dad875ed836ff Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 22 Jan 2018 18:06:13 -0600 Subject: [PATCH 043/171] this should work as the new malloc --- src/memory/alloc/Malloc.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/memory/alloc/Malloc.c b/src/memory/alloc/Malloc.c index 774e305c3..2b0872751 100644 --- a/src/memory/alloc/Malloc.c +++ b/src/memory/alloc/Malloc.c @@ -10,15 +10,16 @@ #include "memory/structures/PageTable.h" #include "memory/alloc/PageFrameAllocator.h" -int topPaged; +void *top; +void*; /** * set up the vars needed for malloc */ void mallocInit() { - topPaged = (((size_t)(&kernelSize) + (uint32_t) & kernelStart - vKernelStart) / FOUR_KB + 1) * FOUR_KB + - FOUR_KB - 1; + top = (((size_t)(&kernelSize) + (uint32_t) & kernelStart - vKernelStart) / FOUR_KB + 1) * FOUR_KB + + FOUR_KB - 1; &kernelEnd->used = false; &kernelEnd->next = nullptr; @@ -39,6 +40,26 @@ extern "C" {/* Use C linkage for kernel_main. */ */ void *malloc(size_t size) { + //size_t space = (size_t) top - (size_t) & kernelEnd; + //if (space > size) { + //have space + for (memHeader *i; i < &kernelEnd; i = i->next) { + if (next == nullptr && (current - top) > size && !(i->used)) { + //at end + return i; + } else if ((current - i->next) > size && !(i->used)) { + return i; + } + } + //} else { + //need to page in + //TODO handle out of mem + void *startOfNewMem = frameAlloc.allocatePhysMem(size - space, pageTable.getKernelStart()); + size_t sizeOfNewMem = ((size - space) / FOUR_KB + (((size - space) & 0xFFF) != 0)) * FOUR_KB; + top = (void *) ((size_t) top + sizeOfNewMem + ((size_t) startOfNewMem - (size_t) top)); + return malloc(size); + //} + /* size_t space = (size_t) top - (size_t) base; if (space > size) { From 08c5b7661b18d69d37ebe35129d18337b86e5a04 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 22 Jan 2018 18:23:33 -0600 Subject: [PATCH 044/171] this "should" add the headers --- src/memory/alloc/Malloc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/memory/alloc/Malloc.c b/src/memory/alloc/Malloc.c index 2b0872751..a8c4a7377 100644 --- a/src/memory/alloc/Malloc.c +++ b/src/memory/alloc/Malloc.c @@ -46,6 +46,13 @@ void *malloc(size_t size) for (memHeader *i; i < &kernelEnd; i = i->next) { if (next == nullptr && (current - top) > size && !(i->used)) { //at end + current->used = true; + if(current->next ==((memHeader*)(((uint8_t*)current) + size)) ) { + ((memHeader *)(((uint8_t *) current) + size))->used = false; + ((memHeader * )(((uint8_t *) current) + size))->next = current->next; + } + current->used = true; + current->next = ((uint8_t *) current) + size; return i; } else if ((current - i->next) > size && !(i->used)) { return i; From 2e631a870108bead1562e99a6444065ff83cc0ac Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 22 Jan 2018 18:26:39 -0600 Subject: [PATCH 045/171] i forgot to return after the header this should be the end of malloc --- src/memory/alloc/Malloc.c | 41 ++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/memory/alloc/Malloc.c b/src/memory/alloc/Malloc.c index a8c4a7377..2d28aa608 100644 --- a/src/memory/alloc/Malloc.c +++ b/src/memory/alloc/Malloc.c @@ -40,31 +40,32 @@ extern "C" {/* Use C linkage for kernel_main. */ */ void *malloc(size_t size) { + size += sizeof(memHeader); //size_t space = (size_t) top - (size_t) & kernelEnd; //if (space > size) { - //have space - for (memHeader *i; i < &kernelEnd; i = i->next) { - if (next == nullptr && (current - top) > size && !(i->used)) { - //at end - current->used = true; - if(current->next ==((memHeader*)(((uint8_t*)current) + size)) ) { - ((memHeader *)(((uint8_t *) current) + size))->used = false; - ((memHeader * )(((uint8_t *) current) + size))->next = current->next; - } - current->used = true; - current->next = ((uint8_t *) current) + size; - return i; - } else if ((current - i->next) > size && !(i->used)) { - return i; + //have space + for (memHeader *i; i < &kernelEnd; i = i->next) { + if (next == nullptr && (i - top) > size && !(i->used)) { + //at end + current->used = true; + if (current->next == ((memHeader * )(((uint8_t *) i) + size))) { + ((memHeader * )(((uint8_t *) i) + size))->used = false; + ((memHeader * )(((uint8_t *) i) + size))->next = i->next; } + i->used = true; + i->next = ((uint8_t *) i) + size; + return i + sizeof(memHeader); + } else if ((i - i->next) > size && !(i->used)) { + return i + sizeof(memHeader); } + } //} else { - //need to page in - //TODO handle out of mem - void *startOfNewMem = frameAlloc.allocatePhysMem(size - space, pageTable.getKernelStart()); - size_t sizeOfNewMem = ((size - space) / FOUR_KB + (((size - space) & 0xFFF) != 0)) * FOUR_KB; - top = (void *) ((size_t) top + sizeOfNewMem + ((size_t) startOfNewMem - (size_t) top)); - return malloc(size); + //need to page in + //TODO handle out of mem + void *startOfNewMem = frameAlloc.allocatePhysMem(size - space, pageTable.getKernelStart()); + size_t sizeOfNewMem = ((size - space) / FOUR_KB + (((size - space) & 0xFFF) != 0)) * FOUR_KB; + top = (void *) ((size_t) top + sizeOfNewMem + ((size_t) startOfNewMem - (size_t) top)); + return malloc(size); //} /* From 59221089c08c3c20fbaf8e25603ae211df6da3a5 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 22 Jan 2018 18:39:13 -0600 Subject: [PATCH 046/171] i moved the start of the header to after the requested space ok i think im done --- src/memory/alloc/Malloc.c | 8 ++++---- src/memory/alloc/Malloc.h | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/memory/alloc/Malloc.c b/src/memory/alloc/Malloc.c index 2d28aa608..7764876ae 100644 --- a/src/memory/alloc/Malloc.c +++ b/src/memory/alloc/Malloc.c @@ -48,12 +48,12 @@ void *malloc(size_t size) if (next == nullptr && (i - top) > size && !(i->used)) { //at end current->used = true; - if (current->next == ((memHeader * )(((uint8_t *) i) + size))) { - ((memHeader * )(((uint8_t *) i) + size))->used = false; - ((memHeader * )(((uint8_t *) i) + size))->next = i->next; + if (current->next == ((memHeader * )(((uint8_t *) i +1) + size))) { + ((memHeader * )(((uint8_t *) i+1) + size))->used = false; + ((memHeader * )(((uint8_t *) i+1) + size))->next = i->next; } i->used = true; - i->next = ((uint8_t *) i) + size; + i->next = ((uint8_t *) i+1) + size; return i + sizeof(memHeader); } else if ((i - i->next) > size && !(i->used)) { return i + sizeof(memHeader); diff --git a/src/memory/alloc/Malloc.h b/src/memory/alloc/Malloc.h index 273f04a87..a32c7ec05 100644 --- a/src/memory/alloc/Malloc.h +++ b/src/memory/alloc/Malloc.h @@ -27,16 +27,19 @@ void mallocInit(); #if defined(__cplusplus) extern "C" {/* Use C linkage for kernel_main. */ #endif + /** * mem alloc * @param size to alloc */ void* malloc(size_t size); + /** * free mem * @param ptr to the mem to free */ void free(void *ptr); + #if defined(__cplusplus) }/* Use C linkage for kernel_main. */ #endif From ce477172843dd096a44261cfb8a7110613d42885 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 22 Jan 2018 18:53:55 -0600 Subject: [PATCH 047/171] most of free also forgot to init loop vars in malloc, i need more coffee... --- src/memory/alloc/Malloc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/memory/alloc/Malloc.c b/src/memory/alloc/Malloc.c index 7764876ae..fd644eef2 100644 --- a/src/memory/alloc/Malloc.c +++ b/src/memory/alloc/Malloc.c @@ -44,7 +44,7 @@ void *malloc(size_t size) //size_t space = (size_t) top - (size_t) & kernelEnd; //if (space > size) { //have space - for (memHeader *i; i < &kernelEnd; i = i->next) { + for (memHeader *i = &kernelEnd; i < top; i = i->next) { if (next == nullptr && (i - top) > size && !(i->used)) { //at end current->used = true; @@ -93,7 +93,13 @@ void *malloc(size_t size) */ void free(void *ptr) { -//TODO + memHeader *i =&kernelEnd; + for(; i < top && i->next <= ptr && i->next->next >ptr; i = i->next); + if(i == top){ + ptr->next = i->next; + } + ptr->used = false; + i->next=ptr; } #if defined(__cplusplus) From e84fa5cce7375ec99cb422d9c341995d12575471 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 22 Jan 2018 19:00:33 -0600 Subject: [PATCH 048/171] this should combine free space I hope i can still write code --- src/memory/alloc/Malloc.c | 27 +++++++++++++++++++-------- src/memory/alloc/Malloc.h | 3 +++ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/memory/alloc/Malloc.c b/src/memory/alloc/Malloc.c index fd644eef2..401b31904 100644 --- a/src/memory/alloc/Malloc.c +++ b/src/memory/alloc/Malloc.c @@ -48,12 +48,12 @@ void *malloc(size_t size) if (next == nullptr && (i - top) > size && !(i->used)) { //at end current->used = true; - if (current->next == ((memHeader * )(((uint8_t *) i +1) + size))) { - ((memHeader * )(((uint8_t *) i+1) + size))->used = false; - ((memHeader * )(((uint8_t *) i+1) + size))->next = i->next; + if (current->next == ((memHeader * )(((uint8_t *) i + 1) + size))) { + ((memHeader * )(((uint8_t *) i + 1) + size))->used = false; + ((memHeader * )(((uint8_t *) i + 1) + size))->next = i->next; } i->used = true; - i->next = ((uint8_t *) i+1) + size; + i->next = ((uint8_t *) i + 1) + size; return i + sizeof(memHeader); } else if ((i - i->next) > size && !(i->used)) { return i + sizeof(memHeader); @@ -93,13 +93,24 @@ void *malloc(size_t size) */ void free(void *ptr) { - memHeader *i =&kernelEnd; - for(; i < top && i->next <= ptr && i->next->next >ptr; i = i->next); - if(i == top){ + memHeader *i = &kernelEnd; + for (; i < top && i->next <= ptr && i->next->next > ptr; i = i->next); + //TODO hmm something is fishy about this + if (i == top) { ptr->next = i->next; } ptr->used = false; - i->next=ptr; + i->next = ptr; + compFreeSpace(); +} + +void compFreeSpace() +{ + for (memHeader *i = &kernelEnd; i < top; i = i->next) { + if (i->used == false && i->next->used==false){ + i->next = i->next->next; + } + } } #if defined(__cplusplus) diff --git a/src/memory/alloc/Malloc.h b/src/memory/alloc/Malloc.h index a32c7ec05..6b6a3ee58 100644 --- a/src/memory/alloc/Malloc.h +++ b/src/memory/alloc/Malloc.h @@ -43,4 +43,7 @@ void free(void *ptr); #if defined(__cplusplus) }/* Use C linkage for kernel_main. */ #endif + +void compFreeSpace(); + #endif /* MALLOC_H_ */ From 38921b6c9334711defe4d14ad82076ee31af5a71 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 22 Jan 2018 19:48:54 -0600 Subject: [PATCH 049/171] realloc should work --- src/memory/alloc/Malloc.c | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/src/memory/alloc/Malloc.c b/src/memory/alloc/Malloc.c index 401b31904..bb74a7f58 100644 --- a/src/memory/alloc/Malloc.c +++ b/src/memory/alloc/Malloc.c @@ -104,15 +104,46 @@ void free(void *ptr) compFreeSpace(); } +#if defined(__cplusplus) +}/* Use C linkage for kernel_main. */ +#endif + void compFreeSpace() { for (memHeader *i = &kernelEnd; i < top; i = i->next) { - if (i->used == false && i->next->used==false){ + if (i->used == false && i->next->used == false) { i->next = i->next->next; } } } -#if defined(__cplusplus) -}/* Use C linkage for kernel_main. */ -#endif +void *realloc(void *ptr, size_t size) +{ + memHeader *i = &kernelEnd; + for (; i < top && i->next <= ptr && i->next->next > ptr; i = i->next); + memHeader *next = i->next; + if ((uint8_t) ptr + size == next) { + return ptr; + } else if ((uint8_t) ptr + size < next) { + free((uint8_t *) ptr + size); + return ptr; + } else if ((uint8_t) ptr + size < next) { + if (!next->used) { + size_t found = 0; + while (!next->used && next->next != nullptr && found <= size - i - next){ + found += next - next->next; + next = next->next; + } + if(found == size){ + i->next = next; + return ptr; + } + } + void* res = malloc(size); + memcpy(res, ptr, i-next); + free(prt); + return res; + //malloc, copy free + } + +} \ No newline at end of file From 7c208fc3f8ece6339bfd49183867aea80d47e22c Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 22 Jan 2018 20:55:02 -0600 Subject: [PATCH 050/171] fixed some compiler erros thes commits should go away b/c i have a cross compiler on both comps now --- .gitignore | 3 ++- makefile.inc | 4 ++-- src/memory/alloc/Malloc.c | 48 +++++++++++++++++++-------------------- 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/.gitignore b/.gitignore index 2af05c8a1..6c1eb90d6 100755 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ bx_enh_dbg.ini .vscode/ .idea/ -cmake-build-debug/ \ No newline at end of file +cmake-build-debug/ +kernel.bin \ No newline at end of file diff --git a/makefile.inc b/makefile.inc index 984f162ec..d2e97930a 100644 --- a/makefile.inc +++ b/makefile.inc @@ -1,8 +1,8 @@ AS = i686-elf-as GPP = i686-elf-g++ GCC = i686-elf-gcc -OS_CPP = /home/garrett/workspace/ExOS -BUILD_TO = /run/media/garrett/EXOS/boot/kernel.bin +OS_CPP = /Users/garrettbattaglia/Documents/dev/Exos/exos +BUILD_TO = /Users/garrettbattaglia/Documents/dev/Exos/exos/kernel.bin CFLAGS = -c -ffreestanding -O2 -Wall -Wextra -fno-rtti -fno-exceptions -std=gnu++14 -I$(OS_CPP)/src OBJ_DIR = $(OS_CPP)/build diff --git a/src/memory/alloc/Malloc.c b/src/memory/alloc/Malloc.c index bb74a7f58..069d58f82 100644 --- a/src/memory/alloc/Malloc.c +++ b/src/memory/alloc/Malloc.c @@ -9,19 +9,18 @@ #include "Kernel.h" #include "memory/structures/PageTable.h" #include "memory/alloc/PageFrameAllocator.h" - +#include "memory/Mem.h" void *top; -void*; /** * set up the vars needed for malloc */ void mallocInit() { - top = (((size_t)(&kernelSize) + (uint32_t) & kernelStart - vKernelStart) / FOUR_KB + 1) * FOUR_KB + - FOUR_KB - 1; - &kernelEnd->used = false; - &kernelEnd->next = nullptr; + top = (void*)((((size_t)(&kernelSize) + (uint32_t) & kernelStart - (uint32_t)pageTable.getKernelStart()) / FOUR_KB + 1) * FOUR_KB + + FOUR_KB - 1); + ((memHeader*)&kernelEnd)->used = false; + ((memHeader*)&kernelEnd)->next = nullptr; /* base = &kernelEnd; @@ -44,16 +43,16 @@ void *malloc(size_t size) //size_t space = (size_t) top - (size_t) & kernelEnd; //if (space > size) { //have space - for (memHeader *i = &kernelEnd; i < top; i = i->next) { - if (next == nullptr && (i - top) > size && !(i->used)) { + for (memHeader *i = (memHeader*)&kernelEnd; i < top; i = i->next) { + if (i->next == nullptr && ((uint32_t)i - (uint32_t)top) > size && !(i->used)) { //at end - current->used = true; - if (current->next == ((memHeader * )(((uint8_t *) i + 1) + size))) { + i->used = true; + if (i->next == ((memHeader * )(((uint8_t *) i + 1) + size))) { ((memHeader * )(((uint8_t *) i + 1) + size))->used = false; ((memHeader * )(((uint8_t *) i + 1) + size))->next = i->next; } i->used = true; - i->next = ((uint8_t *) i + 1) + size; + i->next = (memHeader*)(((uint8_t *) i + 1) + size); return i + sizeof(memHeader); } else if ((i - i->next) > size && !(i->used)) { return i + sizeof(memHeader); @@ -62,8 +61,8 @@ void *malloc(size_t size) //} else { //need to page in //TODO handle out of mem - void *startOfNewMem = frameAlloc.allocatePhysMem(size - space, pageTable.getKernelStart()); - size_t sizeOfNewMem = ((size - space) / FOUR_KB + (((size - space) & 0xFFF) != 0)) * FOUR_KB; + void *startOfNewMem = frameAlloc.allocatePhysMem(size, pageTable.getKernelStart()); + size_t sizeOfNewMem = ((size) / FOUR_KB + (((size) & 0xFFF) != 0)) * FOUR_KB; top = (void *) ((size_t) top + sizeOfNewMem + ((size_t) startOfNewMem - (size_t) top)); return malloc(size); //} @@ -93,14 +92,14 @@ void *malloc(size_t size) */ void free(void *ptr) { - memHeader *i = &kernelEnd; + memHeader *i = (memHeader*)&kernelEnd; for (; i < top && i->next <= ptr && i->next->next > ptr; i = i->next); //TODO hmm something is fishy about this if (i == top) { - ptr->next = i->next; + ((memHeader*)ptr)->next = i->next; } - ptr->used = false; - i->next = ptr; + ((memHeader*)ptr)->used = false; + i->next = (memHeader*)ptr; compFreeSpace(); } @@ -110,7 +109,7 @@ void free(void *ptr) void compFreeSpace() { - for (memHeader *i = &kernelEnd; i < top; i = i->next) { + for (memHeader *i = (memHeader*)&kernelEnd; i < top; i = i->next) { if (i->used == false && i->next->used == false) { i->next = i->next->next; } @@ -119,18 +118,18 @@ void compFreeSpace() void *realloc(void *ptr, size_t size) { - memHeader *i = &kernelEnd; + memHeader *i = (memHeader*)&kernelEnd; for (; i < top && i->next <= ptr && i->next->next > ptr; i = i->next); memHeader *next = i->next; - if ((uint8_t) ptr + size == next) { + if ((uint8_t*) ptr + size == (uint8_t*)next) { return ptr; - } else if ((uint8_t) ptr + size < next) { + } else if ((uint8_t*) ptr + size < (uint8_t*)next) { free((uint8_t *) ptr + size); return ptr; - } else if ((uint8_t) ptr + size < next) { + } else if ((uint8_t*) ptr + size < (uint8_t*)next) { if (!next->used) { size_t found = 0; - while (!next->used && next->next != nullptr && found <= size - i - next){ + while (!next->used && next->next != nullptr && found <= size - (uint32_t)i - (uint32_t)next){ found += next - next->next; next = next->next; } @@ -141,9 +140,8 @@ void *realloc(void *ptr, size_t size) } void* res = malloc(size); memcpy(res, ptr, i-next); - free(prt); + free(ptr); return res; - //malloc, copy free } } \ No newline at end of file From 2a0eceb4a09b9888cb9fd63ec518e6a649270405 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Thu, 25 Jan 2018 13:32:50 -0600 Subject: [PATCH 051/171] test code --- src/Kernel.cpp | 118 ++++++++++++++++++++++++++++--------------------- 1 file changed, 67 insertions(+), 51 deletions(-) diff --git a/src/Kernel.cpp b/src/Kernel.cpp index 043a5bab4..4eb252b63 100644 --- a/src/Kernel.cpp +++ b/src/Kernel.cpp @@ -29,69 +29,85 @@ PageFrameAllocator frameAlloc; #if defined(__cplusplus) extern "C" {/* Use C linkage for kernel_main. */ #endif - void kernelMain(multiboot_info_t* mbd) { - //turn off interrupts before configed - asm("cli"); - //clear screen, set the pointer to the start of the VGA buffer. - terminalInit((uint16_t*) 0xC00B8000); - // Green on black! - terminalSetColor(vgaEntryColor(VGA_COLOR_GREEN, VGA_COLOR_BLACK)); - terminalWriteLine("Terminal active, Welcome to ExOS!"); - terminalWriteLine("Preparing your system:"); - terminalWriteString(" Preparing GDT..."); - //build and replce grub's GDT with a custom writable one. - gdt.build( ); - gdt.load( ); - terminalWriteLine(" Done!"); - terminalWriteString(" Preparing the page table..."); - //rebuild page table. replaces the one built in boot.s - pageTable.build( ); - terminalWriteLine(" Done!"); - terminalWriteString(" Setting up interrupts..."); - //sets up interrups and enables them - interruptSetUp( ); - terminalWriteLine(" Done!"); - terminalWriteString(" Preparing the memory allocator..."); - //get the memory map from grub - getMemMap(mbd); - //build the page frame allocator (allocate physical memory) - frameAlloc.build( ); - //set malloc's support vars - mallocInit( ); - terminalWriteLine(" Done!"); - terminalWriteString(" Finding PCI buses..."); - //find the valid PCI buses - PCIInit(); - terminalWriteLine(" Done!"); - terminalWriteString(" Finding USB host controllers..."); - //find the (3 or less) USB host controllers. all have the same class/subclass code. - PCIDeviceList usbHostControllers(0x0C, 0x03, false); - terminalWriteLine(" Done!"); - terminalWriteLine("!!!!ExOS fully booted!!!!"); - printf("Test printf %d %c\n", 42, 'B'); - printf("Newline is 0x%x%c", '\n', '\n'); - for (int cx = 0; cx < 10; cx++) { - printf("%d", cx); - } - //dont return. - while (true) { - asm("hlt"); - } + +void kernelMain(multiboot_info_t *mbd) +{ + //turn off interrupts before configed + asm("cli"); + //clear screen, set the pointer to the start of the VGA buffer. + terminalInit((uint16_t *) 0xC00B8000); + // Green on black! + terminalSetColor(vgaEntryColor(VGA_COLOR_GREEN, VGA_COLOR_BLACK)); + terminalWriteLine("Terminal active, Welcome to ExOS!"); + terminalWriteLine("Preparing your system:"); + terminalWriteString(" Preparing GDT..."); + //build and replce grub's GDT with a custom writable one. + gdt.build(); + gdt.load(); + terminalWriteLine(" Done!"); + terminalWriteString(" Preparing the page table..."); + //rebuild page table. replaces the one built in boot.s + pageTable.build(); + terminalWriteLine(" Done!"); + terminalWriteString(" Setting up interrupts..."); + //sets up interrups and enables them + interruptSetUp(); + terminalWriteLine(" Done!"); + terminalWriteString(" Preparing the memory allocator..."); + //get the memory map from grub + getMemMap(mbd); + //build the page frame allocator (allocate physical memory) + frameAlloc.build(); + //set malloc's support vars + mallocInit(); + terminalWriteLine(" Done!"); + terminalWriteString(" Finding PCI buses..."); + //find the valid PCI buses + PCIInit(); + terminalWriteLine(" Done!"); + terminalWriteString(" Finding USB host controllers..."); + //find the (3 or less) USB host controllers. all have the same class/subclass code. + PCIDeviceList usbHostControllers(0x0C, 0x03, false); + terminalWriteLine(" Done!"); + terminalWriteLine("!!!!ExOS fully booted!!!!"); + printf("Test printf %d %c\n", 42, 'B'); + printf("Newline is 0x%x%c", '\n', '\n'); + uint32_t i = (uint32_t) malloc(10); + printf("malloc returned 0x%x\n", i); + i = (uint32_t)malloc(100); + printf("malloc returned 0x%x\n", i); + i =(uint32_t) malloc(50); + printf("malloc returned 0x%x\n", i); + i = (uint32_t)malloc(1); + printf("malloc returned 0x%x\n", i); + printf("freeing 1 byte"); + free((void*)i); + i = (uint32_t)malloc(1); + printf("malloc returned 0x%x\n", i); +/* + for (int cx = 0; cx < 10; cx++) { + printf("%d", cx); + }*/ + //dont return. + while (true) { + asm("hlt"); } +} #if defined(__cplusplus) } #endif -void interruptSetUp( ) { +void interruptSetUp() +{ //build the IDT. - idt.build( ); + idt.build(); //set the interrupt lines for the PIC PICRemap(0x20, 0x28); //mask the timer line IRQSetMask(0); //load it to the CPU - idt.load( ); + idt.load(); //enable interupts asm("sti"); } From 8e4fd4a2db383d0d6d9ec119cad3f5b62d446e0c Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sat, 27 Jan 2018 13:52:21 -0600 Subject: [PATCH 052/171] malloc structure --- .bochsrc | 2 +- makefile | 2 +- makefile.inc | 2 +- src/memory/alloc/Malloc.c | 22 +++++++++++++++++++++- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/.bochsrc b/.bochsrc index 52d43442e..a8a3491b8 100644 --- a/.bochsrc +++ b/.bochsrc @@ -1,7 +1,7 @@ # configuration file generated by Bochs plugin_ctrl: unmapped=1, biosdev=1, speaker=1, extfpuirq=1, parallel=1, serial=1, iodebug=1 config_interface: textconfig -display_library: x, options="gui_debug" +#display_library: x, options="gui_debug" memory: host=32, guest=32 romimage: file="/usr/share/bochs/BIOS-bochs-latest", address=0x0, options=none vgaromimage: file="/usr/share/bochs/VGABIOS-lgpl-latest" diff --git a/makefile b/makefile index fae5c1fbe..0e3657726 100644 --- a/makefile +++ b/makefile @@ -5,7 +5,7 @@ SUBDIRS = src include makefile.inc kernel.bin: $(SUBDIRS) - @$(GCC) -T $(OS_CPP)/linker.ld -o $(BUILD_TO) -ffreestanding -O2 -fno-rtti -fno-exceptions -nostartfiles -nostdlib $(OBJ_DIR)/*.o -lgcc + @$(GCC) -T $(OS_CPP)/linker.ld -o $(BUILD_TO) -g -ffreestanding -O2 -fno-rtti -fno-exceptions -nostartfiles -nostdlib $(OBJ_DIR)/*.o -lgcc @sync clean: diff --git a/makefile.inc b/makefile.inc index d2e97930a..28cf4c5d3 100644 --- a/makefile.inc +++ b/makefile.inc @@ -3,7 +3,7 @@ GPP = i686-elf-g++ GCC = i686-elf-gcc OS_CPP = /Users/garrettbattaglia/Documents/dev/Exos/exos BUILD_TO = /Users/garrettbattaglia/Documents/dev/Exos/exos/kernel.bin -CFLAGS = -c -ffreestanding -O2 -Wall -Wextra -fno-rtti -fno-exceptions -std=gnu++14 -I$(OS_CPP)/src +CFLAGS = -c -ffreestanding -O2 -Wall -Wextra -fno-rtti -fno-exceptions -g -std=gnu++14 -I$(OS_CPP)/src OBJ_DIR = $(OS_CPP)/build %.o: %.c diff --git a/src/memory/alloc/Malloc.c b/src/memory/alloc/Malloc.c index 069d58f82..438f9b15c 100644 --- a/src/memory/alloc/Malloc.c +++ b/src/memory/alloc/Malloc.c @@ -39,7 +39,27 @@ extern "C" {/* Use C linkage for kernel_main. */ */ void *malloc(size_t size) { - size += sizeof(memHeader); + //TODO for loop + memHeaer* c = nullptr; + if(c->next == nullptr){ + if(c-top >= (size + sizeof(memHeader)) && !c->used){ + //TODO alloc + //TODO new header + //TODO return + } else { + //TODO new page frame + } + } else if(!c->used && (c->next - c) == size ){ + //TODO alloc + //TODO return + } else if (!c->used && (c->next - c) >= (size + sizeof(memHeader))){ + //TODO alloc + //TODO new header + //TODO return + } else { + //TODO continue + } + /*size += sizeof(memHeader); //size_t space = (size_t) top - (size_t) & kernelEnd; //if (space > size) { //have space From 760a2bce7dfe287ebcfc9a1e4d44842ac368c36f Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sat, 27 Jan 2018 14:04:59 -0600 Subject: [PATCH 053/171] forloop i forgot --- src/memory/alloc/Malloc.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/memory/alloc/Malloc.c b/src/memory/alloc/Malloc.c index 438f9b15c..388a5a388 100644 --- a/src/memory/alloc/Malloc.c +++ b/src/memory/alloc/Malloc.c @@ -40,25 +40,28 @@ extern "C" {/* Use C linkage for kernel_main. */ void *malloc(size_t size) { //TODO for loop - memHeaer* c = nullptr; - if(c->next == nullptr){ - if(c-top >= (size + sizeof(memHeader)) && !c->used){ + memHeaer* c = &kernelEnd; + for (; c != nullptr; c = c->next) { + if (c->next == nullptr) { + if (c - top >= (size + sizeof(memHeader)) && !c->used) { + //TODO alloc + //TODO new header + //TODO return + } else { + //TODO new page frame + } + } else if (!c->used && (c->next - c) == size) { + //TODO alloc + //TODO return + } else if (!c->used && (c->next - c) >= (size + sizeof(memHeader))) { //TODO alloc //TODO new header //TODO return } else { - //TODO new page frame + //TODO continue } - } else if(!c->used && (c->next - c) == size ){ - //TODO alloc - //TODO return - } else if (!c->used && (c->next - c) >= (size + sizeof(memHeader))){ - //TODO alloc - //TODO new header - //TODO return - } else { - //TODO continue } + /*size += sizeof(memHeader); //size_t space = (size_t) top - (size_t) & kernelEnd; //if (space > size) { From b21ec8952389fc4c0d4c7f17cf22d1178687ef32 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sat, 27 Jan 2018 14:46:42 -0600 Subject: [PATCH 054/171] that might acctually work --- src/memory/alloc/Malloc.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/memory/alloc/Malloc.c b/src/memory/alloc/Malloc.c index 388a5a388..4f5f9a4f1 100644 --- a/src/memory/alloc/Malloc.c +++ b/src/memory/alloc/Malloc.c @@ -40,28 +40,38 @@ extern "C" {/* Use C linkage for kernel_main. */ void *malloc(size_t size) { //TODO for loop - memHeaer* c = &kernelEnd; + memHeader* c = (memHeader*)&kernelEnd; for (; c != nullptr; c = c->next) { if (c->next == nullptr) { - if (c - top >= (size + sizeof(memHeader)) && !c->used) { - //TODO alloc - //TODO new header - //TODO return + if ((uint32_t)c - (uint32_t)top >= (size + sizeof(memHeader)) && !c->used) { + //TODO this may not work + memHeader* temp = (memHeader*)(((uint8_t*)(c+1)) + size); + temp->next = c->next; + temp->used = false; + c->next = temp; + c->used = true; + return c+1; } else { - //TODO new page frame + void* startOfNewMem = frameAlloc.allocatePhysMem(size,pageTable.getKernelStart()); + size_t sizeOfNewMem = ((size)/FOUR_KB + ( (size & 0xFFF) != 0)) * FOUR_KB; + top = (void*) ((size_t) top + sizeOfNewMem + ((size_t)startOfNewMem - (size_t)top) ); + return malloc(size); } } else if (!c->used && (c->next - c) == size) { - //TODO alloc - //TODO return + c->used = true; + return c+1; } else if (!c->used && (c->next - c) >= (size + sizeof(memHeader))) { - //TODO alloc - //TODO new header - //TODO return + memHeader* temp = (memHeader*)(((uint8_t*)(c+1)) + size); + temp->next = c->next; + temp->used = false; + c->next = temp; + c->used = true; + return c+1; } else { - //TODO continue + continue; } } - + /*size += sizeof(memHeader); //size_t space = (size_t) top - (size_t) & kernelEnd; //if (space > size) { From 27971d1edf7939768a1d19889baf2298eb5f19ce Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Fri, 2 Feb 2018 12:12:23 -0600 Subject: [PATCH 055/171] merge in (#39) * Changed the way includes are handled GCC now searches in $(OS_CPP)/src for the includes, so you can specify the directory directly (haha I'm funny, now laugh) instead of using realtive paths. Example: "Global.h" instead of "../../../Global.h" * fixed renames * Update README.MD * Update README.MD * Update README.MD * Update README.MD * Update README.MD * Update README.MD * Update CODE_OF_CONDUCT.md * Update CODE_OF_CONDUCT.md --- CODE_OF_CONDUCT.md | 3 +- README.MD | 81 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 59 insertions(+), 25 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index c74ca6104..cef8465c6 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -13,6 +13,7 @@ Examples of behavior that contributes to creating a positive environment include * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members +***Note that mild NSFW language is allowed*** Examples of unacceptable behavior by participants include: @@ -34,7 +35,7 @@ This Code of Conduct applies both within project spaces and in public spaces whe ## Enforcement -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at garrett@garrettbattaglia.info. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at exos@garrettbattaglia.info. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. diff --git a/README.MD b/README.MD index 099d45686..d89c7a66c 100755 --- a/README.MD +++ b/README.MD @@ -2,7 +2,7 @@ ExOS extends the [MIT exokernel](https://pdos.csail.mit.edu/archive/exo/) by removing the necessity to relink. Removing this process will allow consumers with no advanced computer knowledge better access to the OS. To achive this, the executable is scanned to identify system calls. Once they are identified, the native OS system calls are replaced with the appropriate ExOS userland system calls (from the LibOS). This replacement process is known as "live relinking". -***Before Working on ExOS, you should have a strong knoledge of the MIT Exokernel.*** +***Before Working on ExOS, you should have a strong knowledge of the MIT Exokernel.*** ## Goals @@ -13,32 +13,64 @@ ExOS extends the [MIT exokernel](https://pdos.csail.mit.edu/archive/exo/) by rem * Mac OS X * Live relinking to allow unmodified programs to be run -## Current Status +## Short term work +* Garrett + - [ ] Read USB spec - still going, its long + - [ ] USB abstract class + - [ ] OHCI driver + - [ ] UHCI driver + - [ ] EHCI driver + - [ ] XHCI driver + +* Oskari + - [ ] Floppy drive driver + +* Jacob + + - [ ] replace current PCI enum. strat. The new strat will get all devices at boot. When a device is requested it will be found in the list of devices. -I'm working with a friend on the PCI stuff. It is currently bugged and scanning returns no devices. I'm reading about the USB protocol and figuring out how I'm going to impliment it in the kernel. -### What's Left +* Ben + - [ ] Fat12 file system driver + +## Long term work +* Load files from floppy drives +* Some basic file systems support +* libC + * probably from NewLib +* Decide on a format for the libOS +* live relinking or something +* Linux libOS +* Windows libOS + * Possibly based on [ReactOS](https://www.reactos.org/) +* Mac OS X libOS -* ~~Bus enumeration~~ -* Device scanning (it may not work. atleast my test code found 0 devices. this needs to be worked on) -* ~~PCI Config space reading~~ (i can read the important one, header 0 for standard devices. could extend to more) +## Major systems to support +- [ ] PCI +- [ ] PCI Express +- [ ] USB +- [ ] Text Graphics +- [ ] Regular Graphics +- [ ] Sound +- [ ] Ethernet +- [ ] WIFi +- [ ] SATA +- [ ] IDE +- [ ] SCSI (maybe probably) +- [ ] SAS +- [ ] M.2 -## Next Steps +## Helping out -* libc (maybe later) (newlib is hard) -* libc++ (maybe later) (needs libc and an os toolchain) -* PCI support (~~waiting for libc(++)~~) (I dont need those so were back to this) -* primitive USB support -* floppy support -* Loading and running programs from disk -* SATA HDD support -* IDE HDD support -* LibOS format -* Live relinking -* Linux LibOS -* Multitasking -* Windows LibOS - * Possibly based on [ReactOS's](https://www.reactos.org/) code -* Mac OS X LibOS +### Contacting us +* [slack](https://join.slack.com/t/exos-dev/shared_invite/enQtMjI2OTE2NjYzOTU4LTJhZTIyOTNkYmY2MjcxN2RjZTUzZjhkYTAzZTNlOThkODZkZmE5ODI3ODA0MjBlNDY3Mjg3OWNjODQ0ZGM3NDU) +* Email + * Garrett: exos@garrettbattaglia.info + * Oskari: Coming soon + +### But, what can ***I*** do??? +The best thing you can do is write code. If you know a system like the ones listed above, write a driver for it. If there's a bug that catches your fancy try and patch it. + +If you can't code theres still stuff for you. If you can write our readme or wiki might intrest you. You can run this and test it out. If you have an issue open a bug. ## Building @@ -53,7 +85,8 @@ I'm working with a friend on the PCI stuff. It is currently bugged and scanning * You can also use an emulator such as [Bochs](http://wiki.osdev.org/Bochs) or [QEMU](http://wiki.osdev.org/Qemu) to boot from a disk image. * If you're contributing ***please test on real hardware*** not just an emulator. 3. Set up a ***multiboot compliant*** bootloader - * I'm using [grub legacy](http://wiki.osdev.org/GRUB_Legacy) as my bootloader but you can use whatever as long as it's ***multiboot compliant***. + * I'm using [grub legacy](http://wiki.osdev.org/GRUB_Legacy) as my bootloader but you can use whatever as long as it's ***multiboot compliant***. + * I'm not 100% sure that all of them work the more i look into it. I will try grub and see. 4. Test the bootloader installation * Just boot to the bootloader's menu screen to make sure it works. 5. Configure the makefile (makefile.inc) From af46c1b418b090975ce50b388c8798abd988b66c Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sat, 3 Feb 2018 22:16:34 -0600 Subject: [PATCH 056/171] basic parsing structure --- makefile.inc | 11 +++-------- src/drivers/filesys/fat/fat12/Fat12FS.cpp | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/makefile.inc b/makefile.inc index 0fe6bf524..7341ecd00 100644 --- a/makefile.inc +++ b/makefile.inc @@ -1,15 +1,10 @@ AS = i686-elf-as GPP = i686-elf-g++ GCC = i686-elf-gcc -<<<<<<< HEAD -OS_CPP = /Users/garrettbattaglia/Documents/dev/Exos/exos -BUILD_TO = /Users/garrettbattaglia/Documents/dev/Exos/exos/kernel.bin -CFLAGS = -c -ffreestanding -O2 -Wall -Wextra -fno-rtti -fno-exceptions -g -std=gnu++14 -I$(OS_CPP)/src -======= -OS_CPP = /home/garrett/workspace/ExOS +OS_CPP = /home/garrett/workspace/exos BUILD_TO = /run/media/garrett/disk/boot/kernel.bin -CFLAGS = -c -ffreestanding -O2 -Wall -Wextra -fno-rtti -fno-exceptions -std=gnu++14 -I$(OS_CPP)/src ->>>>>>> 1181f6b0ac1a30b438dc1b712c846b12dfcb50ab +CFLAGS = -c -ffreestanding -O2 -Wall -Wextra -fno-rtti -fno-exceptions -g -std=gnu++14 -I$(OS_CPP)/src + OBJ_DIR = $(OS_CPP)/build %.o: %.c diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.cpp b/src/drivers/filesys/fat/fat12/Fat12FS.cpp index 6567208cf..8928bce1b 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12FS.cpp @@ -42,10 +42,23 @@ void Fat12FS::buildDirStructure( ) { + (_FSInfo->dirEntryCount % _FSInfo->bytePerSec != 0); for (size_t i = 0; i < rootDirSize; i++) { //_device->read(startSectot+i, tempCluster) + if(tempSector[0] == 0){ + break; + } parseEntry(tempSector); } } void Fat12FS::parseEntry(uint8_t* sector){ - + if(sector[0] == 0xE5){ + return; + } + if (sector[10] == 0x0F){ + //long file name + } else { + //normal file name + if(false /*have long file name stored*/){ + //end of name, add name to entry we just read + } + } } From 03add340f3ae63c79f94300a53c118fc1a5e533b Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sat, 3 Feb 2018 22:38:04 -0600 Subject: [PATCH 057/171] standard 8.3 filename structs --- src/drivers/filesys/fat/FatStructs.h | 31 +++++++++++++++++++++++++ src/drivers/filesys/fat/fat12/Fat12FS.h | 1 + 2 files changed, 32 insertions(+) diff --git a/src/drivers/filesys/fat/FatStructs.h b/src/drivers/filesys/fat/FatStructs.h index 60747a6ce..23bde102b 100644 --- a/src/drivers/filesys/fat/FatStructs.h +++ b/src/drivers/filesys/fat/FatStructs.h @@ -7,6 +7,18 @@ #include "Global.h" +struct FatTime{ + uint8_t hour:5; + uint8_t min:6; + uint8_t second:5; +}; + +struct FatDay{ + uint8_t year:7; + uint8_t month:4; + uint8_t day:5; +}; + struct FatBPB{ uint8_t jmp[3]; uint8_t oemIdent[8]; @@ -24,4 +36,23 @@ struct FatBPB{ uint32_t largeSecCount; }; +struct FatNormalFileName { + uint8_t name[11]; + uint8_t attribute; + uint8_t reserved; + uint8_t creationTimeMS; + FatTime createTime; + FatDay createDay; + FatDay latsAccessedDay; + uint16_t highClusterNumber; + FatTime modTime; + FatDay modDay; + uint16_t lowClusterNumber; + uint32_t size; +}; + +struct FatLongFileName { + +}; + #endif //EXOS_FATSTRUCTS_H diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.h b/src/drivers/filesys/fat/fat12/Fat12FS.h index cc4ce6b44..1e2fba4e5 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.h +++ b/src/drivers/filesys/fat/fat12/Fat12FS.h @@ -14,6 +14,7 @@ class Fat12File; class Fat12FS : public FS{ private: FatBPB* _FSInfo; + char* _tempLongName; public: File *open(char *path, int flags, int mode); From fcf6b2a0d6a5113022268827184bc3fd7d7156bb Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sat, 3 Feb 2018 22:45:31 -0600 Subject: [PATCH 058/171] long file name struct --- src/drivers/filesys/fat/FatStructs.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/drivers/filesys/fat/FatStructs.h b/src/drivers/filesys/fat/FatStructs.h index 23bde102b..9aa7f84e0 100644 --- a/src/drivers/filesys/fat/FatStructs.h +++ b/src/drivers/filesys/fat/FatStructs.h @@ -52,7 +52,14 @@ struct FatNormalFileName { }; struct FatLongFileName { - + uint8_t order; + uint16_t nameFirst[5]; + uint8_t attribute; + uint8_t type; + uint8_t checksum; + uint16_t nameMid[5]; + uint16_t zero; + uint16_t nameEnd[2]; }; #endif //EXOS_FATSTRUCTS_H From 741f7874df9ba7de274e9591db43262265d214fe Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sat, 3 Feb 2018 22:46:57 -0600 Subject: [PATCH 059/171] forgot to pack structs --- src/drivers/filesys/fat/FatStructs.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/drivers/filesys/fat/FatStructs.h b/src/drivers/filesys/fat/FatStructs.h index 9aa7f84e0..e3b6f854c 100644 --- a/src/drivers/filesys/fat/FatStructs.h +++ b/src/drivers/filesys/fat/FatStructs.h @@ -11,13 +11,13 @@ struct FatTime{ uint8_t hour:5; uint8_t min:6; uint8_t second:5; -}; +} __attribute__((__packed__)); struct FatDay{ uint8_t year:7; uint8_t month:4; uint8_t day:5; -}; +}__attribute__((__packed__)); struct FatBPB{ uint8_t jmp[3]; @@ -34,7 +34,7 @@ struct FatBPB{ uint16_t heads; uint32_t hiddenSec; uint32_t largeSecCount; -}; +}__attribute__((__packed__)); struct FatNormalFileName { uint8_t name[11]; @@ -49,7 +49,7 @@ struct FatNormalFileName { FatDay modDay; uint16_t lowClusterNumber; uint32_t size; -}; +}__attribute__((__packed__)); struct FatLongFileName { uint8_t order; @@ -60,6 +60,6 @@ struct FatLongFileName { uint16_t nameMid[5]; uint16_t zero; uint16_t nameEnd[2]; -}; +}__attribute__((__packed__)); #endif //EXOS_FATSTRUCTS_H From b838ef9a13eb2d69d12094aa069b3414936b7b8e Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sat, 3 Feb 2018 22:54:59 -0600 Subject: [PATCH 060/171] pointer incrimentor --- src/drivers/filesys/fat/fat12/Fat12FS.cpp | 16 +++++++++++++--- src/drivers/filesys/fat/fat12/Fat12FS.h | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.cpp b/src/drivers/filesys/fat/fat12/Fat12FS.cpp index 8928bce1b..f6d2e19e3 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12FS.cpp @@ -35,17 +35,27 @@ bool Fat12FS::readCluster(uint16_t cluster, void* fileLoc, size_t fileLocSize) { void Fat12FS::buildDirStructure( ) { _root = new Fat12FSNode( ); uint8_t* tempSector = (uint8_t*) malloc(_FSInfo->bytePerSec); + uint8_t sectorOffset = 0; uint16_t startSector = (_FSInfo->resSec) + (_FSInfo->FATs * _FSInfo->secPerFAT); uint16_t rootDirSize = (float) _FSInfo->dirEntryCount / (float) _FSInfo->bytePerSec + (_FSInfo->dirEntryCount % _FSInfo->bytePerSec != 0); + //_device->read(startSector+i, tempCluster) + //TODO there may be an issue if the size of a sector != a mult of the size of an entry... we will deal with that latter for (size_t i = 0; i < rootDirSize; i++) { - //_device->read(startSectot+i, tempCluster) - if(tempSector[0] == 0){ + if(tempSector[sectorOffset] == 0){ break; } - parseEntry(tempSector); + parseEntry(tempSector + sectorOffset); + if (_tempLongName == nullptr){ + sectorOffset += sizeof(FatNormalFileName); + } else { + sectorOffset += sizeof(FatLongFileName); + } + if (sectorOffset >= _FSInfo->bytePerSec){ + //_device->read(startSectot+i, tempCluster) + } } } diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.h b/src/drivers/filesys/fat/fat12/Fat12FS.h index 1e2fba4e5..fb8d79107 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.h +++ b/src/drivers/filesys/fat/fat12/Fat12FS.h @@ -14,7 +14,7 @@ class Fat12File; class Fat12FS : public FS{ private: FatBPB* _FSInfo; - char* _tempLongName; + char* _tempLongName = nullptr; public: File *open(char *path, int flags, int mode); From 1452642297f48ec7c152017f836804085fdf1c70 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sun, 4 Feb 2018 09:32:08 -0600 Subject: [PATCH 061/171] read long file name --- src/Global.h | 1 + src/drivers/TTY/Console.h | 10 +++++++++- src/drivers/filesys/fat/fat12/Fat12FS.cpp | 11 ++++++++++- src/memory/alloc/Malloc.h | 2 ++ 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/Global.h b/src/Global.h index 7c8f20a8e..4a7479f55 100755 --- a/src/Global.h +++ b/src/Global.h @@ -19,6 +19,7 @@ #include "memory/alloc/New.h" #include "clib_misc/Abort.h" #include "clib_misc/Assert.h" +#include "memory/Mem.h" //bochs breakpoing ASM #define BREAKPOINT asm("xchgw %%bx, %%bx" : : : "%bx"); diff --git a/src/drivers/TTY/Console.h b/src/drivers/TTY/Console.h index 066a37ec0..fb65ca851 100644 --- a/src/drivers/TTY/Console.h +++ b/src/drivers/TTY/Console.h @@ -93,7 +93,13 @@ void terminalWrite(const char* data, size_t size); * @param string * @return length */ -size_t stringLength(const char* str); +#if defined(__cplusplus) +extern "C" {/* Use C linkage for kernel_main. */ +#endif +size_t strlen(const char* str); +#if defined(__cplusplus) +} +#endif /** * Print string of unknown length * @param string to print @@ -133,4 +139,6 @@ void writeInt(uint64_t num); */ void writeIntBase(uint64_t num, uint64_t base); + + #endif /* CONSOLE_H_ */ diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.cpp b/src/drivers/filesys/fat/fat12/Fat12FS.cpp index f6d2e19e3..fbe504ee1 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12FS.cpp @@ -5,6 +5,7 @@ #include "Fat12FS.h" #include "Fat12File.h" #include "Fat12FSNode.h" +#include "drivers/TTY/Console.h" File *Fat12FS::open(char *path, int flags, int mode) { //TODO find file @@ -64,7 +65,15 @@ void Fat12FS::parseEntry(uint8_t* sector){ return; } if (sector[10] == 0x0F){ - //long file name + //i belive this wont overrun and will end with a null in the right spot. also i hope this doesnt add a null somewhere + FatLongFileName* entry = (FatLongFileName*)sector; + uint32_t tempLeng = strlen(_tempLongName); + _tempLongName = (char*) realloc(_tempLongName, tempLeng + 10+10+4); + memcpy(_tempLongName+tempLeng, &entry->nameFirst, 10); + memcpy(_tempLongName+tempLeng +10, &entry->nameMid, 10); + memcpy(_tempLongName+tempLeng+10+10, &entry->nameEnd, 4); + _tempLongName[tempLeng+10+10+4+1] = '\0'; + } else { //normal file name if(false /*have long file name stored*/){ diff --git a/src/memory/alloc/Malloc.h b/src/memory/alloc/Malloc.h index 6b6a3ee58..e1065a165 100644 --- a/src/memory/alloc/Malloc.h +++ b/src/memory/alloc/Malloc.h @@ -46,4 +46,6 @@ void free(void *ptr); void compFreeSpace(); +void *realloc(void *ptr, size_t size); + #endif /* MALLOC_H_ */ From 2827f0f1f45205d616db911d8e77869f27c94137 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sun, 4 Feb 2018 11:07:07 -0600 Subject: [PATCH 062/171] create entry in the dag --- src/drivers/filesys/fat/fat12/Fat12FS.cpp | 13 +++++++++++-- src/drivers/filesys/fat/fat12/Fat12FSNode.cpp | 10 +--------- src/drivers/filesys/fat/fat12/Fat12FSNode.h | 6 ++++++ 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.cpp b/src/drivers/filesys/fat/fat12/Fat12FS.cpp index fbe504ee1..60d9ab545 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12FS.cpp @@ -75,9 +75,18 @@ void Fat12FS::parseEntry(uint8_t* sector){ _tempLongName[tempLeng+10+10+4+1] = '\0'; } else { - //normal file name + FatNormalFileName* entry = (FatNormalFileName*) sector; + Type type = (entry->attribute && 0x10) != 0 ? DIR : FILE; + char* name = nullptr; if(false /*have long file name stored*/){ - //end of name, add name to entry we just read + name = (char*) malloc(strlen(_tempLongName) * sizeof(uint16_t)); + memcpy(name, _tempLongName, strlen(_tempLongName)*2); + } else { + name = (char*) malloc(strlen((char*)entry->name) * sizeof(uint8_t)); + memcpy(name, entry->name, strlen((char*)entry->name)); } + uint32_t size = entry->size; + uint32_t cluster = entry->lowClusterNumber; + Fat12FSNode* tmp = new Fat12FSNode(name, size, type, cluster); } } diff --git a/src/drivers/filesys/fat/fat12/Fat12FSNode.cpp b/src/drivers/filesys/fat/fat12/Fat12FSNode.cpp index aabb27546..5704e3587 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FSNode.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12FSNode.cpp @@ -5,12 +5,4 @@ * Author: garrett */ -Fat12FSNode::Fat12FSNode( ) { - // TODO Auto-generated constructor stub - -} - -Fat12FSNode::~Fat12FSNode( ) { - // TODO Auto-generated destructor stub -} - +#include "Fat12FSNode.h" \ No newline at end of file diff --git a/src/drivers/filesys/fat/fat12/Fat12FSNode.h b/src/drivers/filesys/fat/fat12/Fat12FSNode.h index 6089c26f6..1de86ce95 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FSNode.h +++ b/src/drivers/filesys/fat/fat12/Fat12FSNode.h @@ -13,6 +13,12 @@ class Fat12FSNode: public FSNode { private: uint32_t startCluster; public: + Fat12FSNode(char* name, uint32_t size, Type type, uint32_t cluster):FSNode(name,size,type), startCluster(cluster){ + + } + Fat12FSNode():FSNode(){ + + } virtual uint32_t startSector(){ } From 38fdf6395efae1310f4fd89522d5e21943351ba4 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sun, 4 Feb 2018 11:29:15 -0600 Subject: [PATCH 063/171] add entry to the dag --- src/drivers/filesys/fat/fat12/Fat12FS.cpp | 14 +++++++++----- src/drivers/filesys/fat/fat12/Fat12FS.h | 3 ++- src/drivers/filesys/general/FSNode.h | 4 ++++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.cpp b/src/drivers/filesys/fat/fat12/Fat12FS.cpp index 60d9ab545..1b1da4d4a 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12FS.cpp @@ -48,21 +48,24 @@ void Fat12FS::buildDirStructure( ) { if(tempSector[sectorOffset] == 0){ break; } - parseEntry(tempSector + sectorOffset); + Fat12FSNode* ret = parseEntry(tempSector + sectorOffset); if (_tempLongName == nullptr){ sectorOffset += sizeof(FatNormalFileName); } else { sectorOffset += sizeof(FatLongFileName); } + if(ret != nullptr){ + _root->add(ret); + } if (sectorOffset >= _FSInfo->bytePerSec){ //_device->read(startSectot+i, tempCluster) } } } -void Fat12FS::parseEntry(uint8_t* sector){ +Fat12FSNode* Fat12FS::parseEntry(uint8_t* sector){ if(sector[0] == 0xE5){ - return; + return nullptr; } if (sector[10] == 0x0F){ //i belive this wont overrun and will end with a null in the right spot. also i hope this doesnt add a null somewhere @@ -73,7 +76,7 @@ void Fat12FS::parseEntry(uint8_t* sector){ memcpy(_tempLongName+tempLeng +10, &entry->nameMid, 10); memcpy(_tempLongName+tempLeng+10+10, &entry->nameEnd, 4); _tempLongName[tempLeng+10+10+4+1] = '\0'; - + return nullptr; } else { FatNormalFileName* entry = (FatNormalFileName*) sector; Type type = (entry->attribute && 0x10) != 0 ? DIR : FILE; @@ -87,6 +90,7 @@ void Fat12FS::parseEntry(uint8_t* sector){ } uint32_t size = entry->size; uint32_t cluster = entry->lowClusterNumber; - Fat12FSNode* tmp = new Fat12FSNode(name, size, type, cluster); + return new Fat12FSNode(name, size, type, cluster); + } } diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.h b/src/drivers/filesys/fat/fat12/Fat12FS.h index fb8d79107..e2332dd22 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.h +++ b/src/drivers/filesys/fat/fat12/Fat12FS.h @@ -8,6 +8,7 @@ #include "drivers/filesys/fat/FatStructs.h" #include "Global.h" #include "drivers/filesys/general/FS.h" +#include "Fat12FSNode.h" class Fat12File; @@ -23,7 +24,7 @@ class Fat12FS : public FS{ } bool readCluster(uint16_t cluser, void* fileLoc, size_t fileLocSize); void buildDirStructure(); - void parseEntry(uint8_t* sector); + Fat12FSNode* parseEntry(uint8_t* sector); }; #endif //EXOS_FAT12_H diff --git a/src/drivers/filesys/general/FSNode.h b/src/drivers/filesys/general/FSNode.h index d1d172432..83882336b 100644 --- a/src/drivers/filesys/general/FSNode.h +++ b/src/drivers/filesys/general/FSNode.h @@ -31,6 +31,10 @@ class FSNode{ _children = nullptr; _childernCount = 0; } + void add(FSNode* toAdd){ + _children = (FSNode**) realloc(_children, sizeof(FSNode*) * (++_childernCount)); + _children[_childernCount-1] = toAdd; + } virtual uint32_t startSector() = 0; //Permissions permissons(); }; From 1f4992d81e31ac1d10ef8248ce7db2f195f5de94 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sun, 4 Feb 2018 12:02:34 -0600 Subject: [PATCH 064/171] better add algro I hope my conversion works --- src/drivers/filesys/fat/fat12/Fat12FS.cpp | 37 +++++++++++++++++++++-- src/drivers/filesys/fat/fat12/Fat12FS.h | 1 + src/drivers/filesys/general/FSNode.h | 9 ++++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.cpp b/src/drivers/filesys/fat/fat12/Fat12FS.cpp index 1b1da4d4a..4eaa258d5 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12FS.cpp @@ -34,8 +34,9 @@ bool Fat12FS::readCluster(uint16_t cluster, void* fileLoc, size_t fileLocSize) { } //TODO check var sizes void Fat12FS::buildDirStructure( ) { - _root = new Fat12FSNode( ); - uint8_t* tempSector = (uint8_t*) malloc(_FSInfo->bytePerSec); + //This conversion may not work correctly... oh well + _root = new Fat12FSNode("Root", 0, DIR, ( (_FSInfo->resSec) + (_FSInfo->FATs * _FSInfo->secPerFAT) )/_FSInfo->secPerCluster); + /*uint8_t* tempSector = (uint8_t*) malloc(_FSInfo->bytePerSec); uint8_t sectorOffset = 0; uint16_t startSector = (_FSInfo->resSec) + (_FSInfo->FATs * _FSInfo->secPerFAT); @@ -56,11 +57,43 @@ void Fat12FS::buildDirStructure( ) { } if(ret != nullptr){ _root->add(ret); + if(ret->type() == DIR){ + buildTree(ret); + } } if (sectorOffset >= _FSInfo->bytePerSec){ //_device->read(startSectot+i, tempCluster) } + }*/ + buildTree((Fat12FSNode*)_root); +} + +void Fat12FS::buildTree(Fat12FSNode* dir){ + uint8_t* tempSector = (uint8_t*) malloc(_FSInfo->bytePerSec); + size_t offset = 0; + while(tempSector[offset] != 0){ + Fat12FSNode* ret = parseEntry(tempSector + offset); + if (_tempLongName == nullptr){ + offset += sizeof(FatNormalFileName); + } else { + offset += sizeof(FatLongFileName); + } + if(ret != nullptr){ + _root->add(ret); + if(ret->type() == DIR){ + buildTree(ret); + } + } + if (offset >= _FSInfo->bytePerSec){ + //_device->read(startSectot+i, tempCluster) + } } + /*for (size_t i =0; ichildernCount() ; i++){ + if(root->children()[i]->type() == DIR){ + //TODO add + } + }*/ + free(tempSector); } Fat12FSNode* Fat12FS::parseEntry(uint8_t* sector){ diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.h b/src/drivers/filesys/fat/fat12/Fat12FS.h index e2332dd22..64f1d6a5f 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.h +++ b/src/drivers/filesys/fat/fat12/Fat12FS.h @@ -25,6 +25,7 @@ class Fat12FS : public FS{ bool readCluster(uint16_t cluser, void* fileLoc, size_t fileLocSize); void buildDirStructure(); Fat12FSNode* parseEntry(uint8_t* sector); + void buildTree(Fat12FSNode* root); }; #endif //EXOS_FAT12_H diff --git a/src/drivers/filesys/general/FSNode.h b/src/drivers/filesys/general/FSNode.h index 83882336b..a17b2bee2 100644 --- a/src/drivers/filesys/general/FSNode.h +++ b/src/drivers/filesys/general/FSNode.h @@ -35,6 +35,15 @@ class FSNode{ _children = (FSNode**) realloc(_children, sizeof(FSNode*) * (++_childernCount)); _children[_childernCount-1] = toAdd; } + size_t childernCount(){ + return _childernCount; + } + FSNode** children(){ + return _children; + } + Type type(){ + return _type; + } virtual uint32_t startSector() = 0; //Permissions permissons(); }; From d6b4b1e8971b1426e5f923686f54289854c0a47a Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sun, 4 Feb 2018 13:02:58 -0600 Subject: [PATCH 065/171] find file and open it also some stdlib work and refactoring --- src/Global.h | 2 ++ src/drivers/TTY/Console.cpp | 17 ----------------- src/drivers/TTY/Console.h | 13 +------------ src/drivers/filesys/fat/fat12/Fat12FS.cpp | 18 +++++++++++++++--- src/drivers/filesys/fat/fat12/Fat12FS.h | 1 + src/drivers/filesys/fat/fat12/Fat12FSNode.h | 7 +++++-- src/drivers/filesys/general/FSNode.h | 3 +++ src/utils/makefile | 2 +- src/utils/string/Split.cpp | 21 +++++++++++++++++++++ src/utils/string/Split.h | 3 +++ src/utils/string/StrCmp.cpp | 11 +++++++++++ src/utils/string/StrCmp.h | 3 +++ src/utils/string/StrLen.cpp | 19 +++++++++++++++++++ src/utils/string/StrLen.h | 10 ++++++++++ src/utils/string/makefile | 5 +++++ 15 files changed, 100 insertions(+), 35 deletions(-) create mode 100644 src/utils/string/Split.cpp create mode 100644 src/utils/string/Split.h create mode 100644 src/utils/string/StrCmp.cpp create mode 100644 src/utils/string/StrCmp.h create mode 100644 src/utils/string/StrLen.cpp create mode 100644 src/utils/string/StrLen.h create mode 100644 src/utils/string/makefile diff --git a/src/Global.h b/src/Global.h index 4a7479f55..73462221c 100755 --- a/src/Global.h +++ b/src/Global.h @@ -20,6 +20,8 @@ #include "clib_misc/Abort.h" #include "clib_misc/Assert.h" #include "memory/Mem.h" +#include "utils/string/StrCmp.h" +#include "utils/string/StrLen.h" //bochs breakpoing ASM #define BREAKPOINT asm("xchgw %%bx, %%bx" : : : "%bx"); diff --git a/src/drivers/TTY/Console.cpp b/src/drivers/TTY/Console.cpp index ed6809b54..9316e7770 100644 --- a/src/drivers/TTY/Console.cpp +++ b/src/drivers/TTY/Console.cpp @@ -103,23 +103,6 @@ void terminalWrite(const char* _toPrint, size_t _length) { terminalPutChar(_toPrint[_i]); } -#if defined(__cplusplus) -extern "C" {/* Use C linkage for kernel_main. */ -#endif -/** - * Get string length - * @param string - * @return length - */ -size_t strlen(const char* str) { - size_t _length = 0; - while (str[_length]) - _length++; - return _length; -} -#if defined(__cplusplus) -}/* Use C linkage for kernel_main. */ -#endif /** * Print string of unknown length diff --git a/src/drivers/TTY/Console.h b/src/drivers/TTY/Console.h index fb65ca851..1a913ae74 100644 --- a/src/drivers/TTY/Console.h +++ b/src/drivers/TTY/Console.h @@ -88,18 +88,7 @@ void terminalPutChar(char c); * @param length */ void terminalWrite(const char* data, size_t size); -/** - * Get string length - * @param string - * @return length - */ -#if defined(__cplusplus) -extern "C" {/* Use C linkage for kernel_main. */ -#endif -size_t strlen(const char* str); -#if defined(__cplusplus) -} -#endif + /** * Print string of unknown length * @param string to print diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.cpp b/src/drivers/filesys/fat/fat12/Fat12FS.cpp index 4eaa258d5..6f77f5e7d 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12FS.cpp @@ -5,14 +5,26 @@ #include "Fat12FS.h" #include "Fat12File.h" #include "Fat12FSNode.h" -#include "drivers/TTY/Console.h" +#include "utils/string/Split.h" File *Fat12FS::open(char *path, int flags, int mode) { - //TODO find file - Fat12File *ret = new Fat12File(0); + Fat12FSNode* file = find(path,(Fat12FSNode*)_root ); + Fat12File *ret = new Fat12File(file->startCluster()); return ret; } +Fat12FSNode* Fat12FS::find(char* path, Fat12FSNode* root){ + char** split = strSplit(path, '/'); + if (split == nullptr){ + return root; + } + for (int i=0; i< root->childernCount(); i++){ + if (strcmp(root->children()[i]->name(), split[0]) == 0){ + return find(split[1], (Fat12FSNode*)root->children()[i]); + } + } +} + //todo names, var sizes, structure taken from osdev wiki bool Fat12FS::readCluster(uint16_t cluster, void* fileLoc, size_t fileLocSize) { assert(fileLocSize >= (_FSInfo->secPerCluster * _FSInfo->bytePerSec)); diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.h b/src/drivers/filesys/fat/fat12/Fat12FS.h index 64f1d6a5f..902bad643 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.h +++ b/src/drivers/filesys/fat/fat12/Fat12FS.h @@ -26,6 +26,7 @@ class Fat12FS : public FS{ void buildDirStructure(); Fat12FSNode* parseEntry(uint8_t* sector); void buildTree(Fat12FSNode* root); + Fat12FSNode* find(char* path, Fat12FSNode* root); }; #endif //EXOS_FAT12_H diff --git a/src/drivers/filesys/fat/fat12/Fat12FSNode.h b/src/drivers/filesys/fat/fat12/Fat12FSNode.h index 1de86ce95..53da8aa07 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FSNode.h +++ b/src/drivers/filesys/fat/fat12/Fat12FSNode.h @@ -11,9 +11,9 @@ class Fat12FSNode: public FSNode { private: - uint32_t startCluster; + uint32_t _startCluster; public: - Fat12FSNode(char* name, uint32_t size, Type type, uint32_t cluster):FSNode(name,size,type), startCluster(cluster){ + Fat12FSNode(char* name, uint32_t size, Type type, uint32_t cluster):FSNode(name,size,type), _startCluster(cluster){ } Fat12FSNode():FSNode(){ @@ -25,6 +25,9 @@ class Fat12FSNode: public FSNode { virtual ~Fat12FSNode( ){ } + uint32_t startCluster(){ + return _startCluster; + } }; #endif /* SRC_DRIVERS_FILESYS_FAT_FAT12_FAT12FSNODE_H_ */ diff --git a/src/drivers/filesys/general/FSNode.h b/src/drivers/filesys/general/FSNode.h index a17b2bee2..6e2242b63 100644 --- a/src/drivers/filesys/general/FSNode.h +++ b/src/drivers/filesys/general/FSNode.h @@ -44,6 +44,9 @@ class FSNode{ Type type(){ return _type; } + char* name(){ + return _name; + } virtual uint32_t startSector() = 0; //Permissions permissons(); }; diff --git a/src/utils/makefile b/src/utils/makefile index 542466463..661e122ca 100644 --- a/src/utils/makefile +++ b/src/utils/makefile @@ -1,4 +1,4 @@ -SUBDIRS = linked_list printf +SUBDIRS = linked_list printf string OBS = include ../../makefile.inc diff --git a/src/utils/string/Split.cpp b/src/utils/string/Split.cpp new file mode 100644 index 000000000..a2912926e --- /dev/null +++ b/src/utils/string/Split.cpp @@ -0,0 +1,21 @@ +#include "Split.h" + +//This looks like it works but it might not +char **strSplit(char *to_split, char delim) +{ + int spl_ind = -1; + for (int i = 0; i < strlen(to_split); i++) { + if (to_split[i] == delim) { + spl_ind = i; + break; + } + } + if (spl_ind == -1) { + return nullptr; + } + char **ret = (char**) malloc(2* sizeof(char *)); + ret[0] = to_split; + ret[0][spl_ind] = '\0'; + ret[1] = to_split + spl_ind + 1; + return ret; +} \ No newline at end of file diff --git a/src/utils/string/Split.h b/src/utils/string/Split.h new file mode 100644 index 000000000..30602e620 --- /dev/null +++ b/src/utils/string/Split.h @@ -0,0 +1,3 @@ +#include "Global.h" + +char **strSplit(char *to_split, char delim); \ No newline at end of file diff --git a/src/utils/string/StrCmp.cpp b/src/utils/string/StrCmp.cpp new file mode 100644 index 000000000..fa53a7dd9 --- /dev/null +++ b/src/utils/string/StrCmp.cpp @@ -0,0 +1,11 @@ +#include "StrCmp.h" + +int strcmp(char* str1, char* str2){ + size_t i; + for(i = 0; i Date: Sun, 4 Feb 2018 15:24:02 -0600 Subject: [PATCH 066/171] basic device class --- src/drivers/Device.cpp | 16 ++++++++++++++++ src/drivers/Device.h | 1 + 2 files changed, 17 insertions(+) create mode 100644 src/drivers/Device.cpp create mode 100644 src/drivers/Device.h diff --git a/src/drivers/Device.cpp b/src/drivers/Device.cpp new file mode 100644 index 000000000..b59f8903b --- /dev/null +++ b/src/drivers/Device.cpp @@ -0,0 +1,16 @@ +#include "Device.h" + +class Device +{ + private: + uint32_t _Id; + + public: + Device():_Id(++lastDeviceId){ + + } +} + +Device *deviceList; + +uint32_t lastDeviceId; \ No newline at end of file diff --git a/src/drivers/Device.h b/src/drivers/Device.h new file mode 100644 index 000000000..61e8f7a5b --- /dev/null +++ b/src/drivers/Device.h @@ -0,0 +1 @@ +#include "Global.h" \ No newline at end of file From c8c5a4aec029c7b70b520df49b4eddbe83336c9f Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sun, 4 Feb 2018 15:27:05 -0600 Subject: [PATCH 067/171] im really dumb --- src/drivers/Device.h | 1 - src/drivers/generic/Device.cpp | 2 ++ src/drivers/{Device.cpp => generic/Device.h} | 14 +++++++++----- src/drivers/generic/makefile | 4 ++++ src/drivers/makefile | 2 +- 5 files changed, 16 insertions(+), 7 deletions(-) delete mode 100644 src/drivers/Device.h create mode 100644 src/drivers/generic/Device.cpp rename src/drivers/{Device.cpp => generic/Device.h} (55%) create mode 100644 src/drivers/generic/makefile diff --git a/src/drivers/Device.h b/src/drivers/Device.h deleted file mode 100644 index 61e8f7a5b..000000000 --- a/src/drivers/Device.h +++ /dev/null @@ -1 +0,0 @@ -#include "Global.h" \ No newline at end of file diff --git a/src/drivers/generic/Device.cpp b/src/drivers/generic/Device.cpp new file mode 100644 index 000000000..68ed99d62 --- /dev/null +++ b/src/drivers/generic/Device.cpp @@ -0,0 +1,2 @@ +#include "Device.h" + diff --git a/src/drivers/Device.cpp b/src/drivers/generic/Device.h similarity index 55% rename from src/drivers/Device.cpp rename to src/drivers/generic/Device.h index b59f8903b..6d8e0a00e 100644 --- a/src/drivers/Device.cpp +++ b/src/drivers/generic/Device.h @@ -1,4 +1,10 @@ -#include "Device.h" +#include "Global.h" + + + + +uint32_t lastDeviceId; + class Device { @@ -9,8 +15,6 @@ class Device Device():_Id(++lastDeviceId){ } -} - -Device *deviceList; +}; -uint32_t lastDeviceId; \ No newline at end of file +Device* deviceList = nullptr; \ No newline at end of file diff --git a/src/drivers/generic/makefile b/src/drivers/generic/makefile new file mode 100644 index 000000000..e3a550ce2 --- /dev/null +++ b/src/drivers/generic/makefile @@ -0,0 +1,4 @@ +SUBDIRS = +OBS= Device.o + +include ../../../makefile.inc diff --git a/src/drivers/makefile b/src/drivers/makefile index 0766b9328..f003486d7 100644 --- a/src/drivers/makefile +++ b/src/drivers/makefile @@ -1,4 +1,4 @@ -SUBDIRS = PCI TTY +SUBDIRS = PCI TTY generic OBS= Keyboard.o ProgrammableInterruptController.o include ../../makefile.inc From b95fab298945a5690cab4c050def90227d595fe8 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sun, 4 Feb 2018 15:44:45 -0600 Subject: [PATCH 068/171] base device types --- makefile.inc | 4 ++-- src/drivers/generic/BlockDevice.h | 4 ++-- src/drivers/generic/CharDevice.cpp | 0 src/drivers/generic/CharDevice.h | 8 ++++++++ src/drivers/generic/Device.cpp | 2 ++ src/drivers/generic/Device.h | 4 ++-- src/drivers/generic/makefile | 2 +- 7 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 src/drivers/generic/CharDevice.cpp create mode 100644 src/drivers/generic/CharDevice.h diff --git a/makefile.inc b/makefile.inc index 03446c995..090964dd6 100644 --- a/makefile.inc +++ b/makefile.inc @@ -2,8 +2,8 @@ AS = i686-elf-as GPP = i686-elf-g++ GCC = i686-elf-gcc -OS_CPP = /home/garrett/workspace/exos -BUILD_TO = /run/media/garrett/disk/boot/kernel.bin +OS_CPP = /Users/garrettbattaglia/Documents/dev/Exos/exos +BUILD_TO = $(OS_CPP)/../kernel.bin CFLAGS = -c -ffreestanding -O2 -Wall -Wextra -fno-rtti -fno-exceptions -g -std=gnu++14 -I$(OS_CPP)/src OBJ_DIR = $(OS_CPP)/build diff --git a/src/drivers/generic/BlockDevice.h b/src/drivers/generic/BlockDevice.h index 5bb2522d0..6c3b7de59 100644 --- a/src/drivers/generic/BlockDevice.h +++ b/src/drivers/generic/BlockDevice.h @@ -4,5 +4,5 @@ class BlockDevice :public Device{ private: public: -virtual read() = 0; -} \ No newline at end of file +virtual void read(uint32_t sector, void* readTo) = 0; +}; \ No newline at end of file diff --git a/src/drivers/generic/CharDevice.cpp b/src/drivers/generic/CharDevice.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/drivers/generic/CharDevice.h b/src/drivers/generic/CharDevice.h new file mode 100644 index 000000000..e9df592ac --- /dev/null +++ b/src/drivers/generic/CharDevice.h @@ -0,0 +1,8 @@ +#include "Global.h" +#include "device.h" + +class CharDevice : public Device +{ + private: + public: +}; \ No newline at end of file diff --git a/src/drivers/generic/Device.cpp b/src/drivers/generic/Device.cpp index 68ed99d62..e60890c57 100644 --- a/src/drivers/generic/Device.cpp +++ b/src/drivers/generic/Device.cpp @@ -1,2 +1,4 @@ #include "Device.h" +uint32_t lastDeviceId; +Device *deviceList = nullptr; \ No newline at end of file diff --git a/src/drivers/generic/Device.h b/src/drivers/generic/Device.h index 16a5b1e89..acc6e37ae 100644 --- a/src/drivers/generic/Device.h +++ b/src/drivers/generic/Device.h @@ -3,7 +3,7 @@ -uint32_t lastDeviceId; +extern uint32_t lastDeviceId; class Device @@ -16,4 +16,4 @@ class Device } }; -Device* deviceList = nullptr; \ No newline at end of file +extern Device* deviceList; \ No newline at end of file diff --git a/src/drivers/generic/makefile b/src/drivers/generic/makefile index e3a550ce2..adffd85ca 100644 --- a/src/drivers/generic/makefile +++ b/src/drivers/generic/makefile @@ -1,4 +1,4 @@ SUBDIRS = -OBS= Device.o +OBS= Device.o BlockDevice.o CharDevice.o include ../../../makefile.inc From 16c26cb802af528bed94a42e68fea18053e9747c Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sun, 4 Feb 2018 15:59:52 -0600 Subject: [PATCH 069/171] keyboard is now a char device also fixed some include guards --- src/drivers/Keyboard.h | 3 ++- src/drivers/generic/BlockDevice.cpp | 3 ++- src/drivers/generic/BlockDevice.h | 8 +++++++- src/drivers/generic/CharDevice.h | 6 +++++- src/drivers/generic/Device.h | 7 ++++++- src/drivers/generic/SpecialDevice.cpp | 1 + src/drivers/generic/SpecialDevice.h | 11 +++++++++++ src/drivers/generic/makefile | 2 +- 8 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 src/drivers/generic/SpecialDevice.cpp create mode 100644 src/drivers/generic/SpecialDevice.h diff --git a/src/drivers/Keyboard.h b/src/drivers/Keyboard.h index 755108683..f15fec337 100644 --- a/src/drivers/Keyboard.h +++ b/src/drivers/Keyboard.h @@ -9,6 +9,7 @@ #define KEYBOARD_H_ #include "Global.h" +#include "generic/CharDevice.h" /** * the possible scan code sets */ @@ -74,7 +75,7 @@ enum ModKeyMasks { NUM_LOCK = 1 << 10, //!< NUM_LOCK }; -class Keyboard { +class Keyboard :public CharDevice { private: SCAN_CODE scanCodeSet; uint16_t modKeys = 0; diff --git a/src/drivers/generic/BlockDevice.cpp b/src/drivers/generic/BlockDevice.cpp index a494c6df6..c8bb86e80 100644 --- a/src/drivers/generic/BlockDevice.cpp +++ b/src/drivers/generic/BlockDevice.cpp @@ -1 +1,2 @@ -#include "BlockDevice.h" \ No newline at end of file + +#include "BlockDevice.h" diff --git a/src/drivers/generic/BlockDevice.h b/src/drivers/generic/BlockDevice.h index 6c3b7de59..e31157cf6 100644 --- a/src/drivers/generic/BlockDevice.h +++ b/src/drivers/generic/BlockDevice.h @@ -1,3 +1,6 @@ +#ifndef BLOCKDEVICE_H_ +#define BLOCKDEVICE_H_ + #include "Global.h" #include "Device.h" @@ -5,4 +8,7 @@ class BlockDevice :public Device{ private: public: virtual void read(uint32_t sector, void* readTo) = 0; -}; \ No newline at end of file +}; + + +#endif \ No newline at end of file diff --git a/src/drivers/generic/CharDevice.h b/src/drivers/generic/CharDevice.h index e9df592ac..4f095007a 100644 --- a/src/drivers/generic/CharDevice.h +++ b/src/drivers/generic/CharDevice.h @@ -1,3 +1,5 @@ +#ifndef CHARDEVICE_H_ +#define CHARDEVICE_H_ #include "Global.h" #include "device.h" @@ -5,4 +7,6 @@ class CharDevice : public Device { private: public: -}; \ No newline at end of file +}; + +#endif \ No newline at end of file diff --git a/src/drivers/generic/Device.h b/src/drivers/generic/Device.h index acc6e37ae..5e8a2c514 100644 --- a/src/drivers/generic/Device.h +++ b/src/drivers/generic/Device.h @@ -1,3 +1,6 @@ +#ifndef DEVICE_H_ +#define DEVICE_H_ + #include "Global.h" @@ -16,4 +19,6 @@ class Device } }; -extern Device* deviceList; \ No newline at end of file +extern Device* deviceList; + +#endif \ No newline at end of file diff --git a/src/drivers/generic/SpecialDevice.cpp b/src/drivers/generic/SpecialDevice.cpp new file mode 100644 index 000000000..fb2994cf9 --- /dev/null +++ b/src/drivers/generic/SpecialDevice.cpp @@ -0,0 +1 @@ +#include "SpecialDevice.h" \ No newline at end of file diff --git a/src/drivers/generic/SpecialDevice.h b/src/drivers/generic/SpecialDevice.h new file mode 100644 index 000000000..fb130cdda --- /dev/null +++ b/src/drivers/generic/SpecialDevice.h @@ -0,0 +1,11 @@ +#ifndef SPECIALDEVICE_H_ +#define SPECIALDEVICE_H_ +#include "Global.h" +#include "Device.h" + +class SpecialDevice : public Device{ + private: + public: +}; + +#endif \ No newline at end of file diff --git a/src/drivers/generic/makefile b/src/drivers/generic/makefile index adffd85ca..b0fcda2b5 100644 --- a/src/drivers/generic/makefile +++ b/src/drivers/generic/makefile @@ -1,4 +1,4 @@ SUBDIRS = -OBS= Device.o BlockDevice.o CharDevice.o +OBS= Device.o BlockDevice.o CharDevice.o SpecialDevice.o include ../../../makefile.inc From f179b323fde4a95e544a7e16d6db9d3db13dd615 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 5 Feb 2018 21:14:56 -0600 Subject: [PATCH 070/171] continuing device refactor --- src/drivers/ProgrammableInterruptController.h | 1 + src/drivers/generic/OutputDevice.cpp | 1 + src/drivers/generic/OutputDevice.h | 10 ++++++++++ 3 files changed, 12 insertions(+) create mode 100644 src/drivers/generic/OutputDevice.cpp create mode 100644 src/drivers/generic/OutputDevice.h diff --git a/src/drivers/ProgrammableInterruptController.h b/src/drivers/ProgrammableInterruptController.h index f21b915ee..b3e0ffe8e 100755 --- a/src/drivers/ProgrammableInterruptController.h +++ b/src/drivers/ProgrammableInterruptController.h @@ -11,6 +11,7 @@ #include "Global.h" +//TODO classify /* class ProgrammableInterruptController { private: diff --git a/src/drivers/generic/OutputDevice.cpp b/src/drivers/generic/OutputDevice.cpp new file mode 100644 index 000000000..27251d5f7 --- /dev/null +++ b/src/drivers/generic/OutputDevice.cpp @@ -0,0 +1 @@ +#include "OutputDevice.h" \ No newline at end of file diff --git a/src/drivers/generic/OutputDevice.h b/src/drivers/generic/OutputDevice.h new file mode 100644 index 000000000..129fdef1c --- /dev/null +++ b/src/drivers/generic/OutputDevice.h @@ -0,0 +1,10 @@ +#ifndef OUTPUT_DEVICE_H_ +#define OUTPUT_DEVICE_H_ + +#include "Device.h" + +class OutputDevice: public Device{ + +}; + +#endif \ No newline at end of file From 9b4e6a613661c5f6f5352d1f578a98727faf8bf2 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 5 Feb 2018 21:26:04 -0600 Subject: [PATCH 071/171] more device stuff --- src/drivers/PCI/PCI_devices/PCIDevice.h | 4 ++-- src/drivers/PCI/USB/USBController.cpp | 1 + src/drivers/PCI/USB/USBController.h | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/drivers/PCI/PCI_devices/PCIDevice.h b/src/drivers/PCI/PCI_devices/PCIDevice.h index 56000d426..cb6038cd7 100644 --- a/src/drivers/PCI/PCI_devices/PCIDevice.h +++ b/src/drivers/PCI/PCI_devices/PCIDevice.h @@ -9,9 +9,9 @@ #define SRC_DRIVERS_PCI_PCIDEVICE_H_ #include "Global.h" +#include "drivers/generic/SpecialDevice.h" - -class PCIDevice { +class PCIDevice: public SpecialDevice { protected: uint8_t _bus; uint8_t _device; diff --git a/src/drivers/PCI/USB/USBController.cpp b/src/drivers/PCI/USB/USBController.cpp index 9f0c55fa1..606819565 100644 --- a/src/drivers/PCI/USB/USBController.cpp +++ b/src/drivers/PCI/USB/USBController.cpp @@ -7,6 +7,7 @@ #include "drivers/PCI/USB/USBController.h" + USBController::USBController( ) { // TODO Auto-generated constructor stub diff --git a/src/drivers/PCI/USB/USBController.h b/src/drivers/PCI/USB/USBController.h index e0bd6873e..da804efe8 100644 --- a/src/drivers/PCI/USB/USBController.h +++ b/src/drivers/PCI/USB/USBController.h @@ -9,8 +9,9 @@ #define USBCONTROLLER_H_ #include "Global.h" +#include "drivers/PCI/PCI_devices/PCIStandardDevice.h" -class USBController { +class USBController :public PCIStandardDevice{ public: USBController( ); }; From 08d98331cfb518951b4c3da45150b94889f87d0b Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 5 Feb 2018 21:33:18 -0600 Subject: [PATCH 072/171] added some functions to the device classes --- src/drivers/generic/BlockDevice.h | 10 +++++----- src/drivers/generic/CharDevice.h | 2 ++ src/drivers/generic/OutputDevice.h | 7 +++++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/drivers/generic/BlockDevice.h b/src/drivers/generic/BlockDevice.h index e31157cf6..6c9b9d811 100644 --- a/src/drivers/generic/BlockDevice.h +++ b/src/drivers/generic/BlockDevice.h @@ -4,11 +4,11 @@ #include "Global.h" #include "Device.h" -class BlockDevice :public Device{ -private: -public: -virtual void read(uint32_t sector, void* readTo) = 0; +class BlockDevice : public Device +{ + private: + public: + virtual void read(uint32_t sector, void *readTo) = 0; }; - #endif \ No newline at end of file diff --git a/src/drivers/generic/CharDevice.h b/src/drivers/generic/CharDevice.h index 4f095007a..b4c37d6d8 100644 --- a/src/drivers/generic/CharDevice.h +++ b/src/drivers/generic/CharDevice.h @@ -7,6 +7,8 @@ class CharDevice : public Device { private: public: + void read(char* readTo); + char read(); }; #endif \ No newline at end of file diff --git a/src/drivers/generic/OutputDevice.h b/src/drivers/generic/OutputDevice.h index 129fdef1c..9b8e72570 100644 --- a/src/drivers/generic/OutputDevice.h +++ b/src/drivers/generic/OutputDevice.h @@ -3,8 +3,11 @@ #include "Device.h" -class OutputDevice: public Device{ - +class OutputDevice : public Device +{ + private: + public: + void write(char* toWrite, size_t size); }; #endif \ No newline at end of file From 94028eb8c89b0a2662d0d88326834ca16183512a Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 5 Feb 2018 21:38:01 -0600 Subject: [PATCH 073/171] forgot to make them pure virtual --- src/drivers/Keyboard.h | 6 ++++++ src/drivers/generic/CharDevice.h | 4 ++-- src/drivers/generic/OutputDevice.h | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/drivers/Keyboard.h b/src/drivers/Keyboard.h index f15fec337..814563409 100644 --- a/src/drivers/Keyboard.h +++ b/src/drivers/Keyboard.h @@ -123,6 +123,12 @@ class Keyboard :public CharDevice { uint16_t* getModkeys( ) { return &modKeys; } + virtual void read(char* readTo){ + *readTo = getKey(); + } + virtual char read(){ + return getKey(); + } }; #endif /* KEYBOARD_H_ */ diff --git a/src/drivers/generic/CharDevice.h b/src/drivers/generic/CharDevice.h index b4c37d6d8..dd9c0d774 100644 --- a/src/drivers/generic/CharDevice.h +++ b/src/drivers/generic/CharDevice.h @@ -7,8 +7,8 @@ class CharDevice : public Device { private: public: - void read(char* readTo); - char read(); + virtual void read(char* readTo) =0 ; + virtual char read()=0; }; #endif \ No newline at end of file diff --git a/src/drivers/generic/OutputDevice.h b/src/drivers/generic/OutputDevice.h index 9b8e72570..34ffdf3bb 100644 --- a/src/drivers/generic/OutputDevice.h +++ b/src/drivers/generic/OutputDevice.h @@ -7,7 +7,7 @@ class OutputDevice : public Device { private: public: - void write(char* toWrite, size_t size); + virtual void write(char* toWrite, size_t size) = 0; }; #endif \ No newline at end of file From 9be10a18b331286a9079b30e53b3cc02926d9b87 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 5 Feb 2018 22:13:22 -0600 Subject: [PATCH 074/171] makefile updates --- makefile.inc | 7 ++++--- src/drivers/filesys/fat/fat12/makefile | 3 +++ src/drivers/filesys/general/makefile | 2 ++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/makefile.inc b/makefile.inc index 03446c995..8776d425f 100644 --- a/makefile.inc +++ b/makefile.inc @@ -2,9 +2,10 @@ AS = i686-elf-as GPP = i686-elf-g++ GCC = i686-elf-gcc -OS_CPP = /home/garrett/workspace/exos -BUILD_TO = /run/media/garrett/disk/boot/kernel.bin -CFLAGS = -c -ffreestanding -O2 -Wall -Wextra -fno-rtti -fno-exceptions -g -std=gnu++14 -I$(OS_CPP)/src +OS_CPP = /Users/garrettbattaglia/Documents/dev/Exos/exos +BUILD_TO = $(OS_CPP)/../kernel.bin + +CFLAGS = $(CFLAGS_CUSTOM) -c -ffreestanding -O2 -Wall -Wextra -fno-rtti -fno-exceptions -g -std=gnu++14 -I$(OS_CPP)/src OBJ_DIR = $(OS_CPP)/build diff --git a/src/drivers/filesys/fat/fat12/makefile b/src/drivers/filesys/fat/fat12/makefile index 4f7c32c94..e369f3906 100644 --- a/src/drivers/filesys/fat/fat12/makefile +++ b/src/drivers/filesys/fat/fat12/makefile @@ -1,3 +1,6 @@ OBS = Fat12FS.o Fat12File.o +CFLAGS_CUSTOM = -Wno-packed-bitfield-compat -Wno-write-strings + include ../../../../../makefile.inc + diff --git a/src/drivers/filesys/general/makefile b/src/drivers/filesys/general/makefile index 851bb5fa7..cc10f5ce9 100644 --- a/src/drivers/filesys/general/makefile +++ b/src/drivers/filesys/general/makefile @@ -1,3 +1,5 @@ OBS = File.o FS.o FSNode.h +CFLAGS_CUSTOM = -Wno-write-strings + include ../../../../makefile.inc \ No newline at end of file From 9e02512e53eabc9f83aaf5665408b8427738cdb1 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 5 Feb 2018 22:13:58 -0600 Subject: [PATCH 075/171] Fat12 warnings --- src/drivers/filesys/fat/fat12/Fat12FS.cpp | 127 ++++++++++++-------- src/drivers/filesys/fat/fat12/Fat12FS.h | 34 +++--- src/drivers/filesys/fat/fat12/Fat12FSNode.h | 46 ++++--- src/drivers/filesys/fat/fat12/Fat12File.cpp | 64 +++++----- 4 files changed, 159 insertions(+), 112 deletions(-) diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.cpp b/src/drivers/filesys/fat/fat12/Fat12FS.cpp index 6f77f5e7d..81958463a 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12FS.cpp @@ -7,37 +7,44 @@ #include "Fat12FSNode.h" #include "utils/string/Split.h" -File *Fat12FS::open(char *path, int flags, int mode) { - Fat12FSNode* file = find(path,(Fat12FSNode*)_root ); +File *Fat12FS::open(char *path, int flags, int mode) +{ + (void)flags; + (void)mode; + Fat12FSNode *file = find(path, (Fat12FSNode *)_root); Fat12File *ret = new Fat12File(file->startCluster()); return ret; } -Fat12FSNode* Fat12FS::find(char* path, Fat12FSNode* root){ - char** split = strSplit(path, '/'); - if (split == nullptr){ +Fat12FSNode *Fat12FS::find(char *path, Fat12FSNode *root) +{ + char **split = strSplit(path, '/'); + if (split == nullptr) + { return root; } - for (int i=0; i< root->childernCount(); i++){ - if (strcmp(root->children()[i]->name(), split[0]) == 0){ - return find(split[1], (Fat12FSNode*)root->children()[i]); + for (unsigned int i = 0; i < root->childernCount(); i++) + { + if (strcmp(root->children()[i]->name(), split[0]) == 0) + { + return find(split[1], (Fat12FSNode *)root->children()[i]); } } + return nullptr; } //todo names, var sizes, structure taken from osdev wiki -bool Fat12FS::readCluster(uint16_t cluster, void* fileLoc, size_t fileLocSize) { +bool Fat12FS::readCluster(uint16_t cluster, void *fileLoc, size_t fileLocSize) +{ + (void)fileLoc; assert(fileLocSize >= (_FSInfo->secPerCluster * _FSInfo->bytePerSec)); uint32_t fat_size = - (_FSInfo->secCount != 0) ? - _FSInfo->secCount : _FSInfo->largeSecCount; - uint32_t root_dir_sectors = ( (_FSInfo->dirEntryCount * 32) - + (_FSInfo->bytePerSec - 1)) / _FSInfo->bytePerSec; - uint32_t first_data_sector = _FSInfo->resSec + (_FSInfo->FATs * fat_size) - + root_dir_sectors; - uint32_t first_sector_of_cluster = ( (cluster - 2) * _FSInfo->secPerCluster) - + first_data_sector; - for (uint32_t i = 0; i < _FSInfo->secPerCluster; i++) { + (_FSInfo->secCount != 0) ? _FSInfo->secCount : _FSInfo->largeSecCount; + uint32_t root_dir_sectors = ((_FSInfo->dirEntryCount * 32) + (_FSInfo->bytePerSec - 1)) / _FSInfo->bytePerSec; + uint32_t first_data_sector = _FSInfo->resSec + (_FSInfo->FATs * fat_size) + root_dir_sectors; + uint32_t first_sector_of_cluster = ((cluster - 2) * _FSInfo->secPerCluster) + first_data_sector; + for (uint32_t i = 0; i < _FSInfo->secPerCluster; i++) + { //TODO after _device isnt void* uncommetn below //bool ret = _device->read(first_sector_of_cluster, fileLoc); //TODO return on read error @@ -45,9 +52,10 @@ bool Fat12FS::readCluster(uint16_t cluster, void* fileLoc, size_t fileLocSize) { } } //TODO check var sizes -void Fat12FS::buildDirStructure( ) { +void Fat12FS::buildDirStructure() +{ //This conversion may not work correctly... oh well - _root = new Fat12FSNode("Root", 0, DIR, ( (_FSInfo->resSec) + (_FSInfo->FATs * _FSInfo->secPerFAT) )/_FSInfo->secPerCluster); + _root = new Fat12FSNode("Root", 0, DIR, ((_FSInfo->resSec) + (_FSInfo->FATs * _FSInfo->secPerFAT)) / _FSInfo->secPerCluster, this); /*uint8_t* tempSector = (uint8_t*) malloc(_FSInfo->bytePerSec); uint8_t sectorOffset = 0; uint16_t startSector = (_FSInfo->resSec) @@ -77,26 +85,36 @@ void Fat12FS::buildDirStructure( ) { //_device->read(startSectot+i, tempCluster) } }*/ - buildTree((Fat12FSNode*)_root); + buildTree((Fat12FSNode *)_root); } -void Fat12FS::buildTree(Fat12FSNode* dir){ - uint8_t* tempSector = (uint8_t*) malloc(_FSInfo->bytePerSec); +void Fat12FS::buildTree(Fat12FSNode *dir) +{ + (void)dir; + uint8_t *tempSector = (uint8_t *)malloc(_FSInfo->bytePerSec); size_t offset = 0; - while(tempSector[offset] != 0){ - Fat12FSNode* ret = parseEntry(tempSector + offset); - if (_tempLongName == nullptr){ + //_device.read(...) + while (tempSector[offset] != 0) + { + Fat12FSNode *ret = parseEntry(tempSector + offset); + if (_tempLongName == nullptr) + { offset += sizeof(FatNormalFileName); - } else { + } + else + { offset += sizeof(FatLongFileName); } - if(ret != nullptr){ + if (ret != nullptr) + { _root->add(ret); - if(ret->type() == DIR){ + if (ret->type() == DIR) + { buildTree(ret); } } - if (offset >= _FSInfo->bytePerSec){ + if (offset >= _FSInfo->bytePerSec) + { //_device->read(startSectot+i, tempCluster) } } @@ -108,34 +126,41 @@ void Fat12FS::buildTree(Fat12FSNode* dir){ free(tempSector); } -Fat12FSNode* Fat12FS::parseEntry(uint8_t* sector){ - if(sector[0] == 0xE5){ +Fat12FSNode *Fat12FS::parseEntry(uint8_t *sector) +{ + if (sector[0] == 0xE5) + { return nullptr; } - if (sector[10] == 0x0F){ + if (sector[10] == 0x0F) + { //i belive this wont overrun and will end with a null in the right spot. also i hope this doesnt add a null somewhere - FatLongFileName* entry = (FatLongFileName*)sector; + FatLongFileName *entry = (FatLongFileName *)sector; uint32_t tempLeng = strlen(_tempLongName); - _tempLongName = (char*) realloc(_tempLongName, tempLeng + 10+10+4); - memcpy(_tempLongName+tempLeng, &entry->nameFirst, 10); - memcpy(_tempLongName+tempLeng +10, &entry->nameMid, 10); - memcpy(_tempLongName+tempLeng+10+10, &entry->nameEnd, 4); - _tempLongName[tempLeng+10+10+4+1] = '\0'; + _tempLongName = (char *)realloc(_tempLongName, tempLeng + 10 + 10 + 4); + memcpy(_tempLongName + tempLeng, &entry->nameFirst, 10); + memcpy(_tempLongName + tempLeng + 10, &entry->nameMid, 10); + memcpy(_tempLongName + tempLeng + 10 + 10, &entry->nameEnd, 4); + _tempLongName[tempLeng + 10 + 10 + 4 + 1] = '\0'; return nullptr; - } else { - FatNormalFileName* entry = (FatNormalFileName*) sector; + } + else + { + FatNormalFileName *entry = (FatNormalFileName *)sector; Type type = (entry->attribute && 0x10) != 0 ? DIR : FILE; - char* name = nullptr; - if(false /*have long file name stored*/){ - name = (char*) malloc(strlen(_tempLongName) * sizeof(uint16_t)); - memcpy(name, _tempLongName, strlen(_tempLongName)*2); - } else { - name = (char*) malloc(strlen((char*)entry->name) * sizeof(uint8_t)); - memcpy(name, entry->name, strlen((char*)entry->name)); + char *name = nullptr; + if (false /*have long file name stored*/) + { + name = (char *)malloc(strlen(_tempLongName) * sizeof(uint16_t)); + memcpy(name, _tempLongName, strlen(_tempLongName) * 2); + } + else + { + name = (char *)malloc(strlen((char *)entry->name) * sizeof(uint8_t)); + memcpy(name, entry->name, strlen((char *)entry->name)); } - uint32_t size = entry->size; + uint32_t size = entry->size; uint32_t cluster = entry->lowClusterNumber; - return new Fat12FSNode(name, size, type, cluster); - + return new Fat12FSNode(name, size, type, cluster, this); } } diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.h b/src/drivers/filesys/fat/fat12/Fat12FS.h index 902bad643..6f1653083 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.h +++ b/src/drivers/filesys/fat/fat12/Fat12FS.h @@ -8,25 +8,27 @@ #include "drivers/filesys/fat/FatStructs.h" #include "Global.h" #include "drivers/filesys/general/FS.h" -#include "Fat12FSNode.h" +//#include "Fat12FSNode.h" class Fat12File; +class Fat12FSNode; +class Fat12FS : public FS +{ + private: + FatBPB *_FSInfo; + char *_tempLongName = nullptr; -class Fat12FS : public FS{ - private: - FatBPB* _FSInfo; - char* _tempLongName = nullptr; - public: - File *open(char *path, int flags, int mode); - - FatBPB *FSInfo( ) { - return _FSInfo; - } - bool readCluster(uint16_t cluser, void* fileLoc, size_t fileLocSize); - void buildDirStructure(); - Fat12FSNode* parseEntry(uint8_t* sector); - void buildTree(Fat12FSNode* root); - Fat12FSNode* find(char* path, Fat12FSNode* root); + public: + File *open(char *path, int flags, int mode); + FatBPB *FSInfo() + { + return _FSInfo; + } + bool readCluster(uint16_t cluser, void *fileLoc, size_t fileLocSize); + void buildDirStructure(); + Fat12FSNode *parseEntry(uint8_t *sector); + void buildTree(Fat12FSNode *root); + Fat12FSNode *find(char *path, Fat12FSNode *root); }; #endif //EXOS_FAT12_H diff --git a/src/drivers/filesys/fat/fat12/Fat12FSNode.h b/src/drivers/filesys/fat/fat12/Fat12FSNode.h index 53da8aa07..20f89e082 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FSNode.h +++ b/src/drivers/filesys/fat/fat12/Fat12FSNode.h @@ -8,26 +8,38 @@ #ifndef SRC_DRIVERS_FILESYS_FAT_FAT12_FAT12FSNODE_H_ #define SRC_DRIVERS_FILESYS_FAT_FAT12_FAT12FSNODE_H_ #include "Global.h" +#include "Fat12FS.h" -class Fat12FSNode: public FSNode { - private: - uint32_t _startCluster; - public: - Fat12FSNode(char* name, uint32_t size, Type type, uint32_t cluster):FSNode(name,size,type), _startCluster(cluster){ +//class Fat12FS; - } - Fat12FSNode():FSNode(){ - - } - virtual uint32_t startSector(){ +class Fat12FSNode : public FSNode +{ + private: + uint32_t _startCluster; + Fat12FS *_host; - } - virtual ~Fat12FSNode( ){ - - } - uint32_t startCluster(){ - return _startCluster; - } + public: + Fat12FSNode(char *name, uint32_t size, Type type, uint32_t cluster, Fat12FS *fs) : FSNode(name, size, type), _startCluster(cluster), _host(fs) + { + } + Fat12FSNode() : FSNode() + { + } + //todo var names and size, taken from fat12fs.cpp + virtual uint32_t startSector() + { + uint32_t fat_size = (_host->FSInfo()->secCount != 0) ? _host->FSInfo()->secCount : _host->FSInfo()->largeSecCount; + uint32_t root_dir_sectors = ((_host->FSInfo()->dirEntryCount * 32) + (_host->FSInfo()->bytePerSec - 1)) / _host->FSInfo()->bytePerSec; + uint32_t first_data_sector = _host->FSInfo()->resSec + (_host->FSInfo()->FATs * fat_size) + root_dir_sectors; + return ((_startCluster - 2) * _host->FSInfo()->secPerCluster) + first_data_sector; + } + virtual ~Fat12FSNode() + { + } + uint32_t startCluster() + { + return _startCluster; + } }; #endif /* SRC_DRIVERS_FILESYS_FAT_FAT12_FAT12FSNODE_H_ */ diff --git a/src/drivers/filesys/fat/fat12/Fat12File.cpp b/src/drivers/filesys/fat/fat12/Fat12File.cpp index afa81f472..49792189a 100644 --- a/src/drivers/filesys/fat/fat12/Fat12File.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12File.cpp @@ -5,59 +5,67 @@ #include "Fat12File.h" #include "memory/Mem.h" -size_t Fat12File::read(char *buffer, size_t size) { +size_t Fat12File::read(char *buffer, size_t size) +{ size_t bytesRead = 0; - while (bytesRead < size) { - if (size < (_fileLocSize - _lastByteRead)) { + while (bytesRead < size) + { + if (size < (_fileLocSize - _lastByteRead)) + { memcpy(buffer + bytesRead, - (uint8_t*) _fileLoc + (_lastByteRead - _fileLocStartInFile), - size); + (uint8_t *)_fileLoc + (_lastByteRead - _fileLocStartInFile), + size); bytesRead += size; - } else { + } + else + { memcpy(buffer + bytesRead, - (uint8_t*) _fileLoc + (_lastByteRead - _fileLocStartInFile), - _lastByteLoaded - _lastByteRead); + (uint8_t *)_fileLoc + (_lastByteRead - _fileLocStartInFile), + _lastByteLoaded - _lastByteRead); bytesRead += _lastByteLoaded - _lastByteRead; - if ( !readFromDisk( )) { + if (!readFromDisk()) + { return bytesRead; } } } + return 0; } //TODO naming and types and general structure, taken from osdev wiki -bool Fat12File::readFromDisk( ) { - uint16_t firstFatSec = _device->FSInfo( )->resSec; - unsigned char FAT_table[_device->FSInfo( )->bytePerSec]; +bool Fat12File::readFromDisk() +{ + //uint16_t firstFatSec = _device->FSInfo()->resSec; + unsigned char FAT_table[_device->FSInfo()->bytePerSec]; uint32_t read = 0; - while (read < _fileLocSize - && _fileLocSize - read - >= (_device->FSInfo( )->secPerCluster - * _device->FSInfo( )->bytePerSec)) { + while (read < _fileLocSize && _fileLocSize - read >= (_device->FSInfo()->secPerCluster * _device->FSInfo()->bytePerSec)) + { unsigned int fat_offset = _lastCluster + (_lastCluster / 2); // multiply by 1.5 - unsigned int fat_sector = firstFatSec - + (fat_offset / _device->FSInfo( )->bytePerSec); - unsigned int ent_offset = fat_offset % _device->FSInfo( )->bytePerSec; + //unsigned int fat_sector = firstFatSec + (fat_offset / _device->FSInfo()->bytePerSec); + unsigned int ent_offset = fat_offset % _device->FSInfo()->bytePerSec; - unsigned short table_value = *(unsigned short *) &FAT_table[ent_offset]; + unsigned short table_value = *(unsigned short *)&FAT_table[ent_offset]; if (_lastCluster & 0x0001) table_value = table_value >> 4; else table_value = table_value & 0x0FFF; - if (table_value >= 0xFF8) { + if (table_value >= 0xFF8) + { //TODO make sure this frees everything - free((uint8_t*)_fileLoc + read); + free((uint8_t *)_fileLoc + read); _fileLocSize = read; return true; - } else { - bool ret = _device->readCluster(table_value, (uint8_t*)_fileLoc + read, - _fileLocSize - read); - if ( !ret) { + } + else + { + bool ret = _device->readCluster(table_value, (uint8_t *)_fileLoc + read, + _fileLocSize - read); + if (!ret) + { return false; } - read += (_device->FSInfo( )->secPerCluster - * _device->FSInfo( )->bytePerSec); + read += (_device->FSInfo()->secPerCluster * _device->FSInfo()->bytePerSec); _lastCluster = table_value; } } From 7c33bb4515607599cf20ff8d475af1e900af992e Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 5 Feb 2018 22:14:54 -0600 Subject: [PATCH 076/171] somrthing to FSNode --- src/drivers/filesys/general/FSNode.h | 92 ++++++++++++++++------------ 1 file changed, 52 insertions(+), 40 deletions(-) diff --git a/src/drivers/filesys/general/FSNode.h b/src/drivers/filesys/general/FSNode.h index 6e2242b63..035354490 100644 --- a/src/drivers/filesys/general/FSNode.h +++ b/src/drivers/filesys/general/FSNode.h @@ -7,48 +7,60 @@ #include "Global.h" -enum Type{ - FILE, DIR, LINK +enum Type +{ + FILE, + DIR, + LINK }; -class FSNode{ - private: - char* _name; - uint32_t _size; - FSNode** _children; - Type _type; - size_t _childernCount; - public: - FSNode(){ - _name="root"; - _size =0; - _type=DIR; - } - FSNode(char* name, uint32_t size, Type type){ - _name=name; - _size = size; - _type =type; - _children = nullptr; - _childernCount = 0; - } - void add(FSNode* toAdd){ - _children = (FSNode**) realloc(_children, sizeof(FSNode*) * (++_childernCount)); - _children[_childernCount-1] = toAdd; - } - size_t childernCount(){ - return _childernCount; - } - FSNode** children(){ - return _children; - } - Type type(){ - return _type; - } - char* name(){ - return _name; - } - virtual uint32_t startSector() = 0; - //Permissions permissons(); +class FSNode +{ + private: + char *_name; + uint32_t _size; + FSNode **_children; + Type _type; + size_t _childernCount; + + public: + FSNode() + { + _name = "root"; + _size = 0; + _type = DIR; + } + FSNode(char *name, uint32_t size, Type type) + { + _name = name; + _size = size; + _type = type; + _children = nullptr; + _childernCount = 0; + } + void add(FSNode *toAdd) + { + _children = (FSNode **)realloc(_children, sizeof(FSNode *) * (++_childernCount)); + _children[_childernCount - 1] = toAdd; + } + size_t childernCount() + { + return _childernCount; + } + FSNode **children() + { + return _children; + } + Type type() + { + return _type; + } + char *name() + { + return _name; + } + virtual uint32_t startSector() = 0; + //Permissions permissons(); }; #endif //EXOS_FSNODE_H From 3689124d0c3dcc3bbafaafbf6d8cf39d82909c5f Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 5 Feb 2018 22:17:43 -0600 Subject: [PATCH 077/171] sign warning issues --- src/memory/alloc/Malloc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/memory/alloc/Malloc.c b/src/memory/alloc/Malloc.c index 0ebd4a991..c6e4c8262 100644 --- a/src/memory/alloc/Malloc.c +++ b/src/memory/alloc/Malloc.c @@ -59,10 +59,10 @@ void *malloc(size_t size) top = (void*) ((size_t) top + sizeOfNewMem + ((size_t)startOfNewMem - (size_t)top) ); return malloc(size); } - } else if (!c->used && (c->next - c) == size) { + } else if (!c->used && (unsigned)(c->next - c) == size) { c->used = true; return c+1; - } else if (!c->used && (c->next - c) >= (size + sizeof(memHeader))) { + } else if (!c->used && (unsigned)(c->next - c) >= (size + sizeof(memHeader))) { memHeader* temp = (memHeader*)(((uint8_t*)(c+1)) + size); temp->next = c->next; temp->used = false; @@ -102,7 +102,7 @@ void *malloc(size_t size) return malloc(size); //} - /* + size_t space = (size_t) top - (size_t) base; if (space > size) { //if there is space in the current phys mem allocated From 9e1b3cca595eacdd86311dbdaba3508ec74e5ce8 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 5 Feb 2018 22:19:14 -0600 Subject: [PATCH 078/171] no return warnings fixed --- src/memory/alloc/Malloc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/memory/alloc/Malloc.c b/src/memory/alloc/Malloc.c index c6e4c8262..4e4e96cc3 100644 --- a/src/memory/alloc/Malloc.c +++ b/src/memory/alloc/Malloc.c @@ -73,7 +73,7 @@ void *malloc(size_t size) continue; } } - +return nullptr; /*size += sizeof(memHeader); //size_t space = (size_t) top - (size_t) & kernelEnd; //if (space > size) { @@ -178,5 +178,5 @@ void *realloc(void *ptr, size_t size) free(ptr); return res; } - +return null; } \ No newline at end of file From 1799b428bc5fe5e9b50817b263d02695768cda26 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 5 Feb 2018 22:21:29 -0600 Subject: [PATCH 079/171] delete done --- src/memory/alloc/Malloc.c | 2 +- src/memory/alloc/New.cpp | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/memory/alloc/Malloc.c b/src/memory/alloc/Malloc.c index 4e4e96cc3..00c4dd9f4 100644 --- a/src/memory/alloc/Malloc.c +++ b/src/memory/alloc/Malloc.c @@ -178,5 +178,5 @@ void *realloc(void *ptr, size_t size) free(ptr); return res; } -return null; +return nullptr; } \ No newline at end of file diff --git a/src/memory/alloc/New.cpp b/src/memory/alloc/New.cpp index dfc7f7014..d97976c8c 100644 --- a/src/memory/alloc/New.cpp +++ b/src/memory/alloc/New.cpp @@ -16,10 +16,11 @@ void * operator new(size_t size) { } void operator delete(void * p) { -//TODO + free(p); } void operator delete(void* ptr, long unsigned int size/*maybe?*/) { -//TODO + (void) size; + free(ptr); } void* operator new[](unsigned long size){ From 3cbabd37fa13e2869b030cec56daf36a024476da Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 5 Feb 2018 22:22:27 -0600 Subject: [PATCH 080/171] unsigned var comp again --- src/utils/string/Split.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/string/Split.cpp b/src/utils/string/Split.cpp index a2912926e..0948f355b 100644 --- a/src/utils/string/Split.cpp +++ b/src/utils/string/Split.cpp @@ -4,7 +4,7 @@ char **strSplit(char *to_split, char delim) { int spl_ind = -1; - for (int i = 0; i < strlen(to_split); i++) { + for (unsigned int i = 0; i < strlen(to_split); i++) { if (to_split[i] == delim) { spl_ind = i; break; From 26b07790545b36b79b8611565b8a926aa99c1a44 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 19 Feb 2018 11:16:19 -0600 Subject: [PATCH 081/171] removed test prints --- src/Kernel.cpp | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/Kernel.cpp b/src/Kernel.cpp index 4eb252b63..b121e2342 100644 --- a/src/Kernel.cpp +++ b/src/Kernel.cpp @@ -70,24 +70,6 @@ void kernelMain(multiboot_info_t *mbd) PCIDeviceList usbHostControllers(0x0C, 0x03, false); terminalWriteLine(" Done!"); terminalWriteLine("!!!!ExOS fully booted!!!!"); - printf("Test printf %d %c\n", 42, 'B'); - printf("Newline is 0x%x%c", '\n', '\n'); - uint32_t i = (uint32_t) malloc(10); - printf("malloc returned 0x%x\n", i); - i = (uint32_t)malloc(100); - printf("malloc returned 0x%x\n", i); - i =(uint32_t) malloc(50); - printf("malloc returned 0x%x\n", i); - i = (uint32_t)malloc(1); - printf("malloc returned 0x%x\n", i); - printf("freeing 1 byte"); - free((void*)i); - i = (uint32_t)malloc(1); - printf("malloc returned 0x%x\n", i); -/* - for (int cx = 0; cx < 10; cx++) { - printf("%d", cx); - }*/ //dont return. while (true) { asm("hlt"); From 7494898eb59e55e50973170b56f0d1bb7f2095e0 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 19 Feb 2018 11:52:47 -0600 Subject: [PATCH 082/171] removed all old PCI code --- src/Kernel.cpp | 4 +-- src/drivers/PCI/PCI.c | 30 ++++++++++--------- src/drivers/PCI/PCI.h | 28 +++++++++-------- src/drivers/PCI/PCIDeviceList.cpp | 3 +- src/drivers/PCI/PCIDeviceList.h | 3 +- src/drivers/PCI/PCI_devices/PCIDevice.cpp | 30 +++++++++---------- .../PCI/PCI_devices/PCIStandardDevice.cpp | 30 +++++++++---------- 7 files changed, 67 insertions(+), 61 deletions(-) diff --git a/src/Kernel.cpp b/src/Kernel.cpp index b121e2342..e66127ada 100644 --- a/src/Kernel.cpp +++ b/src/Kernel.cpp @@ -63,11 +63,11 @@ void kernelMain(multiboot_info_t *mbd) terminalWriteLine(" Done!"); terminalWriteString(" Finding PCI buses..."); //find the valid PCI buses - PCIInit(); + //PCIInit(); terminalWriteLine(" Done!"); terminalWriteString(" Finding USB host controllers..."); //find the (3 or less) USB host controllers. all have the same class/subclass code. - PCIDeviceList usbHostControllers(0x0C, 0x03, false); + //PCIDeviceList usbHostControllers(0x0C, 0x03, false); terminalWriteLine(" Done!"); terminalWriteLine("!!!!ExOS fully booted!!!!"); //dont return. diff --git a/src/drivers/PCI/PCI.c b/src/drivers/PCI/PCI.c index 42b060534..425baa4f3 100644 --- a/src/drivers/PCI/PCI.c +++ b/src/drivers/PCI/PCI.c @@ -7,16 +7,17 @@ #include "drivers/PCI/PCI.h" +/* //TODO clean up a lot uint8_t MAX_PCI_FUNCTION = 8; /** * bool array of valid PCI buses - */ + bool validPCIBuses[256]; /** * inits the PCI sub system. finds all PCI buses - */ + void PCIInit( ) { //make sure all buses are invalid for (uint16_t i = 0; i < 256; i++){ @@ -42,7 +43,7 @@ void PCIInit( ) { * @param device on bus * @param function in device * @return if device is multifunction - */ + bool isPCIMultiFunctionDevice(uint8_t bus, uint8_t device, uint8_t function) { return ! ( (getPCIHeaderType(bus, device, function) & 0x80) == 0); } @@ -52,7 +53,7 @@ bool isPCIMultiFunctionDevice(uint8_t bus, uint8_t device, uint8_t function) { * @param device * @param function * @return if the function is a valid function - */ + bool isValidPCIFunction(uint8_t bus, uint8_t device, uint8_t function) { return getPCIVenderID(bus, device, function) != 0xFFFF; } @@ -62,7 +63,7 @@ bool isValidPCIFunction(uint8_t bus, uint8_t device, uint8_t function) { * @param slot * @param function * @return vender ID - */ + uint16_t getPCIVenderID(uint8_t bus, uint8_t slot, uint8_t function) { return readPCIConfigWord(bus, slot, function, 0); } @@ -74,7 +75,7 @@ uint16_t getPCIVenderID(uint8_t bus, uint8_t slot, uint8_t function) { * @param func * @param offset into config space * @return uint32 of the config space starting at offset. - */ + uint32_t readPCIConfigWord(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset) { uint32_t address; @@ -94,7 +95,7 @@ uint32_t readPCIConfigWord(uint8_t bus, uint8_t slot, uint8_t func, /** * check devices on bus for other buses * @param bus - */ + void checkPCIBus(uint8_t bus) { uint8_t device; //set that its a valid bus @@ -109,7 +110,7 @@ void checkPCIBus(uint8_t bus) { * @param bus * @param device * @param function - */ + void checkPCIFunction(uint8_t bus, uint8_t device, uint8_t function) { uint8_t baseClass; uint8_t subClass; @@ -128,7 +129,7 @@ void checkPCIFunction(uint8_t bus, uint8_t device, uint8_t function) { * check device's functions to see if it holds a bus * @param bus * @param device - */ + void checkPCIDevice(uint8_t bus, uint8_t device) { uint8_t function = 0; @@ -138,7 +139,7 @@ void checkPCIDevice(uint8_t bus, uint8_t device) { checkPCIFunction(bus, device, function); uint8_t headerType = getPCIHeaderType(bus, device, function); if ( (headerType & 0x80) != 0) { - /* It is a multi-function device, so check remaining functions */ + /* It is a multi-function device, so check remaining functions for (function = 1; function < 8; function++) { if (getPCIVenderID(bus, device, function) != 0xFFFF) { checkPCIFunction(bus, device, function); @@ -152,7 +153,7 @@ void checkPCIDevice(uint8_t bus, uint8_t device) { * @param device * @param function * @return base class - */ + uint8_t getPCIBaseClass(uint8_t bus, uint8_t device, uint8_t function){ return readPCIConfigWord(bus,device,function,0xB); } @@ -162,7 +163,7 @@ uint8_t getPCIBaseClass(uint8_t bus, uint8_t device, uint8_t function){ * @param device * @param function * @return sub class - */ + uint8_t getPCISubClass(uint8_t bus, uint8_t device, uint8_t function){ return readPCIConfigWord(bus,device,function,0xA); } @@ -172,7 +173,7 @@ uint8_t getPCISubClass(uint8_t bus, uint8_t device, uint8_t function){ * @param device * @param function * @return header type - */ + uint8_t getPCIHeaderType(uint8_t bus, uint8_t device, uint8_t function){ return readPCIConfigWord(bus,device,function,0xE); } @@ -182,8 +183,9 @@ uint8_t getPCIHeaderType(uint8_t bus, uint8_t device, uint8_t function){ * @param device * @param function * @return secondary bus - */ + uint8_t getPCISecondaryBus(uint8_t bus, uint8_t device, uint8_t function){ return readPCIConfigWord(bus,device,function, 0x19); } +*/ \ No newline at end of file diff --git a/src/drivers/PCI/PCI.h b/src/drivers/PCI/PCI.h index b779a352b..4dcc929a8 100644 --- a/src/drivers/PCI/PCI.h +++ b/src/drivers/PCI/PCI.h @@ -10,14 +10,15 @@ #include "Global.h" +/* extern int8_t MAX_PCI_FUNCTIONS; /** * bool array of valid PCI buses - */ + extern bool validPCIBuses[256]; /** * inits the PCI sub system. finds all PCI buses - */ + void PCIInit( ); /** * checks if the device is multifunction based on given function header type @@ -25,7 +26,7 @@ void PCIInit( ); * @param device on bus * @param function in device * @return if device is multifunction - */ + bool isPCIMultiFunctionDevice(uint8_t bus, uint8_t device, uint8_t function); /** * checks validity of function based off vender code @@ -33,7 +34,7 @@ bool isPCIMultiFunctionDevice(uint8_t bus, uint8_t device, uint8_t function); * @param device * @param function * @return if the function is a valid function - */ + bool isValidPCIFunction(uint8_t bus, uint8_t device, uint8_t function); /** * checks the vender of the pci device / function @@ -41,7 +42,7 @@ bool isValidPCIFunction(uint8_t bus, uint8_t device, uint8_t function); * @param slot * @param function * @return vender ID - */ + uint16_t getPCIVenderID(uint8_t bus, uint8_t slot, uint8_t function); /** * read 32 bits from PCI config space @@ -50,26 +51,26 @@ uint16_t getPCIVenderID(uint8_t bus, uint8_t slot, uint8_t function); * @param func * @param offset into config space * @return uint32 of the config space starting at offset. - */ + uint32_t readPCIConfigWord(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset); /** * check devices on bus for other buses * @param bus - */ + void checkPCIBus(uint8_t bus); /** * check device / function if it's a PCI bus * @param bus * @param device * @param function - */ + void checkPCIFunction(uint8_t bus, uint8_t device, uint8_t function); /** * check device's functions to see if it holds a bus * @param bus * @param device - */ + void checkPCIDevice(uint8_t bus, uint8_t device); /** * read the PCI base class from the config space @@ -77,7 +78,7 @@ void checkPCIDevice(uint8_t bus, uint8_t device); * @param device * @param function * @return base class - */ + uint8_t getPCIBaseClass(uint8_t bus, uint8_t device, uint8_t function); /** * read the PCI sub class from the config space @@ -85,7 +86,7 @@ uint8_t getPCIBaseClass(uint8_t bus, uint8_t device, uint8_t function); * @param device * @param function * @return sub class - */ + uint8_t getPCISubClass(uint8_t bus, uint8_t device, uint8_t function); /** * read the PCI header type from the config space @@ -93,7 +94,7 @@ uint8_t getPCISubClass(uint8_t bus, uint8_t device, uint8_t function); * @param device * @param function * @return header type - */ + uint8_t getPCIHeaderType(uint8_t bus, uint8_t device, uint8_t function); /** * read the PCI second bus from the config space for pci bridge devices @@ -101,7 +102,8 @@ uint8_t getPCIHeaderType(uint8_t bus, uint8_t device, uint8_t function); * @param device * @param function * @return secondary bus - */ + uint8_t getPCISecondaryBus(uint8_t bus, uint8_t device, uint8_t function); +*/ #endif /* SRC_DRIVERS_PCI_PCI_H_ */ diff --git a/src/drivers/PCI/PCIDeviceList.cpp b/src/drivers/PCI/PCIDeviceList.cpp index 4f343eb04..c673b2927 100644 --- a/src/drivers/PCI/PCIDeviceList.cpp +++ b/src/drivers/PCI/PCIDeviceList.cpp @@ -12,7 +12,7 @@ #include "drivers/PCI/PCI_devices/PCIBridgeDevice.h" #include "drivers/PCI/PCI_devices/PCICardBusDevice.h" #include "drivers/TTY/Console.h" - +/* PCIDeviceList::PCIDeviceList( ) { _list = new LinkedList; _size = 0; @@ -108,3 +108,4 @@ PCIDevice** PCIDeviceList::toArray( ) { } return listArr; } +*/ \ No newline at end of file diff --git a/src/drivers/PCI/PCIDeviceList.h b/src/drivers/PCI/PCIDeviceList.h index a5fc5ad94..eccd2c3af 100644 --- a/src/drivers/PCI/PCIDeviceList.h +++ b/src/drivers/PCI/PCIDeviceList.h @@ -9,6 +9,7 @@ #define SRC_DRIVERS_PCI_PCIDEVICELIST_H_ #include "Global.h" +/* #include "utils/linked_list/LinkedList.h" class PCIDevice; @@ -26,5 +27,5 @@ class PCIDeviceList { return _size; } }; - +*/ #endif /* SRC_DRIVERS_PCI_PCIDEVICELIST_H_ */ diff --git a/src/drivers/PCI/PCI_devices/PCIDevice.cpp b/src/drivers/PCI/PCI_devices/PCIDevice.cpp index 9aec5d883..cd9a84e1a 100644 --- a/src/drivers/PCI/PCI_devices/PCIDevice.cpp +++ b/src/drivers/PCI/PCI_devices/PCIDevice.cpp @@ -20,61 +20,61 @@ PCIDevice::PCIDevice(uint8_t bus, uint8_t device, uint8_t function, bool page) { } uint16_t PCIDevice::deviceID( ) { - return readPCIConfigWord(_bus, _device, _function, 16); + //return readPCIConfigWord(_bus, _device, _function, 16); } uint16_t PCIDevice::venderID( ) { - return readPCIConfigWord(_bus, _device, _function, 0); + //return readPCIConfigWord(_bus, _device, _function, 0); } uint16_t PCIDevice::status( ) { - return readPCIConfigWord(_bus, _device, _function, 0x04 + 16); + ///return readPCIConfigWord(_bus, _device, _function, 0x04 + 16); } uint16_t PCIDevice::command( ) { - return readPCIConfigWord(_bus, _device, _function, 0x04); + //return readPCIConfigWord(_bus, _device, _function, 0x04); } void PCIDevice::command(uint16_t com) { - (void) com; + //(void) com; } uint8_t PCIDevice::classCode( ) { - return readPCIConfigWord(_bus, _device, _function, 0x08 + 24); + //return readPCIConfigWord(_bus, _device, _function, 0x08 + 24); } uint8_t PCIDevice::subClassCode( ) { - return readPCIConfigWord(_bus, _device, _function, 0x08 + 16); + //return readPCIConfigWord(_bus, _device, _function, 0x08 + 16); } uint8_t PCIDevice::progIF( ) { - return readPCIConfigWord(_bus, _device, _function, 0x08 + 8); + //return readPCIConfigWord(_bus, _device, _function, 0x08 + 8); } uint8_t PCIDevice::revisionID( ) { - return readPCIConfigWord(_bus, _device, _function, 0x08); + //return readPCIConfigWord(_bus, _device, _function, 0x08); } uint8_t PCIDevice::BIST( ) { - return readPCIConfigWord(_bus, _device, _function, 0x0c +24); + //return readPCIConfigWord(_bus, _device, _function, 0x0c +24); } void PCIDevice::BIST(uint8_t testCode) { - (void) testCode; + //(void) testCode; } uint8_t PCIDevice::headerType( ) { - return readPCIConfigWord(_bus, _device, _function, 0x0c +16); + //return readPCIConfigWord(_bus, _device, _function, 0x0c +16); } uint8_t PCIDevice::latencyTimer( ) { - return readPCIConfigWord(_bus, _device, _function, 0x0c +8); + //return readPCIConfigWord(_bus, _device, _function, 0x0c +8); } uint8_t PCIDevice::cacheLineSize( ) { - return readPCIConfigWord(_bus, _device, _function, 0x0c); + //return readPCIConfigWord(_bus, _device, _function, 0x0c); } void PCIDevice::cacheLineSize(uint8_t lineSize) { - (void) lineSize; + //(void) lineSize; } diff --git a/src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp b/src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp index 10b9e0b4c..6d3862148 100644 --- a/src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp +++ b/src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp @@ -21,61 +21,61 @@ PCIStandardDevice::~PCIStandardDevice( ) { } uint32_t PCIStandardDevice::BAR0( ) { - return readPCIConfigWord(_bus, _device, _function, 0x10); + //return readPCIConfigWord(_bus, _device, _function, 0x10); } uint32_t PCIStandardDevice::BAR1( ) { - return readPCIConfigWord(_bus, _device, _function, 0x14); + ///return readPCIConfigWord(_bus, _device, _function, 0x14); } uint32_t PCIStandardDevice::BAR2( ) { - return readPCIConfigWord(_bus, _device, _function, 0x18); + //return readPCIConfigWord(_bus, _device, _function, 0x18); } uint32_t PCIStandardDevice::BAR3( ) { - return readPCIConfigWord(_bus, _device, _function, 0x1C); + //return readPCIConfigWord(_bus, _device, _function, 0x1C); } uint32_t PCIStandardDevice::BAR4( ) { - return readPCIConfigWord(_bus, _device, _function, 0x20); + //return readPCIConfigWord(_bus, _device, _function, 0x20); } uint32_t PCIStandardDevice::BAR5( ) { - return readPCIConfigWord(_bus, _device, _function, 0x24); + //return readPCIConfigWord(_bus, _device, _function, 0x24); } uint32_t PCIStandardDevice::cardBusCISptr( ) { - return readPCIConfigWord(_bus, _device, _function, 0x28); + //return readPCIConfigWord(_bus, _device, _function, 0x28); } uint16_t PCIStandardDevice::subsystemID( ) { - return readPCIConfigWord(_bus, _device, _function, 0x2C+16); + //return readPCIConfigWord(_bus, _device, _function, 0x2C+16); } uint16_t PCIStandardDevice::subsystemVenderID( ) { - return readPCIConfigWord(_bus, _device, _function, 0x2c); + //return readPCIConfigWord(_bus, _device, _function, 0x2c); } uint32_t PCIStandardDevice::expandROMbaseAddr( ) { - return readPCIConfigWord(_bus, _device, _function, 0x30); + //return readPCIConfigWord(_bus, _device, _function, 0x30); } uint8_t PCIStandardDevice::capabilitiesPtr( ) { - return readPCIConfigWord(_bus, _device, _function, 0x34); + //return readPCIConfigWord(_bus, _device, _function, 0x34); } uint8_t PCIStandardDevice::interruptLine( ) { - return readPCIConfigWord(_bus, _device, _function, 0x3c); + //return readPCIConfigWord(_bus, _device, _function, 0x3c); } uint8_t PCIStandardDevice::interruptPin( ) { - return readPCIConfigWord(_bus, _device, _function, 0x3c+8); + //return readPCIConfigWord(_bus, _device, _function, 0x3c+8); } uint8_t PCIStandardDevice::minGrant( ) { - return readPCIConfigWord(_bus, _device, _function, 0x3c+16); + //return readPCIConfigWord(_bus, _device, _function, 0x3c+16); } uint8_t PCIStandardDevice::maxLatency( ) { - return readPCIConfigWord(_bus, _device, _function, 0x3c+24); + //return readPCIConfigWord(_bus, _device, _function, 0x3c+24); } From 8a06e7e25cc81b19667931fd96a0467ada9c4ef0 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 19 Feb 2018 15:49:47 -0600 Subject: [PATCH 083/171] read pci config word --- src/drivers/PCI/PCI.c | 14 ++++++++++++++ src/drivers/PCI/PCI.h | 18 +++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/drivers/PCI/PCI.c b/src/drivers/PCI/PCI.c index 425baa4f3..4c04870a6 100644 --- a/src/drivers/PCI/PCI.c +++ b/src/drivers/PCI/PCI.c @@ -7,6 +7,20 @@ #include "drivers/PCI/PCI.h" +uint32_t readPCIConfigWord(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset) +{ + ConfigAddress addr; + addr.enable = 1; + addr.zero1 = 0; + addr.zero2 = 0; + addr.registerNum = offset; + addr.functionNum = function; + addr.deviceNum = device; + addr.busNum = bus; + outl(0xcf8, *(uint32_t*)&addr); + return inl(0xCFC); +} + /* //TODO clean up a lot diff --git a/src/drivers/PCI/PCI.h b/src/drivers/PCI/PCI.h index 4dcc929a8..5c47b1dfc 100644 --- a/src/drivers/PCI/PCI.h +++ b/src/drivers/PCI/PCI.h @@ -10,8 +10,24 @@ #include "Global.h" -/* extern int8_t MAX_PCI_FUNCTIONS; + +struct ConfigAddress +{ + uint8_t zero1 : 2; + uint8_t registerNum : 6; + uint8_t functionNum : 3; + uint8_t deviceNum : 5; + uint8_t busNum : 8; + uint8_t zero2 : 7; + uint8_t enable : 1; +}; + +uint32_t +readPCIConfigWord(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset); + +/* + /** * bool array of valid PCI buses From 71ab8df1da8612db0233002699a55afdf615d514 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 19 Feb 2018 18:17:56 -0600 Subject: [PATCH 084/171] enum all pci devices struct --- src/drivers/PCI/PCI.c | 25 +++++++++++++++++++++++-- src/drivers/PCI/PCI.h | 12 +++++++++--- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/drivers/PCI/PCI.c b/src/drivers/PCI/PCI.c index 4c04870a6..f495cb92e 100644 --- a/src/drivers/PCI/PCI.c +++ b/src/drivers/PCI/PCI.c @@ -7,6 +7,8 @@ #include "drivers/PCI/PCI.h" +uint8_t MAX_PCI_FUNCTIONS = 7; + uint32_t readPCIConfigWord(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset) { ConfigAddress addr; @@ -17,14 +19,33 @@ uint32_t readPCIConfigWord(uint8_t bus, uint8_t device, uint8_t function, uint8_ addr.functionNum = function; addr.deviceNum = device; addr.busNum = bus; - outl(0xcf8, *(uint32_t*)&addr); + outl(0xcf8, *(uint32_t *)&addr); return inl(0xCFC); } +void enumPCIDevices() +{ + for (uint8_t func = 0; func <= MAX_PCI_FUNCTIONS; func++) + { + if (getPCIVender(0, 0, func) == 0xFFFF) + { + checkPCIBus(func); + } + } +} + +uint16_t getPCIVender(uint8_t bus, uint8_t device, uint8_t function){ + +} + +void checkPCIBus(uint8_t bus){ + +} + /* //TODO clean up a lot -uint8_t MAX_PCI_FUNCTION = 8; + /** * bool array of valid PCI buses diff --git a/src/drivers/PCI/PCI.h b/src/drivers/PCI/PCI.h index 5c47b1dfc..233e0403a 100644 --- a/src/drivers/PCI/PCI.h +++ b/src/drivers/PCI/PCI.h @@ -10,7 +10,7 @@ #include "Global.h" -extern int8_t MAX_PCI_FUNCTIONS; +extern uint8_t MAX_PCI_FUNCTIONS; struct ConfigAddress { @@ -23,8 +23,14 @@ struct ConfigAddress uint8_t enable : 1; }; -uint32_t -readPCIConfigWord(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset); +uint32_t readPCIConfigWord(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset); + +void enumPCIDevices(); + +uint16_t getPCIVender(uint8_t bus, uint8_t device, uint8_t function); + +void checkPCIBus(uint8_t bus); + /* From 46a5ebc52393fb2b6c869db38f8d154e9fd1e89d Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 20 Feb 2018 07:04:22 -0600 Subject: [PATCH 085/171] get vender ID --- src/drivers/PCI/PCI.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/PCI/PCI.c b/src/drivers/PCI/PCI.c index f495cb92e..d6572d49d 100644 --- a/src/drivers/PCI/PCI.c +++ b/src/drivers/PCI/PCI.c @@ -35,7 +35,7 @@ void enumPCIDevices() } uint16_t getPCIVender(uint8_t bus, uint8_t device, uint8_t function){ - + return readPCIConfigWord(bus, device, function, 0) & 0xFFFF; } void checkPCIBus(uint8_t bus){ From 00e1ee92dda276928136a75a3a33b8659fb6b710 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 20 Feb 2018 07:06:41 -0600 Subject: [PATCH 086/171] check PCI bus's devices --- src/drivers/PCI/PCI.c | 5 ++++- src/drivers/PCI/PCI.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/drivers/PCI/PCI.c b/src/drivers/PCI/PCI.c index d6572d49d..4efc443a7 100644 --- a/src/drivers/PCI/PCI.c +++ b/src/drivers/PCI/PCI.c @@ -8,6 +8,7 @@ #include "drivers/PCI/PCI.h" uint8_t MAX_PCI_FUNCTIONS = 7; +uint8_t MAX_PCI_DEVICES_PER_BUS =32; uint32_t readPCIConfigWord(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset) { @@ -39,7 +40,9 @@ uint16_t getPCIVender(uint8_t bus, uint8_t device, uint8_t function){ } void checkPCIBus(uint8_t bus){ - + for (uint8_t device =0; device < MAX_PCI_DEVICES_PER_BUS; device++){ + //checkDevice + } } /* diff --git a/src/drivers/PCI/PCI.h b/src/drivers/PCI/PCI.h index 233e0403a..58dba63c4 100644 --- a/src/drivers/PCI/PCI.h +++ b/src/drivers/PCI/PCI.h @@ -11,6 +11,7 @@ #include "Global.h" extern uint8_t MAX_PCI_FUNCTIONS; +extern uint8_t MAX_PCI_DEVICES_PER_BUS; struct ConfigAddress { From 95607f009de70e4abe72fe45d676b3c63077bd58 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 20 Feb 2018 07:17:40 -0600 Subject: [PATCH 087/171] check devices and functions on a bus --- src/drivers/PCI/PCI.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/drivers/PCI/PCI.c b/src/drivers/PCI/PCI.c index 4efc443a7..6194c4846 100644 --- a/src/drivers/PCI/PCI.c +++ b/src/drivers/PCI/PCI.c @@ -41,7 +41,11 @@ uint16_t getPCIVender(uint8_t bus, uint8_t device, uint8_t function){ void checkPCIBus(uint8_t bus){ for (uint8_t device =0; device < MAX_PCI_DEVICES_PER_BUS; device++){ - //checkDevice + for (uint8_t func = 0; func < MAX_PCI_FUNCTIONS; func++){ + if (getPCIVender(bus, device, func) != 0xFFFF){ + //check function + } + } } } From bcb8ea262f9c51707c785fce8bec75f0f65bc965 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 20 Feb 2018 07:38:24 -0600 Subject: [PATCH 088/171] fixed a thing and started checking devices --- makefile.inc | 2 +- src/Kernel.cpp | 3 +++ src/drivers/PCI/PCI.c | 28 ++++++++++++++++++++-------- src/drivers/PCI/PCI.h | 4 ++++ 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/makefile.inc b/makefile.inc index c7fe43e88..5838932ff 100644 --- a/makefile.inc +++ b/makefile.inc @@ -3,7 +3,7 @@ GPP = i686-elf-g++ GCC = i686-elf-gcc OS_CPP = /Users/garrettbattaglia/Documents/dev/Exos/exos -BUILD_TO = $(OS_CPP)/../kernel.bin +BUILD_TO = $(OS_CPP)/kernel.bin CFLAGS = $(CFLAGS_CUSTOM) -c -ffreestanding -O2 -Wall -Wextra -fno-rtti -fno-exceptions -g -std=gnu++14 -I$(OS_CPP)/src OBJ_DIR = $(OS_CPP)/build diff --git a/src/Kernel.cpp b/src/Kernel.cpp index e66127ada..2df32d7dd 100644 --- a/src/Kernel.cpp +++ b/src/Kernel.cpp @@ -64,6 +64,9 @@ void kernelMain(multiboot_info_t *mbd) terminalWriteString(" Finding PCI buses..."); //find the valid PCI buses //PCIInit(); + //test code + enumPCIDevices(); + terminalWriteLine(" Done!"); terminalWriteString(" Finding USB host controllers..."); //find the (3 or less) USB host controllers. all have the same class/subclass code. diff --git a/src/drivers/PCI/PCI.c b/src/drivers/PCI/PCI.c index 6194c4846..6a31ec7d5 100644 --- a/src/drivers/PCI/PCI.c +++ b/src/drivers/PCI/PCI.c @@ -6,9 +6,10 @@ */ #include "drivers/PCI/PCI.h" +#include "utils/printf/Printf.h" uint8_t MAX_PCI_FUNCTIONS = 7; -uint8_t MAX_PCI_DEVICES_PER_BUS =32; +uint8_t MAX_PCI_DEVICES_PER_BUS = 32; uint32_t readPCIConfigWord(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset) { @@ -30,25 +31,36 @@ void enumPCIDevices() { if (getPCIVender(0, 0, func) == 0xFFFF) { - checkPCIBus(func); + break; } + checkPCIBus(func); } } -uint16_t getPCIVender(uint8_t bus, uint8_t device, uint8_t function){ +uint16_t getPCIVender(uint8_t bus, uint8_t device, uint8_t function) +{ return readPCIConfigWord(bus, device, function, 0) & 0xFFFF; } -void checkPCIBus(uint8_t bus){ - for (uint8_t device =0; device < MAX_PCI_DEVICES_PER_BUS; device++){ - for (uint8_t func = 0; func < MAX_PCI_FUNCTIONS; func++){ - if (getPCIVender(bus, device, func) != 0xFFFF){ - //check function +void checkPCIBus(uint8_t bus) +{ + for (uint8_t device = 0; device < MAX_PCI_DEVICES_PER_BUS; device++) + { + for (uint8_t func = 0; func < MAX_PCI_FUNCTIONS; func++) + { + if (getPCIVender(bus, device, func) != 0xFFFF) + { + checkPCIFunction(bus, device, func); } } } } +void checkPCIFunction(uint8_t bus, uint8_t device, uint8_t func) +{ + printf(" found device at bus: %d, device: %d, func: %d\n", bus, device, func); +} + /* //TODO clean up a lot diff --git a/src/drivers/PCI/PCI.h b/src/drivers/PCI/PCI.h index 58dba63c4..415cb09b6 100644 --- a/src/drivers/PCI/PCI.h +++ b/src/drivers/PCI/PCI.h @@ -32,6 +32,10 @@ uint16_t getPCIVender(uint8_t bus, uint8_t device, uint8_t function); void checkPCIBus(uint8_t bus); +void checkPCIFunction(uint8_t bus, uint8_t device, uint8_t func); + +uint16_t getPCIClass(uint8_t bus, uint8_t device, uint8_t func); + /* From f4ef8350ccac37a582b583f879f96efebad4386d Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 20 Feb 2018 07:57:31 -0600 Subject: [PATCH 089/171] read the config and print it --- src/drivers/PCI/PCI.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/drivers/PCI/PCI.c b/src/drivers/PCI/PCI.c index 6a31ec7d5..44e04a47a 100644 --- a/src/drivers/PCI/PCI.c +++ b/src/drivers/PCI/PCI.c @@ -58,9 +58,14 @@ void checkPCIBus(uint8_t bus) void checkPCIFunction(uint8_t bus, uint8_t device, uint8_t func) { - printf(" found device at bus: %d, device: %d, func: %d\n", bus, device, func); + printf(" found device at bus: %d, device: %d, func: %d\n", bus, device, func); + uint16_t classCode = getPCIClass(bus, device, func); + printf(" Has a class code of %x\n", classCode); } +uint16_t getPCIClass(uint8_t bus, uint8_t device, uint8_t func){ + return readPCIConfigWord(bus, device, func, 0x0A) & 0xFFFF; +} /* //TODO clean up a lot From be3c440c3c225e1a9c5deab05b4b5f7c04a794c4 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 20 Feb 2018 08:04:59 -0600 Subject: [PATCH 090/171] fixed a few things --- -ffreestanding | Bin 0 -> 165476 bytes makefile.inc | 6 ++++-- src/drivers/generic/CharDevice.h | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) create mode 100755 -ffreestanding diff --git a/-ffreestanding b/-ffreestanding new file mode 100755 index 0000000000000000000000000000000000000000..4420c1a288d3cde90b7eb6278600d15bce7eed57 GIT binary patch literal 165476 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 D&_6^O literal 0 HcmV?d00001 diff --git a/makefile.inc b/makefile.inc index 5838932ff..545cc54aa 100644 --- a/makefile.inc +++ b/makefile.inc @@ -2,8 +2,10 @@ AS = i686-elf-as GPP = i686-elf-g++ GCC = i686-elf-gcc -OS_CPP = /Users/garrettbattaglia/Documents/dev/Exos/exos -BUILD_TO = $(OS_CPP)/kernel.bin +OS_CPP=/home/garrett/workspace/exos +BUILD_T0=/mnt/boot/kernel.bin +#OS_CPP = /Users/garrettbattaglia/Documents/dev/Exos/exos +#BUILD_TO = $(OS_CPP)/kernel.bin CFLAGS = $(CFLAGS_CUSTOM) -c -ffreestanding -O2 -Wall -Wextra -fno-rtti -fno-exceptions -g -std=gnu++14 -I$(OS_CPP)/src OBJ_DIR = $(OS_CPP)/build diff --git a/src/drivers/generic/CharDevice.h b/src/drivers/generic/CharDevice.h index dd9c0d774..cf2219412 100644 --- a/src/drivers/generic/CharDevice.h +++ b/src/drivers/generic/CharDevice.h @@ -1,7 +1,7 @@ #ifndef CHARDEVICE_H_ #define CHARDEVICE_H_ #include "Global.h" -#include "device.h" +#include "Device.h" class CharDevice : public Device { @@ -11,4 +11,4 @@ class CharDevice : public Device virtual char read()=0; }; -#endif \ No newline at end of file +#endif From 05e5a351797b2c9c659e4204bf734f5e174ba535 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 20 Feb 2018 09:54:33 -0600 Subject: [PATCH 091/171] this should scan all buses for all devices --- -ffreestanding | Bin 165476 -> 0 bytes makefile.inc | 8 +++--- src/drivers/PCI/PCI.c | 60 +++++++++++++++++++++++++++--------------- src/drivers/PCI/PCI.h | 5 ++-- 4 files changed, 46 insertions(+), 27 deletions(-) delete mode 100755 -ffreestanding diff --git a/-ffreestanding b/-ffreestanding deleted file mode 100755 index 4420c1a288d3cde90b7eb6278600d15bce7eed57..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 165476 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 D&_6^O diff --git a/makefile.inc b/makefile.inc index 545cc54aa..77a28ebed 100644 --- a/makefile.inc +++ b/makefile.inc @@ -2,10 +2,10 @@ AS = i686-elf-as GPP = i686-elf-g++ GCC = i686-elf-gcc -OS_CPP=/home/garrett/workspace/exos -BUILD_T0=/mnt/boot/kernel.bin -#OS_CPP = /Users/garrettbattaglia/Documents/dev/Exos/exos -#BUILD_TO = $(OS_CPP)/kernel.bin +#OS_CPP=/home/garrett/workspace/exos +#BUILD_T0=/mnt/boot/kernel.bin +OS_CPP = /Users/garrettbattaglia/Documents/dev/Exos/exos +BUILD_TO = $(OS_CPP)/kernel.bin CFLAGS = $(CFLAGS_CUSTOM) -c -ffreestanding -O2 -Wall -Wextra -fno-rtti -fno-exceptions -g -std=gnu++14 -I$(OS_CPP)/src OBJ_DIR = $(OS_CPP)/build diff --git a/src/drivers/PCI/PCI.c b/src/drivers/PCI/PCI.c index 44e04a47a..d93b71f85 100644 --- a/src/drivers/PCI/PCI.c +++ b/src/drivers/PCI/PCI.c @@ -8,22 +8,25 @@ #include "drivers/PCI/PCI.h" #include "utils/printf/Printf.h" + uint8_t MAX_PCI_FUNCTIONS = 7; uint8_t MAX_PCI_DEVICES_PER_BUS = 32; -uint32_t readPCIConfigWord(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset) +/*uint32_t readPCIConfigWord(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset) { ConfigAddress addr; addr.enable = 1; addr.zero1 = 0; addr.zero2 = 0; - addr.registerNum = offset; + addr.registerNum = offset & 0xFC; addr.functionNum = function; addr.deviceNum = device; addr.busNum = bus; + //printf("reading PCI register: %x\n", *(uint32_t *)&addr); outl(0xcf8, *(uint32_t *)&addr); + //printf( "read %x", inl(0xCFC)); return inl(0xCFC); -} +}*/ void enumPCIDevices() { @@ -58,14 +61,26 @@ void checkPCIBus(uint8_t bus) void checkPCIFunction(uint8_t bus, uint8_t device, uint8_t func) { - printf(" found device at bus: %d, device: %d, func: %d\n", bus, device, func); - uint16_t classCode = getPCIClass(bus, device, func); - printf(" Has a class code of %x\n", classCode); + //printf(" Found device at bus: %d, device: %d, func: %d\n", bus, device, func); + //printf(" The vender id is %x\n", getPCIVender(bus,device,func)); + uint32_t classCode = getPCIClass(bus, device, func); + //printf(" Has a class code of %x\n", classCode); + if (classCode == 0x604) { + uint8_t secondBus = getPCISecondBus(bus,device,func); + printf(" is a PCI->PCI with a 2nd bus of %d", secondBus); + checkPCIBus(secondBus); + } } -uint16_t getPCIClass(uint8_t bus, uint8_t device, uint8_t func){ - return readPCIConfigWord(bus, device, func, 0x0A) & 0xFFFF; +uint32_t getPCIClass(uint8_t bus, uint8_t device, uint8_t func){ + return readPCIConfigWord(bus, device, func, 10); } + +uint8_t getPCISecondBus(uint8_t bus, uint8_t device, uint8_t func){ + printf("2nd bus: %d", readPCIConfigWord(bus,device,func, 18)); + return readPCIConfigWord(bus,device,func,18) >> 8; +} + /* //TODO clean up a lot @@ -134,22 +149,25 @@ uint16_t getPCIVenderID(uint8_t bus, uint8_t slot, uint8_t function) { * @param func * @param offset into config space * @return uint32 of the config space starting at offset. - + */ uint32_t readPCIConfigWord(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset) { uint32_t address; - uint32_t lbus = (uint32_t) bus; - uint32_t lslot = (uint32_t) slot; - uint32_t lfunc = (uint32_t) func; - uint32_t tmp = 0; - - address = (uint32_t)( - (lbus << 16) | (lslot << 11) | (lfunc << 8) | (offset & 0xfc) - | ((uint32_t) 0x80000000)); - - outl(0xCF8, address); - tmp = inl(0xCFC); - return (tmp); + uint32_t lbus = (uint32_t)bus; + uint32_t lslot = (uint32_t)slot; + uint32_t lfunc = (uint32_t)func; + uint16_t tmp = 0; + + /* create configuration address as per Figure 1 */ + address = (uint32_t)((lbus << 16) | (lslot << 11) | + (lfunc << 8) | (offset & 0xfc) | ((uint32_t)0x80000000)); + + /* write out the address */ + outl (0xCF8, address); + /* read in the data */ + /* (offset & 2) * 8) = 0 will choose the first word of the 32 bits register */ + tmp = (uint16_t)((inl (0xCFC) >> ((offset & 2) * 8)) & 0xffff); + return (tmp); } /** * check devices on bus for other buses diff --git a/src/drivers/PCI/PCI.h b/src/drivers/PCI/PCI.h index 415cb09b6..03ddac7ae 100644 --- a/src/drivers/PCI/PCI.h +++ b/src/drivers/PCI/PCI.h @@ -22,7 +22,7 @@ struct ConfigAddress uint8_t busNum : 8; uint8_t zero2 : 7; uint8_t enable : 1; -}; +} __attribute__((__packed__)); uint32_t readPCIConfigWord(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset); @@ -34,8 +34,9 @@ void checkPCIBus(uint8_t bus); void checkPCIFunction(uint8_t bus, uint8_t device, uint8_t func); -uint16_t getPCIClass(uint8_t bus, uint8_t device, uint8_t func); +uint32_t getPCIClass(uint8_t bus, uint8_t device, uint8_t func); +uint8_t getPCISecondBus(uint8_t bus, uint8_t device, uint8_t func); /* From ce59b17ae619cd2f632d7e84ce5228b11f2ecb34 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 20 Feb 2018 10:00:14 -0600 Subject: [PATCH 092/171] protection --- src/drivers/PCI/PCI.c | 62 ++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/src/drivers/PCI/PCI.c b/src/drivers/PCI/PCI.c index d93b71f85..0907a96ae 100644 --- a/src/drivers/PCI/PCI.c +++ b/src/drivers/PCI/PCI.c @@ -8,7 +8,6 @@ #include "drivers/PCI/PCI.h" #include "utils/printf/Printf.h" - uint8_t MAX_PCI_FUNCTIONS = 7; uint8_t MAX_PCI_DEVICES_PER_BUS = 32; @@ -61,24 +60,30 @@ void checkPCIBus(uint8_t bus) void checkPCIFunction(uint8_t bus, uint8_t device, uint8_t func) { - //printf(" Found device at bus: %d, device: %d, func: %d\n", bus, device, func); - //printf(" The vender id is %x\n", getPCIVender(bus,device,func)); + printf(" Found device at bus: %d, device: %d, func: %d\n", bus, device, func); + printf(" The vender id is %x\n", getPCIVender(bus, device, func)); uint32_t classCode = getPCIClass(bus, device, func); - //printf(" Has a class code of %x\n", classCode); - if (classCode == 0x604) { - uint8_t secondBus = getPCISecondBus(bus,device,func); - printf(" is a PCI->PCI with a 2nd bus of %d", secondBus); - checkPCIBus(secondBus); + printf(" Has a class code of %x\n", classCode); + if (classCode == 0x604) + { + uint8_t secondBus = getPCISecondBus(bus, device, func); + printf(" is a PCI->PCI with a 2nd bus of %d\n", secondBus); + if (secondBus != bus) + { + checkPCIBus(secondBus); + } } } -uint32_t getPCIClass(uint8_t bus, uint8_t device, uint8_t func){ +uint32_t getPCIClass(uint8_t bus, uint8_t device, uint8_t func) +{ return readPCIConfigWord(bus, device, func, 10); } -uint8_t getPCISecondBus(uint8_t bus, uint8_t device, uint8_t func){ - printf("2nd bus: %d", readPCIConfigWord(bus,device,func, 18)); - return readPCIConfigWord(bus,device,func,18) >> 8; +uint8_t getPCISecondBus(uint8_t bus, uint8_t device, uint8_t func) +{ + printf("2nd bus: %d", readPCIConfigWord(bus, device, func, 18)); + return readPCIConfigWord(bus, device, func, 18) >> 8; } /* @@ -151,23 +156,24 @@ uint16_t getPCIVenderID(uint8_t bus, uint8_t slot, uint8_t function) { * @return uint32 of the config space starting at offset. */ uint32_t readPCIConfigWord(uint8_t bus, uint8_t slot, uint8_t func, - uint8_t offset) { + uint8_t offset) +{ uint32_t address; - uint32_t lbus = (uint32_t)bus; - uint32_t lslot = (uint32_t)slot; - uint32_t lfunc = (uint32_t)func; - uint16_t tmp = 0; - - /* create configuration address as per Figure 1 */ - address = (uint32_t)((lbus << 16) | (lslot << 11) | - (lfunc << 8) | (offset & 0xfc) | ((uint32_t)0x80000000)); - - /* write out the address */ - outl (0xCF8, address); - /* read in the data */ - /* (offset & 2) * 8) = 0 will choose the first word of the 32 bits register */ - tmp = (uint16_t)((inl (0xCFC) >> ((offset & 2) * 8)) & 0xffff); - return (tmp); + uint32_t lbus = (uint32_t)bus; + uint32_t lslot = (uint32_t)slot; + uint32_t lfunc = (uint32_t)func; + uint16_t tmp = 0; + + /* create configuration address as per Figure 1 */ + address = (uint32_t)((lbus << 16) | (lslot << 11) | + (lfunc << 8) | (offset & 0xfc) | ((uint32_t)0x80000000)); + + /* write out the address */ + outl(0xCF8, address); + /* read in the data */ + /* (offset & 2) * 8) = 0 will choose the first word of the 32 bits register */ + tmp = (uint16_t)((inl(0xCFC) >> ((offset & 2) * 8)) & 0xffff); + return (tmp); } /** * check devices on bus for other buses From b3be116e42b045ce96e19137caf0bbead95a38ec Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 20 Feb 2018 13:53:14 -0600 Subject: [PATCH 093/171] hex not dec --- src/drivers/PCI/PCI.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/drivers/PCI/PCI.c b/src/drivers/PCI/PCI.c index 0907a96ae..5fa35b50d 100644 --- a/src/drivers/PCI/PCI.c +++ b/src/drivers/PCI/PCI.c @@ -77,13 +77,12 @@ void checkPCIFunction(uint8_t bus, uint8_t device, uint8_t func) uint32_t getPCIClass(uint8_t bus, uint8_t device, uint8_t func) { - return readPCIConfigWord(bus, device, func, 10); + return readPCIConfigWord(bus, device, func, 0x0A); } uint8_t getPCISecondBus(uint8_t bus, uint8_t device, uint8_t func) { - printf("2nd bus: %d", readPCIConfigWord(bus, device, func, 18)); - return readPCIConfigWord(bus, device, func, 18) >> 8; + return readPCIConfigWord(bus, device, func, 0x18) >> 8; } /* From 918e60d0f90c9ee8f1383ba30b703cae45199837 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 20 Feb 2018 14:00:50 -0600 Subject: [PATCH 094/171] more prints --- src/drivers/PCI/PCI.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/drivers/PCI/PCI.c b/src/drivers/PCI/PCI.c index 5fa35b50d..4cc6f230f 100644 --- a/src/drivers/PCI/PCI.c +++ b/src/drivers/PCI/PCI.c @@ -46,6 +46,7 @@ uint16_t getPCIVender(uint8_t bus, uint8_t device, uint8_t function) void checkPCIBus(uint8_t bus) { + printf(" Checking bus: %d\n", bus) for (uint8_t device = 0; device < MAX_PCI_DEVICES_PER_BUS; device++) { for (uint8_t func = 0; func < MAX_PCI_FUNCTIONS; func++) @@ -60,18 +61,15 @@ void checkPCIBus(uint8_t bus) void checkPCIFunction(uint8_t bus, uint8_t device, uint8_t func) { - printf(" Found device at bus: %d, device: %d, func: %d\n", bus, device, func); - printf(" The vender id is %x\n", getPCIVender(bus, device, func)); + printf(" Found device at bus: %d, device: %d, func: %d\n", bus, device, func); + printf(" The vender id is %x\n", getPCIVender(bus, device, func)); uint32_t classCode = getPCIClass(bus, device, func); printf(" Has a class code of %x\n", classCode); if (classCode == 0x604) { uint8_t secondBus = getPCISecondBus(bus, device, func); - printf(" is a PCI->PCI with a 2nd bus of %d\n", secondBus); - if (secondBus != bus) - { + printf(" is a PCI->PCI with a 2nd bus of %d\n", secondBus); checkPCIBus(secondBus); - } } } From 0e3a2e8130027bb99fb8c6d284594f6d19f59773 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 20 Feb 2018 14:02:10 -0600 Subject: [PATCH 095/171] oups --- src/drivers/PCI/PCI.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/PCI/PCI.c b/src/drivers/PCI/PCI.c index 4cc6f230f..7778ad49c 100644 --- a/src/drivers/PCI/PCI.c +++ b/src/drivers/PCI/PCI.c @@ -46,7 +46,7 @@ uint16_t getPCIVender(uint8_t bus, uint8_t device, uint8_t function) void checkPCIBus(uint8_t bus) { - printf(" Checking bus: %d\n", bus) + printf(" Checking bus: %d\n", bus); for (uint8_t device = 0; device < MAX_PCI_DEVICES_PER_BUS; device++) { for (uint8_t func = 0; func < MAX_PCI_FUNCTIONS; func++) From 2f99578dfdb68bbf3f55639c7b1b48a802d3950e Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 27 Feb 2018 10:08:25 -0600 Subject: [PATCH 096/171] handle devies based on class --- src/drivers/PCI/PCI.c | 35 ++++++++++++++++++++++++++++++++--- src/drivers/PCI/USB/USB.c | 4 ++++ src/drivers/PCI/USB/USB.h | 1 + 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/drivers/PCI/PCI.c b/src/drivers/PCI/PCI.c index 7778ad49c..dc0536fbd 100644 --- a/src/drivers/PCI/PCI.c +++ b/src/drivers/PCI/PCI.c @@ -7,6 +7,7 @@ #include "drivers/PCI/PCI.h" #include "utils/printf/Printf.h" +#include "USB/USB.h" uint8_t MAX_PCI_FUNCTIONS = 7; uint8_t MAX_PCI_DEVICES_PER_BUS = 32; @@ -61,16 +62,44 @@ void checkPCIBus(uint8_t bus) void checkPCIFunction(uint8_t bus, uint8_t device, uint8_t func) { + asm("hlt"); printf(" Found device at bus: %d, device: %d, func: %d\n", bus, device, func); printf(" The vender id is %x\n", getPCIVender(bus, device, func)); uint32_t classCode = getPCIClass(bus, device, func); - printf(" Has a class code of %x\n", classCode); - if (classCode == 0x604) + printf(" Has a class code of %x\n", classCode); + uint8_t baseClass = (classCode >> 8) & 0xFF; + uint8_t subClass = classCode & 0xFF; + switch (baseClass) + { + case 0x06: + { + if (subClass == 0x04) + { + uint8_t secondBus = getPCISecondBus(bus, device, func); + printf(" is a PCI->PCI with a 2nd bus of %d\n", secondBus); + checkPCIBus(secondBus); + } + } + case 0x0C: + { + if (subClass == 0x03){ + addUSBHostController(bus, device, func); + printf(" This is a USB host controller\n"); + } + break; + } + default: + { + printf(" This device is unkown\n"); + break; + } + } + /*if (classCode == 0x604) { uint8_t secondBus = getPCISecondBus(bus, device, func); printf(" is a PCI->PCI with a 2nd bus of %d\n", secondBus); checkPCIBus(secondBus); - } + }*/ } uint32_t getPCIClass(uint8_t bus, uint8_t device, uint8_t func) diff --git a/src/drivers/PCI/USB/USB.c b/src/drivers/PCI/USB/USB.c index e9cb4b5d2..ca16fd712 100644 --- a/src/drivers/PCI/USB/USB.c +++ b/src/drivers/PCI/USB/USB.c @@ -21,3 +21,7 @@ void USBInit(){//how it works: //set max USB version } +//todo types +void addUSBHostController(int bus, int device, int function){ + +} diff --git a/src/drivers/PCI/USB/USB.h b/src/drivers/PCI/USB/USB.h index 78786cc50..13e257b33 100644 --- a/src/drivers/PCI/USB/USB.h +++ b/src/drivers/PCI/USB/USB.h @@ -15,6 +15,7 @@ extern uint8_t maxUSBVersion; extern USBController* uSBControllers; void USBInit(); +void addUSBHostController(int bus, int device, int function); #endif /* SRC_DRIVERS_PCI_USB_USB_H_ */ From cd1172c4ae5f63294fcd4725bb2d12c8e42052de Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 27 Feb 2018 13:40:36 -0600 Subject: [PATCH 097/171] basic structure for creating a USB HCI --- src/drivers/PCI/PCI.c | 4 ++++ src/drivers/PCI/PCI.h | 2 ++ src/drivers/PCI/USB/USB.c | 36 +++++++++++++++++++++++++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/drivers/PCI/PCI.c b/src/drivers/PCI/PCI.c index dc0536fbd..e5531f927 100644 --- a/src/drivers/PCI/PCI.c +++ b/src/drivers/PCI/PCI.c @@ -12,6 +12,10 @@ uint8_t MAX_PCI_FUNCTIONS = 7; uint8_t MAX_PCI_DEVICES_PER_BUS = 32; +uint8_t getPCIProgIF(uint8_t bus, uint8_t device, uint8_t function){ + return (readPCIConfigWord(bus, device, function, 0x08) >> 8) & 0xFFFF; +} + /*uint32_t readPCIConfigWord(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset) { ConfigAddress addr; diff --git a/src/drivers/PCI/PCI.h b/src/drivers/PCI/PCI.h index 03ddac7ae..b18903c9d 100644 --- a/src/drivers/PCI/PCI.h +++ b/src/drivers/PCI/PCI.h @@ -24,6 +24,8 @@ struct ConfigAddress uint8_t enable : 1; } __attribute__((__packed__)); +uint8_t getPCIProgIF(uint8_t bus, uint8_t device, uint8_t function) + uint32_t readPCIConfigWord(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset); void enumPCIDevices(); diff --git a/src/drivers/PCI/USB/USB.c b/src/drivers/PCI/USB/USB.c index ca16fd712..747d75df4 100644 --- a/src/drivers/PCI/USB/USB.c +++ b/src/drivers/PCI/USB/USB.c @@ -6,7 +6,9 @@ */ #include "drivers/PCI/USB/USB.h" +#include "drivers/PCI/PCI.h" +//TODO better host coontroller marking uint8_t maxUSBVersion = 0; USBController* uSBControllers; @@ -23,5 +25,37 @@ void USBInit(){//how it works: //todo types void addUSBHostController(int bus, int device, int function){ - + uint8_t progIF = getPCIProgIF(bus, device, function); + switch (progIF){ + case 0x00:{ + //UHCI + break; + } + case 0x10:{ + //OHCI + break; + } + case 0x20:{ + //EHCI + break; + } + case 0x30:{ + //XHCI + break; + } + case 0x80:{ + //OTHER HCI + break; + } + case 0xFE{ + //Not a HCI + break; + } + default:{ + //error + } + } + //create correct object + //store in array + //mark as valid host controller } From 8e891632c5740504dea2ad51a3e123fda2a275df Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Wed, 28 Feb 2018 19:56:49 -0600 Subject: [PATCH 098/171] fixed a few syntax errors --- src/drivers/PCI/PCI.h | 2 +- src/drivers/PCI/USB/USB.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/drivers/PCI/PCI.h b/src/drivers/PCI/PCI.h index b18903c9d..fe8de0351 100644 --- a/src/drivers/PCI/PCI.h +++ b/src/drivers/PCI/PCI.h @@ -24,7 +24,7 @@ struct ConfigAddress uint8_t enable : 1; } __attribute__((__packed__)); -uint8_t getPCIProgIF(uint8_t bus, uint8_t device, uint8_t function) +uint8_t getPCIProgIF(uint8_t bus, uint8_t device, uint8_t function); uint32_t readPCIConfigWord(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset); diff --git a/src/drivers/PCI/USB/USB.c b/src/drivers/PCI/USB/USB.c index 747d75df4..727e876a5 100644 --- a/src/drivers/PCI/USB/USB.c +++ b/src/drivers/PCI/USB/USB.c @@ -47,7 +47,7 @@ void addUSBHostController(int bus, int device, int function){ //OTHER HCI break; } - case 0xFE{ + case 0xFE:{ //Not a HCI break; } From d1623dbf9bacc3b2de0744bd162f53b4b26b584b Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Fri, 2 Mar 2018 16:07:19 -0600 Subject: [PATCH 099/171] fixed issue #49 --- src/drivers/PCI/PCI.c | 72 +++++++++++++++++++++++-------------------- src/drivers/PCI/PCI.h | 5 +-- 2 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/drivers/PCI/PCI.c b/src/drivers/PCI/PCI.c index e5531f927..9c3206d7b 100644 --- a/src/drivers/PCI/PCI.c +++ b/src/drivers/PCI/PCI.c @@ -16,24 +16,56 @@ uint8_t getPCIProgIF(uint8_t bus, uint8_t device, uint8_t function){ return (readPCIConfigWord(bus, device, function, 0x08) >> 8) & 0xFFFF; } -/*uint32_t readPCIConfigWord(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset) +//TODO rewrite +/** + * read 32 bits from PCI config space + * @param bus + * @param slot + * @param func + * @param offset into config space + * @return uint32 of the config space starting at offset. + */ +/*uint32_t readPCIConfigWord(uint8_t bus, uint8_t slot, uint8_t func, + uint8_t offset) +{ + uint32_t address; + uint32_t lbus = (uint32_t)bus; + uint32_t lslot = (uint32_t)slot; + uint32_t lfunc = (uint32_t)func; + uint16_t tmp = 0; + + /* create configuration address as per Figure 1 + address = (uint32_t)((lbus << 16) | (lslot << 11) | + (lfunc << 8) | (offset & 0xfc) | ((uint32_t)0x80000000)); + + /* write out the address + //printf("reading PCI register (old): %x\n", address); + outl(0xCF8, address); + /* read in the data + /* (offset & 2) * 8) = 0 will choose the first word of the 32 bits register + tmp = (uint16_t)((inl(0xCFC) >> ((offset & 2) * 8)) & 0xffff); + return (tmp); +}*/ + +uint32_t readPCIConfigWord/*New*/(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset) { ConfigAddress addr; addr.enable = 1; - addr.zero1 = 0; + //addr.zero1 = 0; addr.zero2 = 0; addr.registerNum = offset & 0xFC; addr.functionNum = function; addr.deviceNum = device; addr.busNum = bus; - //printf("reading PCI register: %x\n", *(uint32_t *)&addr); + //printf("reading PCI register (new): %x\n", *(uint32_t *)&addr); outl(0xcf8, *(uint32_t *)&addr); //printf( "read %x", inl(0xCFC)); return inl(0xCFC); -}*/ +} void enumPCIDevices() { + //printf("old: 0x%x, new: 0x%x", readPCIConfigWord(0,2,4,8), readPCIConfigWordNew(0,2,4,8) ); for (uint8_t func = 0; func <= MAX_PCI_FUNCTIONS; func++) { if (getPCIVender(0, 0, func) == 0xFFFF) @@ -106,9 +138,9 @@ void checkPCIFunction(uint8_t bus, uint8_t device, uint8_t func) }*/ } -uint32_t getPCIClass(uint8_t bus, uint8_t device, uint8_t func) +uint16_t getPCIClass(uint8_t bus, uint8_t device, uint8_t func) { - return readPCIConfigWord(bus, device, func, 0x0A); + return readPCIConfigWord(bus, device, func, 0x08)>>16; } uint8_t getPCISecondBus(uint8_t bus, uint8_t device, uint8_t func) @@ -176,35 +208,7 @@ bool isValidPCIFunction(uint8_t bus, uint8_t device, uint8_t function) { uint16_t getPCIVenderID(uint8_t bus, uint8_t slot, uint8_t function) { return readPCIConfigWord(bus, slot, function, 0); } -//TODO rewrite -/** - * read 32 bits from PCI config space - * @param bus - * @param slot - * @param func - * @param offset into config space - * @return uint32 of the config space starting at offset. - */ -uint32_t readPCIConfigWord(uint8_t bus, uint8_t slot, uint8_t func, - uint8_t offset) -{ - uint32_t address; - uint32_t lbus = (uint32_t)bus; - uint32_t lslot = (uint32_t)slot; - uint32_t lfunc = (uint32_t)func; - uint16_t tmp = 0; - - /* create configuration address as per Figure 1 */ - address = (uint32_t)((lbus << 16) | (lslot << 11) | - (lfunc << 8) | (offset & 0xfc) | ((uint32_t)0x80000000)); - /* write out the address */ - outl(0xCF8, address); - /* read in the data */ - /* (offset & 2) * 8) = 0 will choose the first word of the 32 bits register */ - tmp = (uint16_t)((inl(0xCFC) >> ((offset & 2) * 8)) & 0xffff); - return (tmp); -} /** * check devices on bus for other buses * @param bus diff --git a/src/drivers/PCI/PCI.h b/src/drivers/PCI/PCI.h index fe8de0351..8099852b9 100644 --- a/src/drivers/PCI/PCI.h +++ b/src/drivers/PCI/PCI.h @@ -15,8 +15,9 @@ extern uint8_t MAX_PCI_DEVICES_PER_BUS; struct ConfigAddress { - uint8_t zero1 : 2; + //uint8_t zero1 : 2; uint8_t registerNum : 6; + uint8_t zero1 :2; uint8_t functionNum : 3; uint8_t deviceNum : 5; uint8_t busNum : 8; @@ -36,7 +37,7 @@ void checkPCIBus(uint8_t bus); void checkPCIFunction(uint8_t bus, uint8_t device, uint8_t func); -uint32_t getPCIClass(uint8_t bus, uint8_t device, uint8_t func); +uint16_t getPCIClass(uint8_t bus, uint8_t device, uint8_t func); uint8_t getPCISecondBus(uint8_t bus, uint8_t device, uint8_t func); From 6311024a8de3c5875885279b64b23643b82acbe8 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Fri, 2 Mar 2018 16:11:22 -0600 Subject: [PATCH 100/171] fixed commented issue in #48 --- src/drivers/PCI/PCI.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/drivers/PCI/PCI.c b/src/drivers/PCI/PCI.c index 9c3206d7b..590a6cd65 100644 --- a/src/drivers/PCI/PCI.c +++ b/src/drivers/PCI/PCI.c @@ -68,11 +68,10 @@ void enumPCIDevices() //printf("old: 0x%x, new: 0x%x", readPCIConfigWord(0,2,4,8), readPCIConfigWordNew(0,2,4,8) ); for (uint8_t func = 0; func <= MAX_PCI_FUNCTIONS; func++) { - if (getPCIVender(0, 0, func) == 0xFFFF) + if (getPCIVender(0, 0, func) != 0xFFFF) { - break; + checkPCIBus(func); } - checkPCIBus(func); } } From 3ff7b55e17f0a5126418b8d2138b7766309a1c55 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Fri, 2 Mar 2018 16:33:39 -0600 Subject: [PATCH 101/171] abort --- src/clib_misc/Abort.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/clib_misc/Abort.c b/src/clib_misc/Abort.c index 9da693f30..49914f8b7 100644 --- a/src/clib_misc/Abort.c +++ b/src/clib_misc/Abort.c @@ -9,7 +9,7 @@ #include "drivers/TTY/Console.h" extern "C" -void /*__cxxabiv1::*/__cxa_pure_virtual(void) { +void __cxa_pure_virtual(void) { terminalWriteString("pure virtual method called......."); abort( ); } From a7440d12d32fef1bd6e1766f0f3cf0e4e57a209d Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Fri, 2 Mar 2018 16:36:50 -0600 Subject: [PATCH 102/171] fat 12y --- src/drivers/filesys/fat/fat12/Fat12FS.cpp | 29 --------------------- src/drivers/filesys/fat/fat12/Fat12File.cpp | 2 -- 2 files changed, 31 deletions(-) diff --git a/src/drivers/filesys/fat/fat12/Fat12FS.cpp b/src/drivers/filesys/fat/fat12/Fat12FS.cpp index 81958463a..de4fc6bc4 100644 --- a/src/drivers/filesys/fat/fat12/Fat12FS.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12FS.cpp @@ -56,35 +56,6 @@ void Fat12FS::buildDirStructure() { //This conversion may not work correctly... oh well _root = new Fat12FSNode("Root", 0, DIR, ((_FSInfo->resSec) + (_FSInfo->FATs * _FSInfo->secPerFAT)) / _FSInfo->secPerCluster, this); - /*uint8_t* tempSector = (uint8_t*) malloc(_FSInfo->bytePerSec); - uint8_t sectorOffset = 0; - uint16_t startSector = (_FSInfo->resSec) - + (_FSInfo->FATs * _FSInfo->secPerFAT); - uint16_t rootDirSize = (float) _FSInfo->dirEntryCount - / (float) _FSInfo->bytePerSec - + (_FSInfo->dirEntryCount % _FSInfo->bytePerSec != 0); - //_device->read(startSector+i, tempCluster) - //TODO there may be an issue if the size of a sector != a mult of the size of an entry... we will deal with that latter - for (size_t i = 0; i < rootDirSize; i++) { - if(tempSector[sectorOffset] == 0){ - break; - } - Fat12FSNode* ret = parseEntry(tempSector + sectorOffset); - if (_tempLongName == nullptr){ - sectorOffset += sizeof(FatNormalFileName); - } else { - sectorOffset += sizeof(FatLongFileName); - } - if(ret != nullptr){ - _root->add(ret); - if(ret->type() == DIR){ - buildTree(ret); - } - } - if (sectorOffset >= _FSInfo->bytePerSec){ - //_device->read(startSectot+i, tempCluster) - } - }*/ buildTree((Fat12FSNode *)_root); } diff --git a/src/drivers/filesys/fat/fat12/Fat12File.cpp b/src/drivers/filesys/fat/fat12/Fat12File.cpp index 49792189a..9ba70421a 100644 --- a/src/drivers/filesys/fat/fat12/Fat12File.cpp +++ b/src/drivers/filesys/fat/fat12/Fat12File.cpp @@ -35,13 +35,11 @@ size_t Fat12File::read(char *buffer, size_t size) //TODO naming and types and general structure, taken from osdev wiki bool Fat12File::readFromDisk() { - //uint16_t firstFatSec = _device->FSInfo()->resSec; unsigned char FAT_table[_device->FSInfo()->bytePerSec]; uint32_t read = 0; while (read < _fileLocSize && _fileLocSize - read >= (_device->FSInfo()->secPerCluster * _device->FSInfo()->bytePerSec)) { unsigned int fat_offset = _lastCluster + (_lastCluster / 2); // multiply by 1.5 - //unsigned int fat_sector = firstFatSec + (fat_offset / _device->FSInfo()->bytePerSec); unsigned int ent_offset = fat_offset % _device->FSInfo()->bytePerSec; unsigned short table_value = *(unsigned short *)&FAT_table[ent_offset]; From 4fb1b3917682175e939c772ddd9b7a819b61710b Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Fri, 2 Mar 2018 16:39:41 -0600 Subject: [PATCH 103/171] Update README.MD --- README.MD | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/README.MD b/README.MD index f6cd08c0e..f6a15cd4e 100755 --- a/README.MD +++ b/README.MD @@ -24,13 +24,7 @@ ExOS extends the [MIT exokernel](https://pdos.csail.mit.edu/archive/exo/) by rem * Oskari - [ ] Floppy drive driver - -* Jacob - - - [ ] replace current PCI enum. strat. The new strat will get all devices at boot. When a device is requested it will be found in the list of devices. -* Ben - - [ ] Fat12 file system driver ## Long term work * Load files from floppy drives @@ -45,7 +39,7 @@ ExOS extends the [MIT exokernel](https://pdos.csail.mit.edu/archive/exo/) by rem * Mac OS X libOS ## Major systems to support -- [ ] PCI +- [x ] PCI - workingish - [ ] PCI Express - [ ] USB - [ ] Text Graphics From 96381ddba3a118502f9f483eb8b5cdaba75879b6 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Fri, 2 Mar 2018 16:40:04 -0600 Subject: [PATCH 104/171] Update README.MD --- README.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.MD b/README.MD index f6a15cd4e..be9326c57 100755 --- a/README.MD +++ b/README.MD @@ -39,7 +39,7 @@ ExOS extends the [MIT exokernel](https://pdos.csail.mit.edu/archive/exo/) by rem * Mac OS X libOS ## Major systems to support -- [x ] PCI - workingish +- [x] PCI - workingish - [ ] PCI Express - [ ] USB - [ ] Text Graphics From 040e09cd7aa78a5c1113810c4655f9d20f7a7e76 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Fri, 2 Mar 2018 16:42:39 -0600 Subject: [PATCH 105/171] Revert "Added some more floppy constants" This reverts commit a762edbe158ff00770ff21ba7620450ec5643594. --- src/drivers/floppy/Floppy.h | 59 ------------------------------------- 1 file changed, 59 deletions(-) diff --git a/src/drivers/floppy/Floppy.h b/src/drivers/floppy/Floppy.h index 09538e4ce..3652d08ad 100644 --- a/src/drivers/floppy/Floppy.h +++ b/src/drivers/floppy/Floppy.h @@ -51,65 +51,6 @@ const uint16_t DATA_FIFO = 0x3F5; const uint16_t DIGITAL_INPUT_REGISTER = 0x3F7; const uint16_t CONFIGURATION_CONTROL_REGISTER = 0x3F7; -/** - * OR the values together for a DOR command - * DOR format: - * Bits 0-1: - * 00 - Drive 0 - * 01 - Drive 1 - * 10 - Drive 2 - * 11 - Drive 3 - * Bit 2: - * 0 - Reset controller - * 1 - Controller enabled - * Bit 3: - * 0 - IRQ channel - * 1 - DMA mode - * Bits 4-7 (bit 4, drive 0 -> bit 7, drive 3): - * 0 - Stop motor - * 1 - Start motor - */ -const uint8_t DOR_DRIVE0 = 0x00; // 0000 00|00| -const uint8_t DOR_DRIVE1 = 0x01; // 0000 00|01| -const uint8_t DOR_DRIVE2 = 0x02; // 0000 00|10| -const uint8_t DOR_DRIVE3 = 0x03; // 0000 00|11| -const uint8_t DOR_ENABLE = 0x04; // 0000 0|1|00 -const uint8_t DOR_DMA = 0x08; // 0000 |1|000 -const uint8_t DOR_MOTOR0 = 0x10; // 000|1| 0000 -const uint8_t DOR_MOTOR1 = 0x20; // 00|1|0 0000 -const uint8_t DOR_MOTOR2 = 0x40; // 0|1|00 0000 -const uint8_t DOR_MOTOR3 = 0x80; // |1|000 0000 - -/** - * MSR format: - * Bit 0 Drive0 - * Bit 1 Drive1 - * Bit 2 Drive2 - * Bit 3 Drive3: - * 0 - Not busy in seek mode - * 1 - Busy - * Bit 4: - * 0 - FDC not busy - * 1 - FDC busy with read/write - * Bit 5: - * 0 - FDC in DMA mode - * 1 - FDC in non-DMA mode - * Bit 6 (direction of transfer): - * 0 - Expecting data from CPU - * 1 - Has data for CPU - * Bit 7: - * 0 - Data register not ready for transfer - * 1 - Data register ready - */ -const uint8_t MSR_DRIVE0_SEEK = 0x01; // 0000 000|1| -const uint8_t MSR_DRIVE1_SEEK = 0x02; // 0000 00|1|0 -const uint8_t MSR_DRIVE2_SEEK = 0x04; // 0000 0|1|00 -const uint8_t MSR_DRIVE3_SEEK = 0x08; // 0000 |1|000 -const uint8_8 MSR_FDC_BUSY = 0x10; // 000|1| 0000 -const uint8_t MSR_FDC_DMA = 0x20; // 00|1|0 0000 -const uint8_t MSR_DIRECTION = 0x40; // 0|1|00 0000 -const uint8_t MSR_DATA_READY = 0x80; // |1|000 0000 - /** * Floppy commands */ From 659956c8d92233c8208d8de6b8f404ba5620ddbd Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Fri, 2 Mar 2018 16:43:22 -0600 Subject: [PATCH 106/171] Revert "Added things for floppy stuffs" This reverts commit bb7c7b966268e1dd708bb893aaa51090bd80f023. --- src/Kernel.cpp | 13 ++----- src/drivers/floppy/Floppy.cpp | 47 ------------------------- src/drivers/floppy/Floppy.h | 66 ----------------------------------- 3 files changed, 3 insertions(+), 123 deletions(-) diff --git a/src/Kernel.cpp b/src/Kernel.cpp index 8682d626c..e2152604c 100644 --- a/src/Kernel.cpp +++ b/src/Kernel.cpp @@ -67,16 +67,9 @@ extern "C" {/* Use C linkage for kernel_main. */ terminalWriteLine(" Done!"); printf (" Master: %x\n", drives.master); printf (" Slave: %x\n", drives.slave); - // Keep track of which drives are supported (only 1.44M 3.5 inch) - uint8_t masterSupported = drives.master == _1440KB35; - uint8_t slaveSupported = drives.slave == _1440KB35; - if (!(masterSupported || slaveSupported)) { - printf (" No supported drives found :(\n"); - } else { - printf (" Initializing floppy ISA DMA transfer..."); - initFloppyDMA (); - printf (" Done!\n"); - } + // Keep track of which drives are supported + uint8_t masterSupported = drives.master == 0x04; + uint8_t slaveSupported = drives.slave == 0x04; terminalWriteString(" Finding PCI buses..."); //find the valid PCI buses PCIInit(); diff --git a/src/drivers/floppy/Floppy.cpp b/src/drivers/floppy/Floppy.cpp index 3ad9b4c3f..5abbcb672 100644 --- a/src/drivers/floppy/Floppy.cpp +++ b/src/drivers/floppy/Floppy.cpp @@ -20,50 +20,3 @@ fdtypes_t getDriveTypes ( ) { .slave = drives & 0x0F }; } - -/** - * Set DMA channel 2 to transfer data from memory address 0x1000 to 0x23FF - * Pagin must map this memory elsewhere and also never page to disk - * The counter is 0x23FF which is the length of a track on 1.44M floppy - 1 - * (with 512 byte sectors) - * Transfer length is counter + 1 - */ -void initFloppyDMA ( ) { - outb (0x0A, 0x06); // Mask DMA channels 2 and 0 - // The following is out of order to avoid extra delays - // from outb'ing the same port twice in a row - outb (0x0C, 0xFF); // Reset master flip flop - outb (0x04, 0x00); // Set address low byte to 0 - outb (0x05, 0x23); // Set counter high byte to 0x23 - outb (0x04, 0x10); // Set address high byte to 0x10 - outb (0x05, 0xFF); // Set counter low byte to 0xFF - outb (0x81, 0x00); // Set external page register to 0 - outb (0x0A, 0x02); // Unmask channel 2 -} - -/** - * TODO: - * TEST: - * demand transfer if "advanced drive" detected - * read the end of the ISA DMA article for for more info - */ - -/** - * Prepare the drive for DMA read - */ -void prepareDMARead ( ) { - outb (0x0A, 0x06); // Mask DMA channels 2 and 0 - outb (0x0B, 0x56); // 01 0 1 01 10 - // single transfer, address inc, autoinit, read, ch2 - outb (0x0A, 0x02); // Unmask channel 2 -} - -/** - * Prepare the drive for DMA write - */ -void prepareDMAWrite ( ) { - outb (0x0A, 0x06); // Mask DMA channels 2 and 0 - outb (0x0B, 0x5A); // 01 0 1 10 10 - // single transfer, address inc, autoinit, write, ch2 - outb (0x0A, 0x02); // Unmask channel 2 -} diff --git a/src/drivers/floppy/Floppy.h b/src/drivers/floppy/Floppy.h index 3652d08ad..d261674e8 100644 --- a/src/drivers/floppy/Floppy.h +++ b/src/drivers/floppy/Floppy.h @@ -28,53 +28,6 @@ typedef struct { uint16_t sect; } chs_t; -/** - * The floppy registers: - * Read/Write, Name - * RO Status register A - * RO Status register B - * Digital output regster - * Tape drive register - * RO Main status regiser - * WO Datarate select register - * Data FIFO - * RO Digital input register - * WO Configuration control register - */ -const uint16_t STATUS_REGISTER_A = 0x3F0; -const uint16_t STATUS_REGISTER_B = 0x3F1; -const uint16_t DIGITAL_OUTPUT_REGISTER = 0x3F2; -const uint16_t TAPE_DRIVE_REGISTER = 0x3F3; -const uint16_t MAIN_STATUS_REGISTER = 0x3F4; -const uint16_t DATARATE_SELECT_REGISTER = 0x3F4; -const uint16_t DATA_FIFO = 0x3F5; -const uint16_t DIGITAL_INPUT_REGISTER = 0x3F7; -const uint16_t CONFIGURATION_CONTROL_REGISTER = 0x3F7; - -/** - * Floppy commands - */ -const uint8_t READ_TRACK = 2; // Generates IRQ6 -const uint8_t SPECIFY = 3; // * Set drive parameters -const uint8_t SENSE_DRIVE_STATUS = 4; -const uint8_t WRITE_DATA = 5; // * Write to disk -const uint8_t READ_DATA = 6; // * Read from disk -const uint8_t RECALIBRATE = 7; // * Seek to cylinder 0 -const uint8_t SENSE_INTERRUPT = 8; // * Ack IRQ6, get status of last cmd -const uint8_t WRITE_DELETED_DATA = 9; -const uint8_t READ_ID = 10; // Generates IRQ6 -const uint8_t READ_DELETED_DATA = 12; -const uint8_t FORMAT_TRACK = 13; // * -const uint8_t SEEK = 15; // * Seek to cylinder X -const uint8_t VERSION = 16; // * Used during init, once -const uint8_t SCAN_EQUAL = 17; -const uint8_t PERPENDICULAR_MODE = 18; // * Used during init, once, maybe -const uint8_t CONFIGURE = 19; // * Set controller parameters -const uint8_t LOCK = 20; // * Protect parameterss from reset -const uint8_t VERIFY = 22 -const uint8_t SCAN_LOW_OR_EQUAL = 25; -const uint8_t SCAN_HIGH_OR_EQUAL = 29; - /** * 1.44M floppy constants * 80 cylinders, 2 head (sides), 18 sectors per track @@ -112,23 +65,4 @@ inline chs_t LBAToCHS (uint32_t lba) { */ fdtypes_t getDriveTypes ( ); -/** - * Set DMA channel 2 to transfer data from memory address 0x1000 to 0x23FF - * Pagin must map this memory elsewhere and also never page to disk - * The counter is 0x23FF which is the length of a track on 1.44M floppy - 1 - * (with 512 byte sectors) - * Transfer length is counter + 1 - */ -void initFloppyDMA ( ); - -/** - * Prepare the drive for DMA read - */ -void prepareDMARead ( ); - -/** - * Prepare the drive for DMA write - */ -void prepareDMAWrite ( ); - #endif From 208cf23206189e871e5e17a820f46f6b4b9ba127 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Fri, 2 Mar 2018 16:43:42 -0600 Subject: [PATCH 107/171] Revert "Detects proper floppy drives" This reverts commit ceabbc5636fb98df270d82c14b7c0ec8759e7e2d. --- makefile.inc | 4 +-- src/Global.h | 1 + src/Kernel.cpp | 11 ------- src/drivers/CMOS/CMOS.h | 57 ----------------------------------- src/drivers/CMOS/makefile | 5 --- src/drivers/floppy/Floppy.cpp | 15 +-------- src/drivers/floppy/Floppy.h | 14 --------- src/drivers/makefile | 2 +- 8 files changed, 5 insertions(+), 104 deletions(-) delete mode 100644 src/drivers/CMOS/CMOS.h delete mode 100644 src/drivers/CMOS/makefile diff --git a/makefile.inc b/makefile.inc index 41af6ba46..984f162ec 100644 --- a/makefile.inc +++ b/makefile.inc @@ -1,8 +1,8 @@ AS = i686-elf-as GPP = i686-elf-g++ GCC = i686-elf-gcc -OS_CPP = /media/sdcard/ExOS -BUILD_TO = /mnt/boot/kernel.bin +OS_CPP = /home/garrett/workspace/ExOS +BUILD_TO = /run/media/garrett/EXOS/boot/kernel.bin CFLAGS = -c -ffreestanding -O2 -Wall -Wextra -fno-rtti -fno-exceptions -std=gnu++14 -I$(OS_CPP)/src OBJ_DIR = $(OS_CPP)/build diff --git a/src/Global.h b/src/Global.h index 435181269..c12d0a687 100755 --- a/src/Global.h +++ b/src/Global.h @@ -25,4 +25,5 @@ //helpful constant #define FOUR_KB 4096 + #endif /* GLOBAL_H_ */ diff --git a/src/Kernel.cpp b/src/Kernel.cpp index e2152604c..043a5bab4 100644 --- a/src/Kernel.cpp +++ b/src/Kernel.cpp @@ -19,8 +19,6 @@ #include "multiboot_spec/Multiboot.h" #include "memory/Mem.h" #include "utils/printf/Printf.h" -#include "drivers/CMOS/CMOS.h" -#include "drivers/floppy/Floppy.h" InterruptDescriptorTable idt; GlobalDescriptorTable gdt; @@ -61,15 +59,6 @@ extern "C" {/* Use C linkage for kernel_main. */ //set malloc's support vars mallocInit( ); terminalWriteLine(" Done!"); - // Get the floppy drive types from CMOS - terminalWriteString(" Finding floppy drive types..."); - fdtypes_t drives = getDriveTypes(); - terminalWriteLine(" Done!"); - printf (" Master: %x\n", drives.master); - printf (" Slave: %x\n", drives.slave); - // Keep track of which drives are supported - uint8_t masterSupported = drives.master == 0x04; - uint8_t slaveSupported = drives.slave == 0x04; terminalWriteString(" Finding PCI buses..."); //find the valid PCI buses PCIInit(); diff --git a/src/drivers/CMOS/CMOS.h b/src/drivers/CMOS/CMOS.h deleted file mode 100644 index 9275cddd8..000000000 --- a/src/drivers/CMOS/CMOS.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - * CMOS.h - * - * Created: Sep 12, 2017 - * - * Author: Oskari - */ - -#ifndef CMOS_H_ -#define CMOS_H_ - -#include "Global.h" - -//NMI disabled flag -const uint8_t NMI_DISABLED = 0; - -/** - * Floppy type descriptors - * Stored in CMOS register 0x10 - * High nybble, master - * Low nybble, slave - */ -const uint8_t NO_DRIVE = 0x00; -const uint8_t _360KB525 = 0x01; // 360KB 5.25 inch -const uint8_t _1200KB525 = 0x02; // 1.2MB 5.25 inch -const uint8_t _720KB35 = 0x03; // 720KB 3.5 inch -const uint8_t _1440KB35 = 0x04; // 1.44MB 3.5 inch -const uint8_t _2880KB35 = 0x05; // 2.88MB 3.5 inch - -/** - * Select a CMOS register - * @param CMOS register - */ -inline void selectCMOS (uint8_t reg) { - outb (0x70, (NMI_DISABLED << 7) | reg); -} -/** - * Read from the CMOS register - * @param register to read - * @return result - */ -inline uint8_t readCMOS (uint8_t reg) { - selectCMOS (reg); - return inb (0x71); -} -/** - * Write to the CMOS register - * !!!NOT RECOMMENDED FOR USE!!! - * @param register to write to - * @param byte to write - */ -inline uint8_t writeCMOS (uint8_t reg, uint8_t val) { - selectCMOS (reg); - outb (0x71, val); -} - -#endif diff --git a/src/drivers/CMOS/makefile b/src/drivers/CMOS/makefile deleted file mode 100644 index 115ad129e..000000000 --- a/src/drivers/CMOS/makefile +++ /dev/null @@ -1,5 +0,0 @@ -SUBDIRS = -OBS= - -include ../../../makefile.inc - diff --git a/src/drivers/floppy/Floppy.cpp b/src/drivers/floppy/Floppy.cpp index 5abbcb672..317b2b30a 100644 --- a/src/drivers/floppy/Floppy.cpp +++ b/src/drivers/floppy/Floppy.cpp @@ -6,17 +6,4 @@ * Author: Oskari */ -#include "drivers/CMOS/CMOS.h" -#include "drivers/floppy/Floppy.h" - -/** - * Get the types of floppy drives - * @return struct with the drive types - */ -fdtypes_t getDriveTypes ( ) { - uint8_t drives = readCMOS (0x10); - return (fdtypes_t) { - .master = (drives >> 4) & 0x0F, - .slave = drives & 0x0F - }; -} +#include "../floppy/Floppy.h" diff --git a/src/drivers/floppy/Floppy.h b/src/drivers/floppy/Floppy.h index d261674e8..b62550e1a 100644 --- a/src/drivers/floppy/Floppy.h +++ b/src/drivers/floppy/Floppy.h @@ -11,14 +11,6 @@ #include "../../Global.h" -/** - * Struct that contains the Floppy types - */ -typedef struct { - uint8_t master; - uint8_t slave; -} fdtypes_t; - /** * Struct that contains a CHS address */ @@ -59,10 +51,4 @@ inline chs_t LBAToCHS (uint32_t lba) { }; } -/** - * Get the types of floppy drives - * @return struct with the drive types - */ -fdtypes_t getDriveTypes ( ); - #endif diff --git a/src/drivers/makefile b/src/drivers/makefile index be1e0fd09..36ea2200b 100644 --- a/src/drivers/makefile +++ b/src/drivers/makefile @@ -1,4 +1,4 @@ -SUBDIRS = PCI TTY floppy CMOS +SUBDIRS = PCI TTY floppy OBS= Keyboard.o ProgrammableInterruptController.o include ../../makefile.inc From 8e6bff4053baa49160de95a6c3bc399769c39e72 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Fri, 2 Mar 2018 16:45:42 -0600 Subject: [PATCH 108/171] Revert "Start floppy stuff" This reverts commit d0a772018d1450eb84b35a01db419cf0fe2b66d3. --- .gitignore | 4 +++ makefile | 2 +- src/drivers/floppy/Floppy.cpp | 9 ------ src/drivers/floppy/Floppy.h | 54 ----------------------------------- src/drivers/floppy/makefile | 5 ---- src/drivers/makefile | 2 +- 6 files changed, 6 insertions(+), 70 deletions(-) delete mode 100644 src/drivers/floppy/Floppy.cpp delete mode 100644 src/drivers/floppy/Floppy.h delete mode 100644 src/drivers/floppy/makefile diff --git a/.gitignore b/.gitignore index 62bd89bc3..3be87ebdc 100755 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,7 @@ .~lock.* *.swp *.swo +.idea/ +.vscode/ +cmake-build-debug/ +kernel.bin \ No newline at end of file diff --git a/makefile b/makefile index fae5c1fbe..a1c2a6e19 100644 --- a/makefile +++ b/makefile @@ -9,4 +9,4 @@ kernel.bin: $(SUBDIRS) @sync clean: - rm $(OBJ_DIR)/*.o + rm $(OBJ_DIR)/*.o \ No newline at end of file diff --git a/src/drivers/floppy/Floppy.cpp b/src/drivers/floppy/Floppy.cpp deleted file mode 100644 index 317b2b30a..000000000 --- a/src/drivers/floppy/Floppy.cpp +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Floppy.cpp - * - * Created: Sept 12, 2017 - * - * Author: Oskari - */ - -#include "../floppy/Floppy.h" diff --git a/src/drivers/floppy/Floppy.h b/src/drivers/floppy/Floppy.h deleted file mode 100644 index b62550e1a..000000000 --- a/src/drivers/floppy/Floppy.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Floppy.h - * - * Created: Sept 11, 2017 - * - * Author: Oskari - */ - -#ifndef FLOPPY_H_ -#define FLOPPY_H_ - -#include "../../Global.h" - -/** - * Struct that contains a CHS address - */ -typedef struct { - uint16_t cyl; - uint16_t head; - uint16_t sect; -} chs_t; - -/** - * 1.44M floppy constants - * 80 cylinders, 2 head (sides), 18 sectors per track - */ -const uint16_t SPT = 18; // Sectors per track -const uint16_t HPC = 2; // Heads per cylinder - -/** - * Converts CHS to LBA - * @param cylinder number - * @param head number - * @param sector number - * @return LBA format (logical base address) - */ -inline uint32_t CHSToLBA (uint16_t cyl, uint16_t head, uint16_t sect) { - return (uint32_t) (((cyl * HPC + head) * SPT) + sect - 1); -} - -/** - * Converts LBA to CHS - * @param logical base address - * @return strut containing cyl, head, sect - */ -inline chs_t LBAToCHS (uint32_t lba) { - return (chs_t) { - .cyl = lba / (2 * SPT), - .head = (lba % (2 * SPT)) / SPT, - .sect = (lba % (2 * SPT)) % SPT + 1 - }; -} - -#endif diff --git a/src/drivers/floppy/makefile b/src/drivers/floppy/makefile deleted file mode 100644 index 4d8706129..000000000 --- a/src/drivers/floppy/makefile +++ /dev/null @@ -1,5 +0,0 @@ -SUBDIRS = -OBS= Floppy.o - -include ../../../makefile.inc - diff --git a/src/drivers/makefile b/src/drivers/makefile index 36ea2200b..0766b9328 100644 --- a/src/drivers/makefile +++ b/src/drivers/makefile @@ -1,4 +1,4 @@ -SUBDIRS = PCI TTY floppy +SUBDIRS = PCI TTY OBS= Keyboard.o ProgrammableInterruptController.o include ../../makefile.inc From bfa2108b86fe96174be38be563d15859969a1adf Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 5 Mar 2018 07:22:00 -0600 Subject: [PATCH 109/171] PCI devices clean up --- src/drivers/PCI/PCI_devices/PCIDevice.cpp | 78 +++++++++++-------- .../PCI/PCI_devices/PCIStandardDevice.cpp | 30 +++---- 2 files changed, 62 insertions(+), 46 deletions(-) diff --git a/src/drivers/PCI/PCI_devices/PCIDevice.cpp b/src/drivers/PCI/PCI_devices/PCIDevice.cpp index cd9a84e1a..625818575 100644 --- a/src/drivers/PCI/PCI_devices/PCIDevice.cpp +++ b/src/drivers/PCI/PCI_devices/PCIDevice.cpp @@ -8,73 +8,89 @@ #include "drivers/PCI/PCI_devices/PCIDevice.h" #include "drivers/PCI/PCI.h" -PCIDevice::PCIDevice( ) { +PCIDevice::PCIDevice() +{ // TODO Auto-generated constructor stub - } -PCIDevice::PCIDevice(uint8_t bus, uint8_t device, uint8_t function, bool page) { +PCIDevice::PCIDevice(uint8_t bus, uint8_t device, uint8_t function, bool page) +{ _bus = bus; _device = device; _function = function; _page = page; } -uint16_t PCIDevice::deviceID( ) { - //return readPCIConfigWord(_bus, _device, _function, 16); +uint16_t PCIDevice::deviceID() +{ + return readPCIConfigWord(_bus, _device, _function, 0x00) >> 16; } -uint16_t PCIDevice::venderID( ) { - //return readPCIConfigWord(_bus, _device, _function, 0); +uint16_t PCIDevice::venderID() +{ + return readPCIConfigWord(_bus, _device, _function, 0); } -uint16_t PCIDevice::status( ) { - ///return readPCIConfigWord(_bus, _device, _function, 0x04 + 16); +uint16_t PCIDevice::status() +{ + return readPCIConfigWord(_bus, _device, _function, 0x04) >> 16; } -uint16_t PCIDevice::command( ) { - //return readPCIConfigWord(_bus, _device, _function, 0x04); +uint16_t PCIDevice::command() +{ + return readPCIConfigWord(_bus, _device, _function, 0x04); } -void PCIDevice::command(uint16_t com) { - //(void) com; +void PCIDevice::command(uint16_t com) +{ + //(void)com; } -uint8_t PCIDevice::classCode( ) { - //return readPCIConfigWord(_bus, _device, _function, 0x08 + 24); +uint8_t PCIDevice::classCode() +{ + return readPCIConfigWord(_bus, _device, _function, 0x08) >> 24; } -uint8_t PCIDevice::subClassCode( ) { - //return readPCIConfigWord(_bus, _device, _function, 0x08 + 16); +uint8_t PCIDevice::subClassCode() +{ + return readPCIConfigWord(_bus, _device, _function, 0x08) >> 16; } -uint8_t PCIDevice::progIF( ) { - //return readPCIConfigWord(_bus, _device, _function, 0x08 + 8); +uint8_t PCIDevice::progIF() +{ + return readPCIConfigWord(_bus, _device, _function, 0x08) >> 8; } -uint8_t PCIDevice::revisionID( ) { - //return readPCIConfigWord(_bus, _device, _function, 0x08); +uint8_t PCIDevice::revisionID() +{ + return readPCIConfigWord(_bus, _device, _function, 0x08); } -uint8_t PCIDevice::BIST( ) { - //return readPCIConfigWord(_bus, _device, _function, 0x0c +24); +uint8_t PCIDevice::BIST() +{ + return readPCIConfigWord(_bus, _device, _function, 0x0c) >> 24; } -void PCIDevice::BIST(uint8_t testCode) { +void PCIDevice::BIST(uint8_t testCode) +{ //(void) testCode; } -uint8_t PCIDevice::headerType( ) { - //return readPCIConfigWord(_bus, _device, _function, 0x0c +16); +uint8_t PCIDevice::headerType() +{ + return readPCIConfigWord(_bus, _device, _function, 0x0c) >>16; } -uint8_t PCIDevice::latencyTimer( ) { - //return readPCIConfigWord(_bus, _device, _function, 0x0c +8); +uint8_t PCIDevice::latencyTimer() +{ + return readPCIConfigWord(_bus, _device, _function, 0x0c) >>8; } -uint8_t PCIDevice::cacheLineSize( ) { - //return readPCIConfigWord(_bus, _device, _function, 0x0c); +uint8_t PCIDevice::cacheLineSize() +{ + return readPCIConfigWord(_bus, _device, _function, 0x0c); } -void PCIDevice::cacheLineSize(uint8_t lineSize) { +void PCIDevice::cacheLineSize(uint8_t lineSize) +{ //(void) lineSize; } diff --git a/src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp b/src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp index 6d3862148..71a0708ae 100644 --- a/src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp +++ b/src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp @@ -21,61 +21,61 @@ PCIStandardDevice::~PCIStandardDevice( ) { } uint32_t PCIStandardDevice::BAR0( ) { - //return readPCIConfigWord(_bus, _device, _function, 0x10); + return readPCIConfigWord(_bus, _device, _function, 0x10); } uint32_t PCIStandardDevice::BAR1( ) { - ///return readPCIConfigWord(_bus, _device, _function, 0x14); + return readPCIConfigWord(_bus, _device, _function, 0x14); } uint32_t PCIStandardDevice::BAR2( ) { - //return readPCIConfigWord(_bus, _device, _function, 0x18); + return readPCIConfigWord(_bus, _device, _function, 0x18); } uint32_t PCIStandardDevice::BAR3( ) { - //return readPCIConfigWord(_bus, _device, _function, 0x1C); + return readPCIConfigWord(_bus, _device, _function, 0x1C); } uint32_t PCIStandardDevice::BAR4( ) { - //return readPCIConfigWord(_bus, _device, _function, 0x20); + return readPCIConfigWord(_bus, _device, _function, 0x20); } uint32_t PCIStandardDevice::BAR5( ) { - //return readPCIConfigWord(_bus, _device, _function, 0x24); + return readPCIConfigWord(_bus, _device, _function, 0x24); } uint32_t PCIStandardDevice::cardBusCISptr( ) { - //return readPCIConfigWord(_bus, _device, _function, 0x28); + return readPCIConfigWord(_bus, _device, _function, 0x28); } uint16_t PCIStandardDevice::subsystemID( ) { - //return readPCIConfigWord(_bus, _device, _function, 0x2C+16); + return readPCIConfigWord(_bus, _device, _function, 0x2C) >>16; } uint16_t PCIStandardDevice::subsystemVenderID( ) { - //return readPCIConfigWord(_bus, _device, _function, 0x2c); + return readPCIConfigWord(_bus, _device, _function, 0x2c); } uint32_t PCIStandardDevice::expandROMbaseAddr( ) { - //return readPCIConfigWord(_bus, _device, _function, 0x30); + return readPCIConfigWord(_bus, _device, _function, 0x30); } uint8_t PCIStandardDevice::capabilitiesPtr( ) { - //return readPCIConfigWord(_bus, _device, _function, 0x34); + return readPCIConfigWord(_bus, _device, _function, 0x34); } uint8_t PCIStandardDevice::interruptLine( ) { - //return readPCIConfigWord(_bus, _device, _function, 0x3c); + return readPCIConfigWord(_bus, _device, _function, 0x3c); } uint8_t PCIStandardDevice::interruptPin( ) { - //return readPCIConfigWord(_bus, _device, _function, 0x3c+8); + return readPCIConfigWord(_bus, _device, _function, 0x3c) >> 8; } uint8_t PCIStandardDevice::minGrant( ) { - //return readPCIConfigWord(_bus, _device, _function, 0x3c+16); + return readPCIConfigWord(_bus, _device, _function, 0x3c) >> 16; } uint8_t PCIStandardDevice::maxLatency( ) { - //return readPCIConfigWord(_bus, _device, _function, 0x3c+24); + return readPCIConfigWord(_bus, _device, _function, 0x3c) >> 24; } From a7457defe47fe7ae93d0cfefd8ff85b1e85d1d19 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 5 Mar 2018 07:24:55 -0600 Subject: [PATCH 110/171] PCI base functions clean up --- src/drivers/PCI/PCI.c | 198 +-------------------------------------- src/drivers/PCI/PCI.h | 96 ------------------- src/drivers/PCI/makefile | 2 +- 3 files changed, 2 insertions(+), 294 deletions(-) diff --git a/src/drivers/PCI/PCI.c b/src/drivers/PCI/PCI.c index 590a6cd65..326135215 100644 --- a/src/drivers/PCI/PCI.c +++ b/src/drivers/PCI/PCI.c @@ -16,37 +16,6 @@ uint8_t getPCIProgIF(uint8_t bus, uint8_t device, uint8_t function){ return (readPCIConfigWord(bus, device, function, 0x08) >> 8) & 0xFFFF; } -//TODO rewrite -/** - * read 32 bits from PCI config space - * @param bus - * @param slot - * @param func - * @param offset into config space - * @return uint32 of the config space starting at offset. - */ -/*uint32_t readPCIConfigWord(uint8_t bus, uint8_t slot, uint8_t func, - uint8_t offset) -{ - uint32_t address; - uint32_t lbus = (uint32_t)bus; - uint32_t lslot = (uint32_t)slot; - uint32_t lfunc = (uint32_t)func; - uint16_t tmp = 0; - - /* create configuration address as per Figure 1 - address = (uint32_t)((lbus << 16) | (lslot << 11) | - (lfunc << 8) | (offset & 0xfc) | ((uint32_t)0x80000000)); - - /* write out the address - //printf("reading PCI register (old): %x\n", address); - outl(0xCF8, address); - /* read in the data - /* (offset & 2) * 8) = 0 will choose the first word of the 32 bits register - tmp = (uint16_t)((inl(0xCFC) >> ((offset & 2) * 8)) & 0xffff); - return (tmp); -}*/ - uint32_t readPCIConfigWord/*New*/(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset) { ConfigAddress addr; @@ -129,12 +98,6 @@ void checkPCIFunction(uint8_t bus, uint8_t device, uint8_t func) break; } } - /*if (classCode == 0x604) - { - uint8_t secondBus = getPCISecondBus(bus, device, func); - printf(" is a PCI->PCI with a 2nd bus of %d\n", secondBus); - checkPCIBus(secondBus); - }*/ } uint16_t getPCIClass(uint8_t bus, uint8_t device, uint8_t func) @@ -145,163 +108,4 @@ uint16_t getPCIClass(uint8_t bus, uint8_t device, uint8_t func) uint8_t getPCISecondBus(uint8_t bus, uint8_t device, uint8_t func) { return readPCIConfigWord(bus, device, func, 0x18) >> 8; -} - -/* -//TODO clean up a lot - - -/** - * bool array of valid PCI buses - -bool validPCIBuses[256]; -/** - * inits the PCI sub system. finds all PCI buses - -void PCIInit( ) { - //make sure all buses are invalid - for (uint16_t i = 0; i < 256; i++){ - validPCIBuses[i] = false; - } - //check if the first bus multifunction, if so check each function for buses. - if (isPCIMultiFunctionDevice(0, 0, 0)) { - for (uint8_t function = 0; function < MAX_PCI_FUNCTION; function++) { - if ( !isValidPCIFunction(0, 0, function)) { - break; - } - //check the valid function - checkPCIBus(function); - } - } else { - //check the base function if not multifunction - checkPCIBus(0); - } -} -/** - * checks if the device is multifunction based on given function header type - * @param bus device is on - * @param device on bus - * @param function in device - * @return if device is multifunction - -bool isPCIMultiFunctionDevice(uint8_t bus, uint8_t device, uint8_t function) { - return ! ( (getPCIHeaderType(bus, device, function) & 0x80) == 0); -} -/** - * checks validity of function based off vender code - * @param bus - * @param device - * @param function - * @return if the function is a valid function - -bool isValidPCIFunction(uint8_t bus, uint8_t device, uint8_t function) { - return getPCIVenderID(bus, device, function) != 0xFFFF; -} -/** - * checks the vender of the pci device / function - * @param bus - * @param slot - * @param function - * @return vender ID - -uint16_t getPCIVenderID(uint8_t bus, uint8_t slot, uint8_t function) { - return readPCIConfigWord(bus, slot, function, 0); -} - -/** - * check devices on bus for other buses - * @param bus - -void checkPCIBus(uint8_t bus) { - uint8_t device; - //set that its a valid bus - validPCIBuses[bus] = true; - //check the devices on the bus - for (device = 0; device < 32; device++) { - checkPCIDevice(bus, device); - } -} -/** - * check device / function if it's a PCI bus - * @param bus - * @param device - * @param function - -void checkPCIFunction(uint8_t bus, uint8_t device, uint8_t function) { - uint8_t baseClass; - uint8_t subClass; - uint8_t secondaryBus; - //get the class codes - baseClass = getPCIBaseClass(bus, device, function); - subClass = getPCISubClass(bus, device, function); - //check the class codes to see if it's a bus - if ( (baseClass == 0x06) && (subClass == 0x04)) { - //check that bus - secondaryBus = getPCISecondaryBus(bus, device, function); - checkPCIBus(secondaryBus); - } -} -/** - * check device's functions to see if it holds a bus - * @param bus - * @param device - -void checkPCIDevice(uint8_t bus, uint8_t device) { - uint8_t function = 0; - - uint16_t vendorID = getPCIVenderID(bus, device, function); - if (vendorID == 0xFFFF) - return; // Device doesn't exist - checkPCIFunction(bus, device, function); - uint8_t headerType = getPCIHeaderType(bus, device, function); - if ( (headerType & 0x80) != 0) { - /* It is a multi-function device, so check remaining functions - for (function = 1; function < 8; function++) { - if (getPCIVenderID(bus, device, function) != 0xFFFF) { - checkPCIFunction(bus, device, function); - } - } - } -} -/** - * read the PCI base class from the config space - * @param bus - * @param device - * @param function - * @return base class - -uint8_t getPCIBaseClass(uint8_t bus, uint8_t device, uint8_t function){ - return readPCIConfigWord(bus,device,function,0xB); -} -/** - * read the PCI sub class from the config space - * @param bus - * @param device - * @param function - * @return sub class - -uint8_t getPCISubClass(uint8_t bus, uint8_t device, uint8_t function){ - return readPCIConfigWord(bus,device,function,0xA); -} -/** - * read the PCI header type from the config space - * @param bus - * @param device - * @param function - * @return header type - -uint8_t getPCIHeaderType(uint8_t bus, uint8_t device, uint8_t function){ - return readPCIConfigWord(bus,device,function,0xE); -} -/** - * read the PCI second bus from the config space for pci bridge devices - * @param bus - * @param device - * @param function - * @return secondary bus - -uint8_t getPCISecondaryBus(uint8_t bus, uint8_t device, uint8_t function){ - return readPCIConfigWord(bus,device,function, 0x19); -} - -*/ \ No newline at end of file +} \ No newline at end of file diff --git a/src/drivers/PCI/PCI.h b/src/drivers/PCI/PCI.h index 8099852b9..59df76baf 100644 --- a/src/drivers/PCI/PCI.h +++ b/src/drivers/PCI/PCI.h @@ -41,100 +41,4 @@ uint16_t getPCIClass(uint8_t bus, uint8_t device, uint8_t func); uint8_t getPCISecondBus(uint8_t bus, uint8_t device, uint8_t func); -/* - -/** - * bool array of valid PCI buses - -extern bool validPCIBuses[256]; -/** - * inits the PCI sub system. finds all PCI buses - -void PCIInit( ); -/** - * checks if the device is multifunction based on given function header type - * @param bus device is on - * @param device on bus - * @param function in device - * @return if device is multifunction - -bool isPCIMultiFunctionDevice(uint8_t bus, uint8_t device, uint8_t function); -/** - * checks validity of function based off vender code - * @param bus - * @param device - * @param function - * @return if the function is a valid function - -bool isValidPCIFunction(uint8_t bus, uint8_t device, uint8_t function); -/** - * checks the vender of the pci device / function - * @param bus - * @param slot - * @param function - * @return vender ID - -uint16_t getPCIVenderID(uint8_t bus, uint8_t slot, uint8_t function); -/** - * read 32 bits from PCI config space - * @param bus - * @param slot - * @param func - * @param offset into config space - * @return uint32 of the config space starting at offset. - -uint32_t readPCIConfigWord(uint8_t bus, uint8_t slot, uint8_t func, - uint8_t offset); -/** - * check devices on bus for other buses - * @param bus - -void checkPCIBus(uint8_t bus); -/** - * check device / function if it's a PCI bus - * @param bus - * @param device - * @param function - -void checkPCIFunction(uint8_t bus, uint8_t device, uint8_t function); -/** - * check device's functions to see if it holds a bus - * @param bus - * @param device - -void checkPCIDevice(uint8_t bus, uint8_t device); -/** - * read the PCI base class from the config space - * @param bus - * @param device - * @param function - * @return base class - -uint8_t getPCIBaseClass(uint8_t bus, uint8_t device, uint8_t function); -/** - * read the PCI sub class from the config space - * @param bus - * @param device - * @param function - * @return sub class - -uint8_t getPCISubClass(uint8_t bus, uint8_t device, uint8_t function); -/** - * read the PCI header type from the config space - * @param bus - * @param device - * @param function - * @return header type - -uint8_t getPCIHeaderType(uint8_t bus, uint8_t device, uint8_t function); -/** - * read the PCI second bus from the config space for pci bridge devices - * @param bus - * @param device - * @param function - * @return secondary bus - -uint8_t getPCISecondaryBus(uint8_t bus, uint8_t device, uint8_t function); -*/ - #endif /* SRC_DRIVERS_PCI_PCI_H_ */ diff --git a/src/drivers/PCI/makefile b/src/drivers/PCI/makefile index f427ff0e4..841df0454 100644 --- a/src/drivers/PCI/makefile +++ b/src/drivers/PCI/makefile @@ -1,4 +1,4 @@ -SUBDIRS = USB PCI_devices +SUBDIRS = USB #PCI_devices OBS = PCI.o PCIDeviceList.o include ../../../makefile.inc From 0248b58766c08857d7010f2b72c0c95f8be6d0d9 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 5 Mar 2018 07:28:38 -0600 Subject: [PATCH 111/171] mem alloc --- src/interrupts/InterruptHandler.h | 1 - src/memory/alloc/Malloc.c | 50 --------------------------- src/memory/alloc/PageFrameAllocator.h | 3 -- 3 files changed, 54 deletions(-) diff --git a/src/interrupts/InterruptHandler.h b/src/interrupts/InterruptHandler.h index 5768021f6..6d99f834d 100755 --- a/src/interrupts/InterruptHandler.h +++ b/src/interrupts/InterruptHandler.h @@ -9,6 +9,5 @@ #define INTERRUPTHANDLER_H_ #include "Global.h" -//#include "../drivers/Keyboard.h" #endif /* INTERRUPTHANDLER_H_ */ diff --git a/src/memory/alloc/Malloc.c b/src/memory/alloc/Malloc.c index 00c4dd9f4..10b0eec13 100644 --- a/src/memory/alloc/Malloc.c +++ b/src/memory/alloc/Malloc.c @@ -24,11 +24,6 @@ void mallocInit() ((memHeader*)&kernelEnd)->used = false; ((memHeader*)&kernelEnd)->next = nullptr; - /* - base = &kernelEnd; - top = (void*) ( (size_t)( &kernelSize) + (uint32_t) - & kernelStart + FOUR_KB); - */ } #if defined(__cplusplus) @@ -41,7 +36,6 @@ extern "C" {/* Use C linkage for kernel_main. */ */ void *malloc(size_t size) { - //TODO for loop memHeader* c = (memHeader*)&kernelEnd; for (; c != nullptr; c = c->next) { if (c->next == nullptr) { @@ -74,51 +68,7 @@ void *malloc(size_t size) } } return nullptr; - /*size += sizeof(memHeader); - //size_t space = (size_t) top - (size_t) & kernelEnd; - //if (space > size) { - //have space - for (memHeader *i = (memHeader*)&kernelEnd; i < top; i = i->next) { - if (i->next == nullptr && ((uint32_t)i - (uint32_t)top) > size && !(i->used)) { - //at end - i->used = true; - if (i->next == ((memHeader * )(((uint8_t *) i + 1) + size))) { - ((memHeader * )(((uint8_t *) i + 1) + size))->used = false; - ((memHeader * )(((uint8_t *) i + 1) + size))->next = i->next; - } - i->used = true; - i->next = (memHeader*)(((uint8_t *) i + 1) + size); - return i + sizeof(memHeader); - } else if ((i - i->next) > size && !(i->used)) { - return i + sizeof(memHeader); - } - } - //} else { - //need to page in - //TODO handle out of mem - void *startOfNewMem = frameAlloc.allocatePhysMem(size, pageTable.getKernelStart()); - size_t sizeOfNewMem = ((size) / FOUR_KB + (((size) & 0xFFF) != 0)) * FOUR_KB; - top = (void *) ((size_t) top + sizeOfNewMem + ((size_t) startOfNewMem - (size_t) top)); - return malloc(size); - //} - - size_t space = (size_t) top - (size_t) base; - if (space > size) { - //if there is space in the current phys mem allocated - void* oldBase = base; - //move the base address - base = (void*) ((size_t) base + size); - //return the start of allocated space - return oldBase; - } else { - //TODO take into account out of mem - void* startOfNewMem = frameAlloc.allocatePhysMem(size - space,pageTable.getKernelStart()); - size_t sizeOfNewMem = ((size-space)/FOUR_KB + ( ((size-space) & 0xFFF) != 0)) * FOUR_KB; - top = (void*) ((size_t) top + sizeOfNewMem + ((size_t)startOfNewMem - (size_t)top) ); - return malloc(size); - } - */ } /** diff --git a/src/memory/alloc/PageFrameAllocator.h b/src/memory/alloc/PageFrameAllocator.h index ab5985662..6c89ceeb6 100755 --- a/src/memory/alloc/PageFrameAllocator.h +++ b/src/memory/alloc/PageFrameAllocator.h @@ -10,9 +10,6 @@ #include "Global.h" -//#include "../../kernel.h" -//#include "../structures/PageTable.h" - class PageFrameAllocator { private: /** From 7849499b12546e87dbac2fbdcaffdb56e14ccfc1 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 5 Mar 2018 07:30:36 -0600 Subject: [PATCH 112/171] mem clean up --- src/memory/structures/GlobalDescriptorTable.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/memory/structures/GlobalDescriptorTable.h b/src/memory/structures/GlobalDescriptorTable.h index 8b0760d8b..3d5466812 100755 --- a/src/memory/structures/GlobalDescriptorTable.h +++ b/src/memory/structures/GlobalDescriptorTable.h @@ -75,8 +75,6 @@ class GlobalDescriptorTable { GdtDescriptor gdtd; public: GlobalDescriptorTable( ) ; - //GlobalDescriptorTable( const GlobalDescriptorTable &) = delete; - //auto operator= (const GlobalDescriptorTable &) = delete; /** * encode gdt entry * @param limit From c0f5ffcc6cf6e00903919fa64e9beacf40eb77ef Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 5 Mar 2018 07:31:56 -0600 Subject: [PATCH 113/171] rest of clean up --- src/Kernel.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Kernel.cpp b/src/Kernel.cpp index 2df32d7dd..9500ba0bb 100644 --- a/src/Kernel.cpp +++ b/src/Kernel.cpp @@ -63,15 +63,13 @@ void kernelMain(multiboot_info_t *mbd) terminalWriteLine(" Done!"); terminalWriteString(" Finding PCI buses..."); //find the valid PCI buses - //PCIInit(); - //test code enumPCIDevices(); terminalWriteLine(" Done!"); - terminalWriteString(" Finding USB host controllers..."); + //terminalWriteString(" Finding USB host controllers..."); //find the (3 or less) USB host controllers. all have the same class/subclass code. //PCIDeviceList usbHostControllers(0x0C, 0x03, false); - terminalWriteLine(" Done!"); + //terminalWriteLine(" Done!"); terminalWriteLine("!!!!ExOS fully booted!!!!"); //dont return. while (true) { From aff5d7c6c2fc3cd54f2892f826fa42a57cc3fc3b Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 6 Mar 2018 07:59:16 -0600 Subject: [PATCH 114/171] moving comps --- .../PCI/USB/USB_tree/USBPeripheral.cpp | 1 + src/drivers/PCI/USB/USB_tree/USBPeripheral.h | 28 +++++++++++++++++++ src/drivers/PCI/USB/USB_tree/makefile | 3 ++ src/drivers/PCI/USB/makefile | 2 +- 4 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp create mode 100644 src/drivers/PCI/USB/USB_tree/USBPeripheral.h create mode 100644 src/drivers/PCI/USB/USB_tree/makefile diff --git a/src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp b/src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp new file mode 100644 index 000000000..280fbe465 --- /dev/null +++ b/src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp @@ -0,0 +1 @@ +#include "USBPeripheral.h" \ No newline at end of file diff --git a/src/drivers/PCI/USB/USB_tree/USBPeripheral.h b/src/drivers/PCI/USB/USB_tree/USBPeripheral.h new file mode 100644 index 000000000..1ff4eddba --- /dev/null +++ b/src/drivers/PCI/USB/USB_tree/USBPeripheral.h @@ -0,0 +1,28 @@ +#ifndef USB_PERIPHERAL_H_ +#define USB_PERIPHERAL_H_ + +#include "Global.h" + +class USBPeripheral +{ + private: + USBPeripheral **_ports; + size_t _portCount; + size_t _port; + + public: + USBPeripheral(size_t port, size_t portCount) + { + _port = port; + _portCount = portCount; + _ports = (USBPeripheral**) malloc(sizeof(USBPeripheral *) * portCount); + memSet((void*)_ports, (sizeof(USBPeripheral*) * portCount), 0); + } + void add(size_t port, USBPeripheral* toAdd) + { + assert(_ports[port] == nullptr); + _ports[port] = toAdd; + } +}; + +#endif \ No newline at end of file diff --git a/src/drivers/PCI/USB/USB_tree/makefile b/src/drivers/PCI/USB/USB_tree/makefile new file mode 100644 index 000000000..bcd6a5273 --- /dev/null +++ b/src/drivers/PCI/USB/USB_tree/makefile @@ -0,0 +1,3 @@ +SUBDIRS = +OBS = USBPeripheral.o +include ../../../../../makefile.inc \ No newline at end of file diff --git a/src/drivers/PCI/USB/makefile b/src/drivers/PCI/USB/makefile index 41d7f4e74..a77727d67 100644 --- a/src/drivers/PCI/USB/makefile +++ b/src/drivers/PCI/USB/makefile @@ -1,4 +1,4 @@ -SUBDIRS = HostController +SUBDIRS = HostController USB_tree OBS = USB.o USBEvent.o include ../../../../makefile.inc \ No newline at end of file From 3f06911142bf81616d16a6827d7f29e4dae65952 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 6 Mar 2018 08:20:45 -0600 Subject: [PATCH 115/171] i did a dumb --- #.bochsrc# | 55 ++++++++++++++++++ -ffreestanding | Bin 0 -> 180068 bytes .bochsrc.old | 57 +++++++++++++++++++ makefile.inc | 8 +-- src/drivers/PCI/USB/USB_tree/USBPeripheral.h | 16 ++---- 5 files changed, 120 insertions(+), 16 deletions(-) create mode 100644 #.bochsrc# create mode 100755 -ffreestanding create mode 100644 .bochsrc.old diff --git a/#.bochsrc# b/#.bochsrc# new file mode 100644 index 000000000..e45fd4ca7 --- /dev/null +++ b/#.bochsrc# @@ -0,0 +1,55 @@ +# configuration file generated by Bochs +plugin_ctrl: unmapped=1, biosdev=1, speaker=1, extfpuirq=1, parallel=1, serial=1, gameport=1 +config_interface: textconfig +display_library: x +memory: host=32, guest=32 +romimage: file="/usr/share/bochs/BIOS-bochs-latest", address=0x0, options=none +vgaromimage: file="/usr/share/bochs/VGABIOS-lgpl-latest" +boot: floppy +floppy_bootsig_check: disabled=0 +floppya: type=1_44, 1_44="/dev/sdf", status=inserted, write_protected=0 +# no floppyb +ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 +ata0-master: type=none +ata0-slave: type=none +ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15 +ata1-master: type=none +ata1-slave: type=none +ata2: enabled=0 +ata3: enabled=0 +optromimage1: file=none +optromimage2: file=none +optromimage3: file=none +optromimage4: file=none +optramimage1: file=none +optramimage2: file=none +optramimage3: file=none +optramimage4: file=none +pci: enabled=1, chipset=i440fx +vga: extension=vbe, update_freq=5, realtime=1 +cpu: count=1:1:1, ips=4000000, quantum=16, model=bx_generic, reset_on_triple_fault=1, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0 +cpuid: level=6, stepping=3, model=3, family=6, vendor_string="GenuineIntel", brand_string=" Intel(R) Pentium(R) 4 CPU " +cpuid: mmx=1, apic=xapic, simd=sse2, sse4a=0, misaligned_sse=0, sep=1, movbe=0, adx=0 +cpuid: aes=0, sha=0, xsave=0, xsaveopt=0, x86_64=1, 1g_pages=0, pcid=0, fsgsbase=0 +cpuid: smep=0, smap=0, mwait=1 +print_timestamps: enabled=0 +port_e9_hack: enabled=0 +private_colormap: enabled=0 +clock: sync=none, time0=local, rtc_sync=0 +# no cmosimage +# no loader +log: - +logprefix: %t%e%d +debug: action=ignore +info: action=report +error: action=report +panic: action=ask +keyboard: type=mf, serial_delay=250, paste_delay=100000, user_shortcut=none +mouse: type=ps2, enabled=0, toggle=ctrl+mbutton +speaker: enabled=1, mode=system +parport1: enabled=1, file=none +parport2: enabled=0 +com1: enabled=1, mode=null +com2: enabled=0 +com3: enabled=0 +com4: enabled=0 diff --git a/-ffreestanding b/-ffreestanding new file mode 100755 index 0000000000000000000000000000000000000000..be30b2908e7bd2a81710de4928ca97a0c70485d5 GIT binary patch literal 180068 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�Cjb!z9Eqp~oHz}cMV_@uPkamw6nR15 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 Date: Tue, 6 Mar 2018 08:36:54 -0600 Subject: [PATCH 116/171] USBPeripheral contructor --- -ffreestanding | Bin 180068 -> 0 bytes makefile.inc | 2 +- .../PCI/USB/USB_tree/USBPeripheral.cpp | 30 +++++++++++++++++- src/drivers/PCI/USB/USB_tree/USBPeripheral.h | 5 ++- 4 files changed, 34 insertions(+), 3 deletions(-) delete mode 100755 -ffreestanding diff --git a/-ffreestanding b/-ffreestanding deleted file mode 100755 index be30b2908e7bd2a81710de4928ca97a0c70485d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 180068 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�Cjb!z9Eqp~oHz}cMV_@uPkamw6nR15 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 Date: Tue, 6 Mar 2018 08:39:48 -0600 Subject: [PATCH 117/171] i really should make before i commit --- src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp | 12 ++++++------ src/drivers/PCI/USB/USB_tree/USBPeripheral.h | 6 ++++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp b/src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp index ed0c93a1a..0152c16b9 100644 --- a/src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp +++ b/src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp @@ -7,21 +7,21 @@ USBPeripheral::USBPeripheral(size_t port, size_t portCount, USBPeripheral* paren memSet((void*)_ports, (sizeof(USBPeripheral*) * portCount), 0); _parent = parent; if (parent != nullptr){ - parent.add(port, this); + parent->add(port, this); } } void USBPeripheral::add(size_t port, USBPeripheral* toAdd){ //TODO not done - if (_portCour== 1){ - toadd._left(nullptr); - toAdd.right(nullptr); + if (_portCount== 1){ + toAdd->left(nullptr); + toAdd->right(nullptr); } if (port == 0){ - toadd._left(nullptr); + toAdd->left(nullptr); //TODo right } else if (_portCount -1 == port){ //TODO left - toAdd.right(nullptr); + toAdd->right(nullptr); } else { //TODO both } diff --git a/src/drivers/PCI/USB/USB_tree/USBPeripheral.h b/src/drivers/PCI/USB/USB_tree/USBPeripheral.h index e49e273ce..7e0459b79 100644 --- a/src/drivers/PCI/USB/USB_tree/USBPeripheral.h +++ b/src/drivers/PCI/USB/USB_tree/USBPeripheral.h @@ -18,6 +18,12 @@ class USBPeripheral size_t portCount(){ return _portCount; } + void left(USBPeripheral* sib){ + _left = sib; + } + void right(USBPeripheral* sib){ + _left = sib; + } }; #endif \ No newline at end of file From 5a996f8d12b24c60d57d0873fcb99474600deeb8 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 6 Mar 2018 09:24:02 -0600 Subject: [PATCH 118/171] USBPer add --- .../PCI/USB/USB_tree/USBPeripheral.cpp | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp b/src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp index 0152c16b9..d12531a32 100644 --- a/src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp +++ b/src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp @@ -12,18 +12,42 @@ USBPeripheral::USBPeripheral(size_t port, size_t portCount, USBPeripheral* paren } void USBPeripheral::add(size_t port, USBPeripheral* toAdd){ //TODO not done + + _ports[port] = toAdd; + if (_portCount== 1){ toAdd->left(nullptr); toAdd->right(nullptr); } if (port == 0){ toAdd->left(nullptr); - //TODo right + for (int i = port; i < _portCount; i++){ + if (_ports[i] != nullptr){ + toAdd->right(_ports[i]); + break; + } + } } else if (_portCount -1 == port){ - //TODO left + for (int i = port; i > 0; i--){ + if (_ports[i] != nullptr){ + toAdd->left(_ports[i]); + break; + } + } toAdd->right(nullptr); } else { - //TODO both + for (int i = port; i > 0; i--){ + if (_ports[i] != nullptr){ + toAdd->left(_ports[i]); + break; + } + } + for (int i = port; i < _portCount; i++){ + if (_ports[i] != nullptr){ + toAdd->right(_ports[i]); + break; + } + } } } \ No newline at end of file From e297e46ef7946ac2c255293cc4e072fb05f6e3fd Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 6 Mar 2018 10:20:40 -0600 Subject: [PATCH 119/171] remove --- src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp | 8 +++++++- src/drivers/PCI/USB/USB_tree/USBPeripheral.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp b/src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp index d12531a32..9630ccfef 100644 --- a/src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp +++ b/src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp @@ -50,4 +50,10 @@ void USBPeripheral::add(size_t port, USBPeripheral* toAdd){ } } -} \ No newline at end of file +} + + void USBPeripheral::remove(size_t port){ + assert(_ports[port] != nullptr); + _ports[port]->_right->_left = _ports[port]->_left; + _ports[port]->_left->_right = _ports[port]->_right; + } \ No newline at end of file diff --git a/src/drivers/PCI/USB/USB_tree/USBPeripheral.h b/src/drivers/PCI/USB/USB_tree/USBPeripheral.h index 7e0459b79..1265aea3f 100644 --- a/src/drivers/PCI/USB/USB_tree/USBPeripheral.h +++ b/src/drivers/PCI/USB/USB_tree/USBPeripheral.h @@ -15,6 +15,7 @@ class USBPeripheral public: USBPeripheral(size_t port, size_t portCount, USBPeripheral* parent); void add(size_t port, USBPeripheral* toAdd); + void remove(size_t port); size_t portCount(){ return _portCount; } From 18ac264732390c7ea1e724506830adcd999e7eb6 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 6 Mar 2018 10:47:59 -0600 Subject: [PATCH 120/171] other USB device types classes --- src/drivers/PCI/USB/USB_tree/USBDevice.cpp | 1 + src/drivers/PCI/USB/USB_tree/USBDevice.h | 9 +++++++++ src/drivers/PCI/USB/USB_tree/USBHub.cpp | 1 + src/drivers/PCI/USB/USB_tree/USBHub.h | 9 +++++++++ src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp | 1 + src/drivers/PCI/USB/USB_tree/makefile | 2 +- 6 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 src/drivers/PCI/USB/USB_tree/USBDevice.cpp create mode 100644 src/drivers/PCI/USB/USB_tree/USBDevice.h create mode 100644 src/drivers/PCI/USB/USB_tree/USBHub.cpp create mode 100644 src/drivers/PCI/USB/USB_tree/USBHub.h diff --git a/src/drivers/PCI/USB/USB_tree/USBDevice.cpp b/src/drivers/PCI/USB/USB_tree/USBDevice.cpp new file mode 100644 index 000000000..7015f7399 --- /dev/null +++ b/src/drivers/PCI/USB/USB_tree/USBDevice.cpp @@ -0,0 +1 @@ +#include "USBDevice.h" \ No newline at end of file diff --git a/src/drivers/PCI/USB/USB_tree/USBDevice.h b/src/drivers/PCI/USB/USB_tree/USBDevice.h new file mode 100644 index 000000000..fbb06456d --- /dev/null +++ b/src/drivers/PCI/USB/USB_tree/USBDevice.h @@ -0,0 +1,9 @@ +#ifndef USB_DEVICE_H_ +#define USB_DEVICE_H_ + +#include "USBPeripheral.h" + class USBDevice: public USBPeripheral{ + + }; + +#endif \ No newline at end of file diff --git a/src/drivers/PCI/USB/USB_tree/USBHub.cpp b/src/drivers/PCI/USB/USB_tree/USBHub.cpp new file mode 100644 index 000000000..c11a9aa60 --- /dev/null +++ b/src/drivers/PCI/USB/USB_tree/USBHub.cpp @@ -0,0 +1 @@ +#include "USBHub.h" \ No newline at end of file diff --git a/src/drivers/PCI/USB/USB_tree/USBHub.h b/src/drivers/PCI/USB/USB_tree/USBHub.h new file mode 100644 index 000000000..5ee07fff6 --- /dev/null +++ b/src/drivers/PCI/USB/USB_tree/USBHub.h @@ -0,0 +1,9 @@ +#ifndef USB_HUB_H_ +#define USB_HUB_H_ + +#include "USBPeripheral.h" + class USBHub: public USBPeripheral{ + + }; + +#endif \ No newline at end of file diff --git a/src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp b/src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp index 9630ccfef..354d4cd5a 100644 --- a/src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp +++ b/src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp @@ -56,4 +56,5 @@ void USBPeripheral::add(size_t port, USBPeripheral* toAdd){ assert(_ports[port] != nullptr); _ports[port]->_right->_left = _ports[port]->_left; _ports[port]->_left->_right = _ports[port]->_right; + _ports[port] = nullptr; } \ No newline at end of file diff --git a/src/drivers/PCI/USB/USB_tree/makefile b/src/drivers/PCI/USB/USB_tree/makefile index bcd6a5273..078ec5144 100644 --- a/src/drivers/PCI/USB/USB_tree/makefile +++ b/src/drivers/PCI/USB/USB_tree/makefile @@ -1,3 +1,3 @@ SUBDIRS = -OBS = USBPeripheral.o +OBS = USBPeripheral.o USBDevice.o USBHub.o include ../../../../../makefile.inc \ No newline at end of file From b6f625f2118f01b62fe0537aaf53ee8c3688f922 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Wed, 7 Mar 2018 06:37:29 -0600 Subject: [PATCH 121/171] I put the cart before the horse starting onver on most of USB --- .../PCI/USB/HostController/HostController.cpp | 26 ------ .../PCI/USB/HostController/HostController.h | 41 --------- src/drivers/PCI/USB/HostController/OHCI.cpp | 18 ---- src/drivers/PCI/USB/HostController/OHCI.h | 86 ------------------- src/drivers/PCI/USB/HostController/makefile | 3 - src/drivers/PCI/USB/USBController.cpp | 16 ---- src/drivers/PCI/USB/USBController.h | 19 ---- src/drivers/PCI/USB/USBEvent.cpp | 17 ---- src/drivers/PCI/USB/USBEvent.h | 17 ---- src/drivers/PCI/USB/USB_tree/USBDevice.cpp | 1 - src/drivers/PCI/USB/USB_tree/USBDevice.h | 9 -- src/drivers/PCI/USB/USB_tree/USBHub.cpp | 1 - src/drivers/PCI/USB/USB_tree/USBHub.h | 9 -- .../PCI/USB/USB_tree/USBPeripheral.cpp | 60 ------------- src/drivers/PCI/USB/USB_tree/USBPeripheral.h | 30 ------- src/drivers/PCI/USB/USB_tree/makefile | 3 - 16 files changed, 356 deletions(-) delete mode 100644 src/drivers/PCI/USB/HostController/HostController.cpp delete mode 100644 src/drivers/PCI/USB/HostController/HostController.h delete mode 100644 src/drivers/PCI/USB/HostController/OHCI.cpp delete mode 100644 src/drivers/PCI/USB/HostController/OHCI.h delete mode 100644 src/drivers/PCI/USB/HostController/makefile delete mode 100644 src/drivers/PCI/USB/USBController.cpp delete mode 100644 src/drivers/PCI/USB/USBController.h delete mode 100644 src/drivers/PCI/USB/USBEvent.cpp delete mode 100644 src/drivers/PCI/USB/USBEvent.h delete mode 100644 src/drivers/PCI/USB/USB_tree/USBDevice.cpp delete mode 100644 src/drivers/PCI/USB/USB_tree/USBDevice.h delete mode 100644 src/drivers/PCI/USB/USB_tree/USBHub.cpp delete mode 100644 src/drivers/PCI/USB/USB_tree/USBHub.h delete mode 100644 src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp delete mode 100644 src/drivers/PCI/USB/USB_tree/USBPeripheral.h delete mode 100644 src/drivers/PCI/USB/USB_tree/makefile diff --git a/src/drivers/PCI/USB/HostController/HostController.cpp b/src/drivers/PCI/USB/HostController/HostController.cpp deleted file mode 100644 index 7297e3c14..000000000 --- a/src/drivers/PCI/USB/HostController/HostController.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/* - * HostController.cpp - * - * Created on: Aug 31, 2017 - * Author: garrett - */ - -#include "HostController.h" - -HostController::HostController( ) { - // TODO Auto-generated constructor stub - -} - -HostController::~HostController( ) { - // TODO Auto-generated destructor stub -} - -USBEvent* HostController::poll(){ - //new usbevent array , default size = 5 - //for each host controller - //check each known hub for info - //for each known hub - //check each device for info - //retunr array -} diff --git a/src/drivers/PCI/USB/HostController/HostController.h b/src/drivers/PCI/USB/HostController/HostController.h deleted file mode 100644 index 512bdd9af..000000000 --- a/src/drivers/PCI/USB/HostController/HostController.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * HostController.h - * - * Created on: Aug 31, 2017 - * Author: garrett - */ - -#ifndef SRC_DRIVERS_PCI_USB_HOSTCONTROLLER_HOSTCONTROLLER_H_ -#define SRC_DRIVERS_PCI_USB_HOSTCONTROLLER_HOSTCONTROLLER_H_ - -#include "Global.h" -#include "drivers/PCI/USB/USBEvent.h" -class HostController { - protected: - void* _BAR0; - void* _BAR1; - void* _BAR2; - void* _BAR3; - void* _BAR4; - public: - HostController( ); - HostController(void** baseAddresses) { - _BAR0 = baseAddresses[0]; - _BAR1 = baseAddresses[1]; - _BAR2 = baseAddresses[2]; - _BAR3 = baseAddresses[3]; - _BAR4 = baseAddresses[4]; - } - HostController(void* BAR0, void* BAR1 = nullptr, void* BAR2 = nullptr, - void* BAR3 = nullptr, void* BAR4 = nullptr) { - _BAR0 = BAR0; - _BAR1 = BAR1; - _BAR2 = BAR2; - _BAR3 = BAR3; - _BAR4 = BAR4; - } - virtual ~HostController( ); - USBEvent* poll(); -}; - -#endif /* SRC_DRIVERS_PCI_USB_HOSTCONTROLLER_HOSTCONTROLLER_H_ */ diff --git a/src/drivers/PCI/USB/HostController/OHCI.cpp b/src/drivers/PCI/USB/HostController/OHCI.cpp deleted file mode 100644 index c1da94aa0..000000000 --- a/src/drivers/PCI/USB/HostController/OHCI.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* - * OHCI.cpp - * - * Created on: Aug 31, 2017 - * Author: garrett - */ - -#include "OHCI.h" - -OHCI::OHCI( ) { - // TODO Auto-generated constructor stub - -} - -OHCI::~OHCI( ) { - // TODO Auto-generated destructor stub -} - diff --git a/src/drivers/PCI/USB/HostController/OHCI.h b/src/drivers/PCI/USB/HostController/OHCI.h deleted file mode 100644 index d481857d5..000000000 --- a/src/drivers/PCI/USB/HostController/OHCI.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * OHCI.h - * - * Created on: Aug 31, 2017 - * Author: garrett - */ - -#ifndef SRC_DRIVERS_PCI_USB_HOSTCONTROLLER_OHCI_H_ -#define SRC_DRIVERS_PCI_USB_HOSTCONTROLLER_OHCI_H_ - -#include "Global.h" -#include "HostController.h" - -class OHCI: public HostController { - public: - OHCI( ); - OHCI(void* BAR0) : - HostController(BAR0) { - - } - virtual ~OHCI( ); - uint32_t revision( ) { - return * ((uint32_t*) _BAR0); - } - uint32_t commandStatus( ) { - return * ((uint32_t*) _BAR0 + 1); - } - uint32_t interruptStatus( ) { - return * ((uint32_t*) _BAR0 +2 ); - } - uint32_t interruptEnable( ) { - return * ((uint32_t*) _BAR0+3); - } - uint32_t interruptDisable( ) { - return * ((uint32_t*) _BAR0+4); - } - uint32_t HCCA( ) { - return * ((uint32_t*) _BAR0+5); - } - uint32_t periodCurrent( ) { - return * ((uint32_t*) _BAR0+6); - } - uint32_t controlHead( ) { - return * ((uint32_t*) _BAR0+7); - } - uint32_t controlCurrent( ) { - return * ((uint32_t*) _BAR0+8); - } - uint32_t bulkHead( ) { - return * ((uint32_t*) _BAR0+9); - } - uint32_t bulkCurrent( ) { - return * ((uint32_t*) _BAR0+10); - } - uint32_t doneHead( ) { - return * ((uint32_t*) _BAR0+11); - } - uint32_t fmInterval( ) { - return * ((uint32_t*) _BAR0+12); - } - uint32_t fmRemaining( ) { - return * ((uint32_t*) _BAR0+13); - - } - uint32_t fmNumber( ) { - return * ((uint32_t*) _BAR0+14); - } - uint32_t periodicStart( ) { - return * ((uint32_t*) _BAR0+15); - } - uint32_t lsThreshold( ) { - return * ((uint32_t*) _BAR0+16); - } - uint32_t rhDescriptorA( ) { - return * ((uint32_t*) _BAR0+17); - - } - uint32_t rhDescriptorB( ) { - return * ((uint32_t*) _BAR0+18); - } - uint32_t rhStatus( ) { - return * ((uint32_t*) _BAR0+19); - } -}; - -#endif /* SRC_DRIVERS_PCI_USB_HOSTCONTROLLER_OHCI_H_ */ diff --git a/src/drivers/PCI/USB/HostController/makefile b/src/drivers/PCI/USB/HostController/makefile deleted file mode 100644 index 957883fd2..000000000 --- a/src/drivers/PCI/USB/HostController/makefile +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = -OBS = OHCI.o HostController.o -include ../../../../../makefile.inc \ No newline at end of file diff --git a/src/drivers/PCI/USB/USBController.cpp b/src/drivers/PCI/USB/USBController.cpp deleted file mode 100644 index 606819565..000000000 --- a/src/drivers/PCI/USB/USBController.cpp +++ /dev/null @@ -1,16 +0,0 @@ -/* - * USBController.cpp - * - * Created on: Jul 12, 2017 - * Author: garrett - */ - -#include "drivers/PCI/USB/USBController.h" - - -USBController::USBController( ) { - // TODO Auto-generated constructor stub - -} - - diff --git a/src/drivers/PCI/USB/USBController.h b/src/drivers/PCI/USB/USBController.h deleted file mode 100644 index da804efe8..000000000 --- a/src/drivers/PCI/USB/USBController.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * USBController.h - * - * Created on: Jul 12, 2017 - * Author: garrett - */ - -#ifndef USBCONTROLLER_H_ -#define USBCONTROLLER_H_ - -#include "Global.h" -#include "drivers/PCI/PCI_devices/PCIStandardDevice.h" - -class USBController :public PCIStandardDevice{ - public: - USBController( ); -}; - -#endif /* USBCONTROLLER_H_ */ diff --git a/src/drivers/PCI/USB/USBEvent.cpp b/src/drivers/PCI/USB/USBEvent.cpp deleted file mode 100644 index 13aab57f6..000000000 --- a/src/drivers/PCI/USB/USBEvent.cpp +++ /dev/null @@ -1,17 +0,0 @@ -/* - * USBEvent.cpp - * - * Created on: Jan 16, 2018 - * Author: garrett - */ -#include "USBEvent.h" - -USBEvent::USBEvent( ) { - // TODO Auto-generated constructor stub - -} - -USBEvent::~USBEvent( ) { - // TODO Auto-generated destructor stub -} - diff --git a/src/drivers/PCI/USB/USBEvent.h b/src/drivers/PCI/USB/USBEvent.h deleted file mode 100644 index 836e52971..000000000 --- a/src/drivers/PCI/USB/USBEvent.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * USBEvent.h - * - * Created on: Jan 16, 2018 - * Author: garrett - */ - -#ifndef SRC_DRIVERS_PCI_USB_USBEVENT_H_ -#define SRC_DRIVERS_PCI_USB_USBEVENT_H_ - -class USBEvent { - public: - USBEvent( ); - virtual ~USBEvent( ); -}; - -#endif /* SRC_DRIVERS_PCI_USB_USBEVENT_H_ */ diff --git a/src/drivers/PCI/USB/USB_tree/USBDevice.cpp b/src/drivers/PCI/USB/USB_tree/USBDevice.cpp deleted file mode 100644 index 7015f7399..000000000 --- a/src/drivers/PCI/USB/USB_tree/USBDevice.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "USBDevice.h" \ No newline at end of file diff --git a/src/drivers/PCI/USB/USB_tree/USBDevice.h b/src/drivers/PCI/USB/USB_tree/USBDevice.h deleted file mode 100644 index fbb06456d..000000000 --- a/src/drivers/PCI/USB/USB_tree/USBDevice.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef USB_DEVICE_H_ -#define USB_DEVICE_H_ - -#include "USBPeripheral.h" - class USBDevice: public USBPeripheral{ - - }; - -#endif \ No newline at end of file diff --git a/src/drivers/PCI/USB/USB_tree/USBHub.cpp b/src/drivers/PCI/USB/USB_tree/USBHub.cpp deleted file mode 100644 index c11a9aa60..000000000 --- a/src/drivers/PCI/USB/USB_tree/USBHub.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "USBHub.h" \ No newline at end of file diff --git a/src/drivers/PCI/USB/USB_tree/USBHub.h b/src/drivers/PCI/USB/USB_tree/USBHub.h deleted file mode 100644 index 5ee07fff6..000000000 --- a/src/drivers/PCI/USB/USB_tree/USBHub.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef USB_HUB_H_ -#define USB_HUB_H_ - -#include "USBPeripheral.h" - class USBHub: public USBPeripheral{ - - }; - -#endif \ No newline at end of file diff --git a/src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp b/src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp deleted file mode 100644 index 354d4cd5a..000000000 --- a/src/drivers/PCI/USB/USB_tree/USBPeripheral.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "USBPeripheral.h" - -USBPeripheral::USBPeripheral(size_t port, size_t portCount, USBPeripheral* parent){ - _port = port; - _portCount = portCount; - _ports = (USBPeripheral**) malloc(sizeof(USBPeripheral*)*portCount); - memSet((void*)_ports, (sizeof(USBPeripheral*) * portCount), 0); - _parent = parent; - if (parent != nullptr){ - parent->add(port, this); - } -} -void USBPeripheral::add(size_t port, USBPeripheral* toAdd){ - //TODO not done - - _ports[port] = toAdd; - - if (_portCount== 1){ - toAdd->left(nullptr); - toAdd->right(nullptr); - } - if (port == 0){ - toAdd->left(nullptr); - for (int i = port; i < _portCount; i++){ - if (_ports[i] != nullptr){ - toAdd->right(_ports[i]); - break; - } - } - } else if (_portCount -1 == port){ - for (int i = port; i > 0; i--){ - if (_ports[i] != nullptr){ - toAdd->left(_ports[i]); - break; - } - } - toAdd->right(nullptr); - } else { - for (int i = port; i > 0; i--){ - if (_ports[i] != nullptr){ - toAdd->left(_ports[i]); - break; - } - } - for (int i = port; i < _portCount; i++){ - if (_ports[i] != nullptr){ - toAdd->right(_ports[i]); - break; - } - } - } - -} - - void USBPeripheral::remove(size_t port){ - assert(_ports[port] != nullptr); - _ports[port]->_right->_left = _ports[port]->_left; - _ports[port]->_left->_right = _ports[port]->_right; - _ports[port] = nullptr; - } \ No newline at end of file diff --git a/src/drivers/PCI/USB/USB_tree/USBPeripheral.h b/src/drivers/PCI/USB/USB_tree/USBPeripheral.h deleted file mode 100644 index 1265aea3f..000000000 --- a/src/drivers/PCI/USB/USB_tree/USBPeripheral.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef USB_PERIPHERAL_H_ -#define USB_PERIPHERAL_H_ - -#include "Global.h" - -class USBPeripheral -{ - protected: - USBPeripheral **_ports; - size_t _portCount; - size_t _port; - USBPeripheral *_left, *_right, *_parent; - - - public: - USBPeripheral(size_t port, size_t portCount, USBPeripheral* parent); - void add(size_t port, USBPeripheral* toAdd); - void remove(size_t port); - size_t portCount(){ - return _portCount; - } - void left(USBPeripheral* sib){ - _left = sib; - } - void right(USBPeripheral* sib){ - _left = sib; - } -}; - -#endif \ No newline at end of file diff --git a/src/drivers/PCI/USB/USB_tree/makefile b/src/drivers/PCI/USB/USB_tree/makefile deleted file mode 100644 index 078ec5144..000000000 --- a/src/drivers/PCI/USB/USB_tree/makefile +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = -OBS = USBPeripheral.o USBDevice.o USBHub.o -include ../../../../../makefile.inc \ No newline at end of file From 5bc37cccfc6e1348354de612afb906ddb790e9e4 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Wed, 7 Mar 2018 06:51:14 -0600 Subject: [PATCH 122/171] forgot to remove old refrences --- src/drivers/PCI/USB/USB.c | 2 +- src/drivers/PCI/USB/USB.h | 4 ++-- src/drivers/PCI/USB/makefile | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/drivers/PCI/USB/USB.c b/src/drivers/PCI/USB/USB.c index 727e876a5..a2670dfce 100644 --- a/src/drivers/PCI/USB/USB.c +++ b/src/drivers/PCI/USB/USB.c @@ -10,7 +10,7 @@ //TODO better host coontroller marking uint8_t maxUSBVersion = 0; -USBController* uSBControllers; +//USBController* uSBControllers; void USBInit(){//how it works: //TODO: diff --git a/src/drivers/PCI/USB/USB.h b/src/drivers/PCI/USB/USB.h index 13e257b33..81bd9028e 100644 --- a/src/drivers/PCI/USB/USB.h +++ b/src/drivers/PCI/USB/USB.h @@ -9,10 +9,10 @@ #define SRC_DRIVERS_PCI_USB_USB_H_ #include "Global.h" -class USBController; +//class USBController; extern uint8_t maxUSBVersion; -extern USBController* uSBControllers; +//extern USBController* uSBControllers; void USBInit(); void addUSBHostController(int bus, int device, int function); diff --git a/src/drivers/PCI/USB/makefile b/src/drivers/PCI/USB/makefile index a77727d67..bd4e84a27 100644 --- a/src/drivers/PCI/USB/makefile +++ b/src/drivers/PCI/USB/makefile @@ -1,4 +1,4 @@ -SUBDIRS = HostController USB_tree -OBS = USB.o USBEvent.o +SUBDIRS = +OBS = USB.o include ../../../../makefile.inc \ No newline at end of file From f5e377dbd2aa3a431cad203872d38730e10bc588 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 19 Mar 2018 09:54:28 -0500 Subject: [PATCH 123/171] Update README.MD --- README.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.MD b/README.MD index be9326c57..70199fec7 100755 --- a/README.MD +++ b/README.MD @@ -15,7 +15,7 @@ ExOS extends the [MIT exokernel](https://pdos.csail.mit.edu/archive/exo/) by rem ## Short term work * Garrett - - [ ] Read USB spec - still going, its long + - [x] Read USB spec - still going, its long - [ ] USB abstract class - [ ] OHCI driver - [ ] UHCI driver From efdaf25385928e590fefb365336f1ccba869362f Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 19 Mar 2018 10:24:10 -0500 Subject: [PATCH 124/171] basic structure for usb device constructor --- src/drivers/PCI/USB/USBFunction.cpp | 16 ++++++++++++++++ src/drivers/PCI/USB/USBFunction.h | 21 +++++++++++++++++++++ src/drivers/PCI/USB/makefile | 2 +- 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 src/drivers/PCI/USB/USBFunction.cpp create mode 100644 src/drivers/PCI/USB/USBFunction.h diff --git a/src/drivers/PCI/USB/USBFunction.cpp b/src/drivers/PCI/USB/USBFunction.cpp new file mode 100644 index 000000000..ce3358660 --- /dev/null +++ b/src/drivers/PCI/USB/USBFunction.cpp @@ -0,0 +1,16 @@ +#include "USBFunction.h" + +USBFunction::USBFunction(){ + +} + +USBFunction(USBHub hub){ + //find out about device + //wait 100MS + //enable port + //send reset for > 50MS + //address device + //read max data payload + //read configs + //select config +} \ No newline at end of file diff --git a/src/drivers/PCI/USB/USBFunction.h b/src/drivers/PCI/USB/USBFunction.h new file mode 100644 index 000000000..ec87300a6 --- /dev/null +++ b/src/drivers/PCI/USB/USBFunction.h @@ -0,0 +1,21 @@ +#ifndef USB_Function_H_ +#define USB_FUNCTION_H_ + +#include "drivers/generic/Device.h" + +//TODO: we need a USB base class, to be made as I learn more +class USBFunction :public Device{ + protected: + USBConfiguration** _configs; + size_t _currnetConfig; + uint8_t _address; + //TODO check size + int _maxDataSize; + USBHostController _host; + public: + USBFunction(); + USBFunction(USBHub hub); + +}; + +#endif \ No newline at end of file diff --git a/src/drivers/PCI/USB/makefile b/src/drivers/PCI/USB/makefile index bd4e84a27..b7490c4e2 100644 --- a/src/drivers/PCI/USB/makefile +++ b/src/drivers/PCI/USB/makefile @@ -1,4 +1,4 @@ SUBDIRS = -OBS = USB.o +OBS = USB.o USBFunction.o include ../../../../makefile.inc \ No newline at end of file From edc03a8f1f5a4a97f27073239019611fdb423652 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 20 Mar 2018 16:04:23 -0500 Subject: [PATCH 125/171] start of USB init code also some base USB enum code, probly will change --- src/drivers/PCI/USB/USB.c | 18 +++++------------- src/drivers/PCI/USB/USBConfiguration.cpp | 1 + src/drivers/PCI/USB/USBConfiguration.h | 7 +++++++ src/drivers/PCI/USB/USBFunction.cpp | 2 +- src/drivers/PCI/USB/USBFunction.h | 4 ++++ src/drivers/PCI/USB/USBHub.cpp | 1 + src/drivers/PCI/USB/USBHub.h | 6 ++++++ .../USB/hostController/USBHostController.cpp | 1 + .../PCI/USB/hostController/USBHostController.h | 6 ++++++ src/drivers/PCI/USB/hostController/makefile | 4 ++++ src/drivers/PCI/USB/makefile | 4 ++-- 11 files changed, 38 insertions(+), 16 deletions(-) create mode 100644 src/drivers/PCI/USB/USBConfiguration.cpp create mode 100644 src/drivers/PCI/USB/USBConfiguration.h create mode 100644 src/drivers/PCI/USB/USBHub.cpp create mode 100644 src/drivers/PCI/USB/USBHub.h create mode 100644 src/drivers/PCI/USB/hostController/USBHostController.cpp create mode 100644 src/drivers/PCI/USB/hostController/USBHostController.h create mode 100644 src/drivers/PCI/USB/hostController/makefile diff --git a/src/drivers/PCI/USB/USB.c b/src/drivers/PCI/USB/USB.c index a2670dfce..59b2c17da 100644 --- a/src/drivers/PCI/USB/USB.c +++ b/src/drivers/PCI/USB/USB.c @@ -5,22 +5,14 @@ * Author: garrett */ -#include "drivers/PCI/USB/USB.h" +#include "USB.h" #include "drivers/PCI/PCI.h" +#include "hostController/USBHostController.h" -//TODO better host coontroller marking -uint8_t maxUSBVersion = 0; -//USBController* uSBControllers; +USBHostController* usbControllers[3]; -void USBInit(){//how it works: -//TODO: - //enum USB controllers - //Enum PCI devices - //Enum PCI controllers (recrsive) | - //Build list of controllers |Already done by PCIInit - //check if device is USB controller - //fill USB controller array with controller objects - //set max USB version +void USBInit(){ + memSet(usbControllers, 3*sizeof(USBHostController*), 0); } //todo types diff --git a/src/drivers/PCI/USB/USBConfiguration.cpp b/src/drivers/PCI/USB/USBConfiguration.cpp new file mode 100644 index 000000000..67a188c34 --- /dev/null +++ b/src/drivers/PCI/USB/USBConfiguration.cpp @@ -0,0 +1 @@ +#include "USBConfiguration.h" \ No newline at end of file diff --git a/src/drivers/PCI/USB/USBConfiguration.h b/src/drivers/PCI/USB/USBConfiguration.h new file mode 100644 index 000000000..9d76cc6c3 --- /dev/null +++ b/src/drivers/PCI/USB/USBConfiguration.h @@ -0,0 +1,7 @@ + +#include "Global.h" + +//TODO superclass +class USBConfiguration{ + +}; \ No newline at end of file diff --git a/src/drivers/PCI/USB/USBFunction.cpp b/src/drivers/PCI/USB/USBFunction.cpp index ce3358660..3348cec92 100644 --- a/src/drivers/PCI/USB/USBFunction.cpp +++ b/src/drivers/PCI/USB/USBFunction.cpp @@ -4,7 +4,7 @@ USBFunction::USBFunction(){ } -USBFunction(USBHub hub){ +USBFunction::USBFunction(USBHub hub){ //find out about device //wait 100MS //enable port diff --git a/src/drivers/PCI/USB/USBFunction.h b/src/drivers/PCI/USB/USBFunction.h index ec87300a6..ae92c6223 100644 --- a/src/drivers/PCI/USB/USBFunction.h +++ b/src/drivers/PCI/USB/USBFunction.h @@ -2,6 +2,10 @@ #define USB_FUNCTION_H_ #include "drivers/generic/Device.h" +#include "hostController/USBHostController.h" +#include "USBHub.h" +#include "USBConfiguration.h" + //TODO: we need a USB base class, to be made as I learn more class USBFunction :public Device{ diff --git a/src/drivers/PCI/USB/USBHub.cpp b/src/drivers/PCI/USB/USBHub.cpp new file mode 100644 index 000000000..c11a9aa60 --- /dev/null +++ b/src/drivers/PCI/USB/USBHub.cpp @@ -0,0 +1 @@ +#include "USBHub.h" \ No newline at end of file diff --git a/src/drivers/PCI/USB/USBHub.h b/src/drivers/PCI/USB/USBHub.h new file mode 100644 index 000000000..1cde14afd --- /dev/null +++ b/src/drivers/PCI/USB/USBHub.h @@ -0,0 +1,6 @@ +#include "Global.h" + +//TODO superclass +class USBHub{ + +}; \ No newline at end of file diff --git a/src/drivers/PCI/USB/hostController/USBHostController.cpp b/src/drivers/PCI/USB/hostController/USBHostController.cpp new file mode 100644 index 000000000..3254447d1 --- /dev/null +++ b/src/drivers/PCI/USB/hostController/USBHostController.cpp @@ -0,0 +1 @@ +#include "USBHostController.h" \ No newline at end of file diff --git a/src/drivers/PCI/USB/hostController/USBHostController.h b/src/drivers/PCI/USB/hostController/USBHostController.h new file mode 100644 index 000000000..00e276f97 --- /dev/null +++ b/src/drivers/PCI/USB/hostController/USBHostController.h @@ -0,0 +1,6 @@ +#include "Global.h" + +//TODO superclass +class USBHostController { + +}; \ No newline at end of file diff --git a/src/drivers/PCI/USB/hostController/makefile b/src/drivers/PCI/USB/hostController/makefile new file mode 100644 index 000000000..2e41bdc17 --- /dev/null +++ b/src/drivers/PCI/USB/hostController/makefile @@ -0,0 +1,4 @@ +SUBDIRS = +OBS = USBHostController.o + +include ../../../../../makefile.inc \ No newline at end of file diff --git a/src/drivers/PCI/USB/makefile b/src/drivers/PCI/USB/makefile index b7490c4e2..aa06836d9 100644 --- a/src/drivers/PCI/USB/makefile +++ b/src/drivers/PCI/USB/makefile @@ -1,4 +1,4 @@ -SUBDIRS = -OBS = USB.o USBFunction.o +SUBDIRS = hostController +OBS = USB.o USBFunction.o USBHub.o include ../../../../makefile.inc \ No newline at end of file From ffe478d57e823de5d7e3e7124ba732eda1642929 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 20 Mar 2018 16:16:10 -0500 Subject: [PATCH 126/171] forgot include gaurds... --- src/drivers/PCI/USB/USBConfiguration.h | 6 +++++- src/drivers/PCI/USB/USBHub.h | 8 +++++++- src/drivers/PCI/USB/hostController/USBEHCIController.cpp | 1 + src/drivers/PCI/USB/hostController/USBEHCIController.h | 6 ++++++ src/drivers/PCI/USB/hostController/USBHostController.h | 7 ++++++- src/drivers/PCI/USB/hostController/makefile | 2 +- 6 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 src/drivers/PCI/USB/hostController/USBEHCIController.cpp create mode 100644 src/drivers/PCI/USB/hostController/USBEHCIController.h diff --git a/src/drivers/PCI/USB/USBConfiguration.h b/src/drivers/PCI/USB/USBConfiguration.h index 9d76cc6c3..cfe087fbc 100644 --- a/src/drivers/PCI/USB/USBConfiguration.h +++ b/src/drivers/PCI/USB/USBConfiguration.h @@ -1,7 +1,11 @@ +#ifndef USB_CONFIGUREATION_H_ +#define USB_CONFIGUREATION_H_ #include "Global.h" //TODO superclass class USBConfiguration{ -}; \ No newline at end of file +}; + +#endif \ No newline at end of file diff --git a/src/drivers/PCI/USB/USBHub.h b/src/drivers/PCI/USB/USBHub.h index 1cde14afd..abbaaef14 100644 --- a/src/drivers/PCI/USB/USBHub.h +++ b/src/drivers/PCI/USB/USBHub.h @@ -1,6 +1,12 @@ +#ifndef USB_HUB_H_ +#define USB_HUB_H_ + + #include "Global.h" //TODO superclass class USBHub{ -}; \ No newline at end of file +}; + +#endif \ No newline at end of file diff --git a/src/drivers/PCI/USB/hostController/USBEHCIController.cpp b/src/drivers/PCI/USB/hostController/USBEHCIController.cpp new file mode 100644 index 000000000..5176b8221 --- /dev/null +++ b/src/drivers/PCI/USB/hostController/USBEHCIController.cpp @@ -0,0 +1 @@ +#include "USBEHCIController.h" \ No newline at end of file diff --git a/src/drivers/PCI/USB/hostController/USBEHCIController.h b/src/drivers/PCI/USB/hostController/USBEHCIController.h new file mode 100644 index 000000000..f771ab404 --- /dev/null +++ b/src/drivers/PCI/USB/hostController/USBEHCIController.h @@ -0,0 +1,6 @@ +#ifndef USB_EHCI_CONTROLLER_H_ +#define USB_EHCI_CONTROLLER_H_ + +#include "Global.h" + +#endif \ No newline at end of file diff --git a/src/drivers/PCI/USB/hostController/USBHostController.h b/src/drivers/PCI/USB/hostController/USBHostController.h index 00e276f97..ea0b061c5 100644 --- a/src/drivers/PCI/USB/hostController/USBHostController.h +++ b/src/drivers/PCI/USB/hostController/USBHostController.h @@ -1,6 +1,11 @@ +#ifndef USB_HOST_CONTROLLER_H_ +#define USB_HOST_CONTROLLER_H_ + #include "Global.h" //TODO superclass class USBHostController { -}; \ No newline at end of file +}; + +#endif \ No newline at end of file diff --git a/src/drivers/PCI/USB/hostController/makefile b/src/drivers/PCI/USB/hostController/makefile index 2e41bdc17..6cc43eec1 100644 --- a/src/drivers/PCI/USB/hostController/makefile +++ b/src/drivers/PCI/USB/hostController/makefile @@ -1,4 +1,4 @@ SUBDIRS = -OBS = USBHostController.o +OBS = USBHostController.o USBEHCIController.o include ../../../../../makefile.inc \ No newline at end of file From 6b8796087093ff2f4e2973be5fa1eb918eafc60d Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 20 Mar 2018 16:28:17 -0500 Subject: [PATCH 127/171] start of host controller constructor, more to come later --- src/drivers/PCI/USB/USB.c | 5 ++--- .../PCI/USB/hostController/USBEHCIController.cpp | 4 +++- .../PCI/USB/hostController/USBEHCIController.h | 10 ++++++++++ .../PCI/USB/hostController/USBHostController.h | 13 +++++++++++++ 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/drivers/PCI/USB/USB.c b/src/drivers/PCI/USB/USB.c index 59b2c17da..cc3126015 100644 --- a/src/drivers/PCI/USB/USB.c +++ b/src/drivers/PCI/USB/USB.c @@ -8,6 +8,7 @@ #include "USB.h" #include "drivers/PCI/PCI.h" #include "hostController/USBHostController.h" +#include "hostController/USBEHCIController.h" USBHostController* usbControllers[3]; @@ -29,6 +30,7 @@ void addUSBHostController(int bus, int device, int function){ } case 0x20:{ //EHCI + usbControllers[1] = new USBEHCIController(); break; } case 0x30:{ @@ -47,7 +49,4 @@ void addUSBHostController(int bus, int device, int function){ //error } } - //create correct object - //store in array - //mark as valid host controller } diff --git a/src/drivers/PCI/USB/hostController/USBEHCIController.cpp b/src/drivers/PCI/USB/hostController/USBEHCIController.cpp index 5176b8221..32dd790dc 100644 --- a/src/drivers/PCI/USB/hostController/USBEHCIController.cpp +++ b/src/drivers/PCI/USB/hostController/USBEHCIController.cpp @@ -1 +1,3 @@ -#include "USBEHCIController.h" \ No newline at end of file +#include "USBEHCIController.h" + + diff --git a/src/drivers/PCI/USB/hostController/USBEHCIController.h b/src/drivers/PCI/USB/hostController/USBEHCIController.h index f771ab404..cae06102a 100644 --- a/src/drivers/PCI/USB/hostController/USBEHCIController.h +++ b/src/drivers/PCI/USB/hostController/USBEHCIController.h @@ -2,5 +2,15 @@ #define USB_EHCI_CONTROLLER_H_ #include "Global.h" +#include "USBHostController.h" +class USBEHCIController: public USBHostController{ + public: + USBEHCIController(){ + + } + USBEHCIController(int bus, int device, int function) : USBHostController(bus,device,function){ + + } +}; #endif \ No newline at end of file diff --git a/src/drivers/PCI/USB/hostController/USBHostController.h b/src/drivers/PCI/USB/hostController/USBHostController.h index ea0b061c5..57c8a7268 100644 --- a/src/drivers/PCI/USB/hostController/USBHostController.h +++ b/src/drivers/PCI/USB/hostController/USBHostController.h @@ -5,6 +5,19 @@ //TODO superclass class USBHostController { + private: + uint8_t _bus; + uint8_t _device; + uint8_t _function; + public: + USBHostController(){ + + } + USBHostController(int bus, int device, int function){ + _bus= bus; + _device = device; + _function = function; + } }; From 6fd291b641ee44b7c444feb31005bbed2b3b1467 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Wed, 21 Mar 2018 07:59:01 -0500 Subject: [PATCH 128/171] moved hubs to own folder --- src/drivers/PCI/USB/USBFunction.h | 2 +- src/drivers/PCI/USB/{ => USB_hubs}/USBHub.cpp | 0 src/drivers/PCI/USB/{ => USB_hubs}/USBHub.h | 0 src/drivers/PCI/USB/USB_hubs/makefile | 4 ++++ .../PCI/USB/hostController/USBEHCIController.h | 12 +++++++----- .../PCI/USB/hostController/USBHostController.h | 5 +++-- src/drivers/PCI/USB/makefile | 4 ++-- 7 files changed, 17 insertions(+), 10 deletions(-) rename src/drivers/PCI/USB/{ => USB_hubs}/USBHub.cpp (100%) rename src/drivers/PCI/USB/{ => USB_hubs}/USBHub.h (100%) create mode 100644 src/drivers/PCI/USB/USB_hubs/makefile diff --git a/src/drivers/PCI/USB/USBFunction.h b/src/drivers/PCI/USB/USBFunction.h index ae92c6223..e3c661739 100644 --- a/src/drivers/PCI/USB/USBFunction.h +++ b/src/drivers/PCI/USB/USBFunction.h @@ -3,7 +3,7 @@ #include "drivers/generic/Device.h" #include "hostController/USBHostController.h" -#include "USBHub.h" +#include "USB_hubs/USBHub.h" #include "USBConfiguration.h" diff --git a/src/drivers/PCI/USB/USBHub.cpp b/src/drivers/PCI/USB/USB_hubs/USBHub.cpp similarity index 100% rename from src/drivers/PCI/USB/USBHub.cpp rename to src/drivers/PCI/USB/USB_hubs/USBHub.cpp diff --git a/src/drivers/PCI/USB/USBHub.h b/src/drivers/PCI/USB/USB_hubs/USBHub.h similarity index 100% rename from src/drivers/PCI/USB/USBHub.h rename to src/drivers/PCI/USB/USB_hubs/USBHub.h diff --git a/src/drivers/PCI/USB/USB_hubs/makefile b/src/drivers/PCI/USB/USB_hubs/makefile new file mode 100644 index 000000000..9cb4e93b8 --- /dev/null +++ b/src/drivers/PCI/USB/USB_hubs/makefile @@ -0,0 +1,4 @@ +SUBDIRS = +OBS = USBHub.o + +include ../../../../../makefile.inc \ No newline at end of file diff --git a/src/drivers/PCI/USB/hostController/USBEHCIController.h b/src/drivers/PCI/USB/hostController/USBEHCIController.h index cae06102a..1616f10c6 100644 --- a/src/drivers/PCI/USB/hostController/USBEHCIController.h +++ b/src/drivers/PCI/USB/hostController/USBEHCIController.h @@ -4,13 +4,15 @@ #include "Global.h" #include "USBHostController.h" class USBEHCIController: public USBHostController{ - public: - USBEHCIController(){ + private: + + public: + USBEHCIController(){ - } - USBEHCIController(int bus, int device, int function) : USBHostController(bus,device,function){ + } + USBEHCIController(int bus, int device, int function) : USBHostController(bus,device,function){ - } + } }; #endif \ No newline at end of file diff --git a/src/drivers/PCI/USB/hostController/USBHostController.h b/src/drivers/PCI/USB/hostController/USBHostController.h index 57c8a7268..eb1e7402c 100644 --- a/src/drivers/PCI/USB/hostController/USBHostController.h +++ b/src/drivers/PCI/USB/hostController/USBHostController.h @@ -2,10 +2,11 @@ #define USB_HOST_CONTROLLER_H_ #include "Global.h" +#include "drivers/PCI/PCI_devices/PCIStandardDevice.h" //TODO superclass -class USBHostController { - private: +class USBHostController : public PCIStandardDevice { + protected: uint8_t _bus; uint8_t _device; uint8_t _function; diff --git a/src/drivers/PCI/USB/makefile b/src/drivers/PCI/USB/makefile index aa06836d9..1e5da1809 100644 --- a/src/drivers/PCI/USB/makefile +++ b/src/drivers/PCI/USB/makefile @@ -1,4 +1,4 @@ -SUBDIRS = hostController -OBS = USB.o USBFunction.o USBHub.o +SUBDIRS = hostController USB_hubs +OBS = USB.o USBFunction.o include ../../../../makefile.inc \ No newline at end of file From 2469cb9e7394f391d2224cbcf18b7de244ba8b5c Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Wed, 21 Mar 2018 08:12:28 -0500 Subject: [PATCH 129/171] ehci root hub class start --- src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.cpp | 1 + src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h | 12 ++++++++++++ src/drivers/PCI/USB/USB_hubs/makefile | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.cpp create mode 100644 src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h diff --git a/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.cpp b/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.cpp new file mode 100644 index 000000000..a0187c18b --- /dev/null +++ b/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.cpp @@ -0,0 +1 @@ +#include "USBEHCIRootHub.h" \ No newline at end of file diff --git a/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h b/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h new file mode 100644 index 000000000..8206249b4 --- /dev/null +++ b/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h @@ -0,0 +1,12 @@ +#ifndef USB_EHCI_ROOT_HUB_H_ +#define USB_EHCI_ROOT_HUB_H_ + +#include "Global.h" +#include "USBHub.h" + +class USBEHCIRootHub : public USBHub { + + +}; + +#endif \ No newline at end of file diff --git a/src/drivers/PCI/USB/USB_hubs/makefile b/src/drivers/PCI/USB/USB_hubs/makefile index 9cb4e93b8..dc4d29124 100644 --- a/src/drivers/PCI/USB/USB_hubs/makefile +++ b/src/drivers/PCI/USB/USB_hubs/makefile @@ -1,4 +1,4 @@ SUBDIRS = -OBS = USBHub.o +OBS = USBHub.o USBEHCIRootHub.o include ../../../../../makefile.inc \ No newline at end of file From dfd0e13f9b7cd1b9509bc4299e4ede8b69a02dab Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Wed, 21 Mar 2018 08:50:51 -0500 Subject: [PATCH 130/171] start of EHCI root hub --- src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h | 29 +++++++++++++++++++ src/drivers/PCI/USB/USB_hubs/USBHub.h | 12 +++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h b/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h index 8206249b4..37c8a9073 100644 --- a/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h +++ b/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h @@ -3,10 +3,39 @@ #include "Global.h" #include "USBHub.h" +#include "drivers/PCI/USB/hostController/USBEHCIController.h" +struct EHCIPortStatCont{ + uint8_t conStat:1; + uint8_t conStatChange:1; + uint8_t portEnable:1; + uint8_t portEnableChange:1; + uint8_t overCurrent:1; + uint8_t overCurrentChage:1; + uint8_t forceResume:1; + uint8_t suspend:1; + uint8_t reset:1; + uint8_t reserved1:1; + uint8_t lineStat:2; + uint8_t power:1; + uint8_t owner:1; + uint8_t indicatorCont:2; + uint8_t testCont:4; + uint8_t wakeOnConnect:1; + uint8_t wakeOnDisconnect:1; + uint8_t wakeOnOvercurrent:1; + uint8_t reserved2; +}; class USBEHCIRootHub : public USBHub { + private: + EHCIPortStatCont* _ports; + public: + USBEHCIRootHub():USBHub(){ + } + USBEHCIRootHub(USBEHCIController* host):USBHub(host){ + } }; #endif \ No newline at end of file diff --git a/src/drivers/PCI/USB/USB_hubs/USBHub.h b/src/drivers/PCI/USB/USB_hubs/USBHub.h index abbaaef14..777f84e31 100644 --- a/src/drivers/PCI/USB/USB_hubs/USBHub.h +++ b/src/drivers/PCI/USB/USB_hubs/USBHub.h @@ -3,9 +3,19 @@ #include "Global.h" - +#include "drivers/PCI/USB/hostController/USBHostController.h" //TODO superclass class USBHub{ + protected: + //TODO size + int _portCount; + USBHostController* _host; + USBHub(){ + + } + USBHub(USBHostController* host):_host(host){ + //TODO port count + } }; From 86c2f342aad59b8f8bd556515e53bf79b7d5b1a7 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Wed, 21 Mar 2018 17:12:18 -0500 Subject: [PATCH 131/171] structs for reading EHCI fields --- src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h | 4 +- src/drivers/PCI/USB/USB_hubs/USBHub.h | 2 + .../USB/hostController/USBEHCIController.h | 52 ++++++++++++++++++- .../USB/hostController/USBHostController.h | 8 +-- 4 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h b/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h index 37c8a9073..e928ebdc0 100644 --- a/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h +++ b/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h @@ -33,7 +33,9 @@ class USBEHCIRootHub : public USBHub { USBEHCIRootHub():USBHub(){ } - USBEHCIRootHub(USBEHCIController* host):USBHub(host){ + USBEHCIRootHub(USBEHCIController* host):USBHub(host, true){ + _ports = (EHCIPortStatCont*)(_host->BAR0() + 0); //TODO add properly, CAPLENGTH (from host) + 44 + //TODO get port count from _host } }; diff --git a/src/drivers/PCI/USB/USB_hubs/USBHub.h b/src/drivers/PCI/USB/USB_hubs/USBHub.h index 777f84e31..a0491c4c9 100644 --- a/src/drivers/PCI/USB/USB_hubs/USBHub.h +++ b/src/drivers/PCI/USB/USB_hubs/USBHub.h @@ -16,6 +16,8 @@ class USBHub{ USBHub(USBHostController* host):_host(host){ //TODO port count } + USBHub(USBHostController* host, bool rootHubOnly):_host(host){ + } }; diff --git a/src/drivers/PCI/USB/hostController/USBEHCIController.h b/src/drivers/PCI/USB/hostController/USBEHCIController.h index 1616f10c6..7c191ee63 100644 --- a/src/drivers/PCI/USB/hostController/USBEHCIController.h +++ b/src/drivers/PCI/USB/hostController/USBEHCIController.h @@ -3,15 +3,63 @@ #include "Global.h" #include "USBHostController.h" + +struct HWVersion{ + uint8_t major; + uint8_t minor; +}; +struct HWStrucParams{ + uint8_t numOfPorts:4; + uint8_t ppc:1; + uint8_t reserved1:2; + uint8_t portRouteRules:1; + uint8_t numOfPortsPerCompanionController:4; + uint8_t numOfCompanionControllers:4; + uint8_t portIndicator:1; + uint8_t reserved2:3; + uint8_t debugPortNum:4; + uint8_t reserved3; +}; + +struct HWCapParams{ + uint8_t addrCap:1; + uint8_t progFrameListFlag:1; + uint8_t asyncSchedParkCap:1; + uint8_t reserved1:1; + uint8_t isochornousSchedThersh:4; + uint8_t ehciExtendCapsPtr; + uint16_t reserved2; +}; + +struct CompaninoPortRoute{ + //TODO.... 15 nibble array +}; + +struct CapReg{ + uint8_t capLeng; + uint8_t reserved; + HWVersion hwVersion; + HWStrucParams structParams; + HWCapParams capParams; + CompaninoPortRoute portRoute; +}; + +struct operReg{ +//TODO +}; + + class USBEHCIController: public USBHostController{ private: - + CapReg* _caps; + operReg* _oper; public: USBEHCIController(){ } USBEHCIController(int bus, int device, int function) : USBHostController(bus,device,function){ - + _caps = (CapReg*)BAR0(); + _oper = (operReg*)((uint32_t) _caps + _caps->capLeng); } }; diff --git a/src/drivers/PCI/USB/hostController/USBHostController.h b/src/drivers/PCI/USB/hostController/USBHostController.h index eb1e7402c..d4ba9d6b3 100644 --- a/src/drivers/PCI/USB/hostController/USBHostController.h +++ b/src/drivers/PCI/USB/hostController/USBHostController.h @@ -7,17 +7,11 @@ //TODO superclass class USBHostController : public PCIStandardDevice { protected: - uint8_t _bus; - uint8_t _device; - uint8_t _function; public: USBHostController(){ } - USBHostController(int bus, int device, int function){ - _bus= bus; - _device = device; - _function = function; + USBHostController(int bus, int device, int function):PCIStandardDevice(bus, device,function, true){ } }; From d86fa74564d9b17bced3472b3aab0d8198588e6a Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Thu, 22 Mar 2018 16:08:12 -0500 Subject: [PATCH 132/171] basic structure for the op registers --- .../PCI/USB/hostController/USBEHCIController.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/drivers/PCI/USB/hostController/USBEHCIController.h b/src/drivers/PCI/USB/hostController/USBEHCIController.h index 7c191ee63..b2a26955c 100644 --- a/src/drivers/PCI/USB/hostController/USBEHCIController.h +++ b/src/drivers/PCI/USB/hostController/USBEHCIController.h @@ -45,7 +45,16 @@ struct CapReg{ }; struct operReg{ -//TODO + USBCmd cmd; + USBStat stat; + IntEnable intEnable; + FrameIndex frameIndex; + ControlDataSegment CDSeg; + FrameListBase frameListBase; + AsyncListAddr asyncListAddr; + uint8_t reserved[35]; + ConfigFlags flags; + PortSC ports; }; From 6387f5e414642555e976787ba9fba2b389c4439f Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Thu, 22 Mar 2018 16:16:53 -0500 Subject: [PATCH 133/171] EHCI USB command register struct --- .../PCI/USB/hostController/USBEHCIController.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/drivers/PCI/USB/hostController/USBEHCIController.h b/src/drivers/PCI/USB/hostController/USBEHCIController.h index b2a26955c..27916e5be 100644 --- a/src/drivers/PCI/USB/hostController/USBEHCIController.h +++ b/src/drivers/PCI/USB/hostController/USBEHCIController.h @@ -44,6 +44,22 @@ struct CapReg{ CompaninoPortRoute portRoute; }; +struct USBCmd { + uint8_t runStop:1; + uint8_t reset:1; + uint8_t frameSizeList:2; + uint8_t periodSchedEnable:1; + uint8_t asyncSchedEnable:1; + uint8_t intOnAsyncDoorbell:1; + uint8_t lightReset:1; + uint8_t asyncSchedParkModeCount:2; + uint8_t reserved1:1; + uint8_t asyncSchedParkModeEnable:1; + uint8_t reserved2:4; + uint8_t interruptThreshCont; + uint8_t reserved3; +}; + struct operReg{ USBCmd cmd; USBStat stat; From 1fd992bdbf8dd690ae298cc05f281dbd0171de2b Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Thu, 22 Mar 2018 16:27:39 -0500 Subject: [PATCH 134/171] EHCI status register struct --- .../PCI/USB/hostController/USBEHCIController.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/drivers/PCI/USB/hostController/USBEHCIController.h b/src/drivers/PCI/USB/hostController/USBEHCIController.h index 27916e5be..ad6ae4d65 100644 --- a/src/drivers/PCI/USB/hostController/USBEHCIController.h +++ b/src/drivers/PCI/USB/hostController/USBEHCIController.h @@ -60,6 +60,21 @@ struct USBCmd { uint8_t reserved3; }; +struct USBstat { + uint8_t rxInt:1; + uint8_t errInt:1; + uint8_t portChange:1; + uint8_t frameListRollover:1; + uint8_t systemError:1; + uint8_t asyncDoorbell:1; + uint8_t reserved1:6; + uint8_t hcHalted:1; + uint8_t reclamation:1; + uint8_t periodiCSchedStat:1; + uint8_t asyncSchedStat:1; + uint16_t reserved2; +}; + struct operReg{ USBCmd cmd; USBStat stat; From 7840627d08731f039b79d1bebb6d10f3db4e5422 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sat, 24 Mar 2018 13:43:53 -0500 Subject: [PATCH 135/171] finished structs for the host controller --- src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h | 23 +------- .../USB/hostController/USBEHCIController.h | 58 ++++++++++++++++++- 2 files changed, 57 insertions(+), 24 deletions(-) diff --git a/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h b/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h index e928ebdc0..921dd35d2 100644 --- a/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h +++ b/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h @@ -4,27 +4,8 @@ #include "Global.h" #include "USBHub.h" #include "drivers/PCI/USB/hostController/USBEHCIController.h" -struct EHCIPortStatCont{ - uint8_t conStat:1; - uint8_t conStatChange:1; - uint8_t portEnable:1; - uint8_t portEnableChange:1; - uint8_t overCurrent:1; - uint8_t overCurrentChage:1; - uint8_t forceResume:1; - uint8_t suspend:1; - uint8_t reset:1; - uint8_t reserved1:1; - uint8_t lineStat:2; - uint8_t power:1; - uint8_t owner:1; - uint8_t indicatorCont:2; - uint8_t testCont:4; - uint8_t wakeOnConnect:1; - uint8_t wakeOnDisconnect:1; - uint8_t wakeOnOvercurrent:1; - uint8_t reserved2; -}; + + class USBEHCIRootHub : public USBHub { private: diff --git a/src/drivers/PCI/USB/hostController/USBEHCIController.h b/src/drivers/PCI/USB/hostController/USBEHCIController.h index ad6ae4d65..9f1c6c231 100644 --- a/src/drivers/PCI/USB/hostController/USBEHCIController.h +++ b/src/drivers/PCI/USB/hostController/USBEHCIController.h @@ -60,7 +60,7 @@ struct USBCmd { uint8_t reserved3; }; -struct USBstat { +struct USBStat { uint8_t rxInt:1; uint8_t errInt:1; uint8_t portChange:1; @@ -74,18 +74,70 @@ struct USBstat { uint8_t asyncSchedStat:1; uint16_t reserved2; }; +struct IntEnable{ + uint8_t usbIntEnable:1; + uint8_t ErrIntEnable:1; + uint8_t portChangeIntEnable:1; + uint8_t frameListRollIntEnable:1; + uint8_t hostSystemIntEnable:1; + uint8_t intOnAsyncAdvanceEnable:1; + uint8_t reserved1:2; + uint16_t reserved2; + uint8_t reserved3; +}; +struct FrameIndex{ + uint16_t frameIndex:13; + uint8_t reserved1:3; + uint16_t reserved2; +}; +struct FrameListBase{ + uint16_t reserved:12; + uint32_t baseAddr:20; +}; + +struct AsyncListAddr{ + uint8_t reserved:5; + uint32_t linkPointerLow:28; +}; + +struct ConfigFlags{ + uint8_t configFlag:1; + uint32_t reserved:31; +}; + +struct EHCIPortStatCont{ + uint8_t conStat:1; + uint8_t conStatChange:1; + uint8_t portEnable:1; + uint8_t portEnableChange:1; + uint8_t overCurrent:1; + uint8_t overCurrentChage:1; + uint8_t forceResume:1; + uint8_t suspend:1; + uint8_t reset:1; + uint8_t reserved1:1; + uint8_t lineStat:2; + uint8_t power:1; + uint8_t owner:1; + uint8_t indicatorCont:2; + uint8_t testCont:4; + uint8_t wakeOnConnect:1; + uint8_t wakeOnDisconnect:1; + uint8_t wakeOnOvercurrent:1; + uint8_t reserved2; +}; struct operReg{ USBCmd cmd; USBStat stat; IntEnable intEnable; FrameIndex frameIndex; - ControlDataSegment CDSeg; + uint32_t CDSeg; FrameListBase frameListBase; AsyncListAddr asyncListAddr; uint8_t reserved[35]; ConfigFlags flags; - PortSC ports; + EHCIPortStatCont ports; }; From d3b0e9bf7ff993a873eb766445004fc9ccd22486 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sun, 25 Mar 2018 10:49:57 -0500 Subject: [PATCH 136/171] init EHCI controller --- .../USB/hostController/USBEHCIController.h | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/drivers/PCI/USB/hostController/USBEHCIController.h b/src/drivers/PCI/USB/hostController/USBEHCIController.h index 9f1c6c231..f07dc362b 100644 --- a/src/drivers/PCI/USB/hostController/USBEHCIController.h +++ b/src/drivers/PCI/USB/hostController/USBEHCIController.h @@ -140,11 +140,19 @@ struct operReg{ EHCIPortStatCont ports; }; +struct FrameListLinkPointer{ + uint8_t t :1; + uint8_t type:2; + uint8_t zero:2; + uint32_t linkPointer: 28; +} ; class USBEHCIController: public USBHostController{ private: CapReg* _caps; operReg* _oper; + FrameListLinkPointer* _frameList; + size_t _frameListSize; public: USBEHCIController(){ @@ -152,6 +160,35 @@ class USBEHCIController: public USBHostController{ USBEHCIController(int bus, int device, int function) : USBHostController(bus,device,function){ _caps = (CapReg*)BAR0(); _oper = (operReg*)((uint32_t) _caps + _caps->capLeng); + + switch (_oper->cmd.frameSizeList){ + case 0b00:{ + _frameListSize =1024; + break; + } + case 0b01:{ + _frameListSize =512; + break; + } + case 0b10:{ + _frameListSize =256; + break; + } + default:{ + //error + } + } + + _frameList = new FrameListLinkPointer[_frameListSize]; + for (size_t i =0; i < _frameListSize; i++){ + _frameList[i].t =1; + } + _oper->intEnable.ErrIntEnable = 1; + _oper->intEnable.portChangeIntEnable =1; + _oper->intEnable.hostSystemIntEnable =1; + _oper->frameListBase.baseAddr = (uint32_t)_frameList >> 12; + _oper->cmd.runStop =1; + _oper->flags.configFlag =1; } }; From 9daf13eaa5f29c44ac8353dbd1a8d6b0fd9e03c0 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 26 Mar 2018 08:26:40 -0500 Subject: [PATCH 137/171] packed structs fixes issue #58 --- .../USB/hostController/USBEHCIController.h | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/drivers/PCI/USB/hostController/USBEHCIController.h b/src/drivers/PCI/USB/hostController/USBEHCIController.h index f07dc362b..1ca52c4dc 100644 --- a/src/drivers/PCI/USB/hostController/USBEHCIController.h +++ b/src/drivers/PCI/USB/hostController/USBEHCIController.h @@ -7,7 +7,7 @@ struct HWVersion{ uint8_t major; uint8_t minor; -}; +}__attribute__((__packed__)); struct HWStrucParams{ uint8_t numOfPorts:4; uint8_t ppc:1; @@ -19,7 +19,7 @@ struct HWStrucParams{ uint8_t reserved2:3; uint8_t debugPortNum:4; uint8_t reserved3; -}; +}__attribute__((__packed__)); struct HWCapParams{ uint8_t addrCap:1; @@ -29,11 +29,11 @@ struct HWCapParams{ uint8_t isochornousSchedThersh:4; uint8_t ehciExtendCapsPtr; uint16_t reserved2; -}; +}__attribute__((__packed__)); struct CompaninoPortRoute{ //TODO.... 15 nibble array -}; +}__attribute__((__packed__)); struct CapReg{ uint8_t capLeng; @@ -42,7 +42,7 @@ struct CapReg{ HWStrucParams structParams; HWCapParams capParams; CompaninoPortRoute portRoute; -}; +}__attribute__((__packed__)); struct USBCmd { uint8_t runStop:1; @@ -58,7 +58,7 @@ struct USBCmd { uint8_t reserved2:4; uint8_t interruptThreshCont; uint8_t reserved3; -}; +}__attribute__((__packed__)); struct USBStat { uint8_t rxInt:1; @@ -73,7 +73,7 @@ struct USBStat { uint8_t periodiCSchedStat:1; uint8_t asyncSchedStat:1; uint16_t reserved2; -}; +}__attribute__((__packed__)); struct IntEnable{ uint8_t usbIntEnable:1; uint8_t ErrIntEnable:1; @@ -84,26 +84,26 @@ struct IntEnable{ uint8_t reserved1:2; uint16_t reserved2; uint8_t reserved3; -}; +}__attribute__((__packed__)); struct FrameIndex{ uint16_t frameIndex:13; uint8_t reserved1:3; uint16_t reserved2; -}; +}__attribute__((__packed__)); struct FrameListBase{ uint16_t reserved:12; uint32_t baseAddr:20; -}; +}__attribute__((__packed__)); struct AsyncListAddr{ uint8_t reserved:5; uint32_t linkPointerLow:28; -}; +}__attribute__((__packed__)); struct ConfigFlags{ uint8_t configFlag:1; uint32_t reserved:31; -}; +}__attribute__((__packed__)); struct EHCIPortStatCont{ uint8_t conStat:1; @@ -125,7 +125,7 @@ struct EHCIPortStatCont{ uint8_t wakeOnDisconnect:1; uint8_t wakeOnOvercurrent:1; uint8_t reserved2; -}; +}__attribute__((__packed__)); struct operReg{ USBCmd cmd; @@ -138,14 +138,14 @@ struct operReg{ uint8_t reserved[35]; ConfigFlags flags; EHCIPortStatCont ports; -}; +}__attribute__((__packed__)); struct FrameListLinkPointer{ uint8_t t :1; uint8_t type:2; uint8_t zero:2; uint32_t linkPointer: 28; -} ; +}__attribute__((__packed__)); class USBEHCIController: public USBHostController{ private: From c170f9b270212c660a59165fa5ba49983a93d9a9 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 26 Mar 2018 12:46:57 -0500 Subject: [PATCH 138/171] init EHCI root hub also scans for devices on the hub... works hopefully --- makefile.inc | 2 +- src/drivers/PCI/USB/USB.c | 6 ++++++ src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h | 11 ++++++++--- src/drivers/PCI/USB/USB_hubs/USBHub.h | 11 +++++++++-- .../PCI/USB/hostController/USBEHCIController.h | 3 +++ src/drivers/PCI/USB/hostController/makefile | 1 + 6 files changed, 28 insertions(+), 6 deletions(-) diff --git a/makefile.inc b/makefile.inc index 97982718b..fac46f2a6 100644 --- a/makefile.inc +++ b/makefile.inc @@ -7,7 +7,7 @@ OS_CPP=/home/garrett/workspace/exos BUILD_TO=/mnt/boot/kernel.bin #OS_CPP = /Users/garrettbattaglia/Documents/dev/Exos/exos #BUILD_TO = $(OS_CPP)/kernel.bin -CFLAGS = $(CFLAGS_CUSTOM) -c -ffreestanding -O2 -Wall -Wextra -fno-rtti -fno-exceptions -g -std=gnu++14 -I$(OS_CPP)/src +CFLAGS = $(CFLAGS_CUSTOM) -c -ffreestanding -O2 -Wno-packed-bitfield-compat -Wall -Wextra -fno-rtti -fno-exceptions -g -std=gnu++14 -I$(OS_CPP)/src OBJ_DIR = $(OS_CPP)/build LINK_FLAGS = -ffreestanding -O2 -fno-rtti -fno-exceptions -nostartfiles -nostdlib diff --git a/src/drivers/PCI/USB/USB.c b/src/drivers/PCI/USB/USB.c index cc3126015..2cb8f8d05 100644 --- a/src/drivers/PCI/USB/USB.c +++ b/src/drivers/PCI/USB/USB.c @@ -9,8 +9,12 @@ #include "drivers/PCI/PCI.h" #include "hostController/USBHostController.h" #include "hostController/USBEHCIController.h" +#include "USB_hubs/USBHub.h" +#include "USB_hubs/USBEHCIRootHub.h" + USBHostController* usbControllers[3]; +USBHub* testRoot; void USBInit(){ memSet(usbControllers, 3*sizeof(USBHostController*), 0); @@ -31,6 +35,8 @@ void addUSBHostController(int bus, int device, int function){ case 0x20:{ //EHCI usbControllers[1] = new USBEHCIController(); + testRoot=new USBEHCIRootHub((USBEHCIController*)usbControllers[1]); + testRoot->findDevices(); break; } case 0x30:{ diff --git a/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h b/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h index 921dd35d2..19446e4b6 100644 --- a/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h +++ b/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h @@ -4,7 +4,7 @@ #include "Global.h" #include "USBHub.h" #include "drivers/PCI/USB/hostController/USBEHCIController.h" - +#include "utils/printf/Printf.h" class USBEHCIRootHub : public USBHub { @@ -15,10 +15,15 @@ class USBEHCIRootHub : public USBHub { } USBEHCIRootHub(USBEHCIController* host):USBHub(host, true){ - _ports = (EHCIPortStatCont*)(_host->BAR0() + 0); //TODO add properly, CAPLENGTH (from host) + 44 - //TODO get port count from _host + _ports = (EHCIPortStatCont*)(((uint32_t)(((USBEHCIController*)_host)->caps()->capLeng ))+ 0x44); //TODO add properly, CAPLENGTH (from host) + 44 + _portCount = ((USBEHCIController*)_host)->caps()->structParams.numOfPorts; } + virtual void findDevices(){ + for (int i = 0; i < _portCount; i++){ + printf("found a device\n"); + } + } }; #endif \ No newline at end of file diff --git a/src/drivers/PCI/USB/USB_hubs/USBHub.h b/src/drivers/PCI/USB/USB_hubs/USBHub.h index a0491c4c9..4d077aa18 100644 --- a/src/drivers/PCI/USB/USB_hubs/USBHub.h +++ b/src/drivers/PCI/USB/USB_hubs/USBHub.h @@ -4,19 +4,26 @@ #include "Global.h" #include "drivers/PCI/USB/hostController/USBHostController.h" +#include "drivers/generic/SpecialDevice.h" //TODO superclass -class USBHub{ +class USBHub :public SpecialDevice{ protected: //TODO size int _portCount; USBHostController* _host; + public: USBHub(){ } USBHub(USBHostController* host):_host(host){ //TODO port count } - USBHub(USBHostController* host, bool rootHubOnly):_host(host){ + USBHub(USBHostController* host, bool rootHubOnly):_host(host){ + (void) rootHubOnly; + + } + virtual void findDevices(){ + } }; diff --git a/src/drivers/PCI/USB/hostController/USBEHCIController.h b/src/drivers/PCI/USB/hostController/USBEHCIController.h index 1ca52c4dc..59c03b85b 100644 --- a/src/drivers/PCI/USB/hostController/USBEHCIController.h +++ b/src/drivers/PCI/USB/hostController/USBEHCIController.h @@ -190,6 +190,9 @@ class USBEHCIController: public USBHostController{ _oper->cmd.runStop =1; _oper->flags.configFlag =1; } + auto caps(){ + return _caps; + } }; #endif \ No newline at end of file diff --git a/src/drivers/PCI/USB/hostController/makefile b/src/drivers/PCI/USB/hostController/makefile index 6cc43eec1..2ddd738c6 100644 --- a/src/drivers/PCI/USB/hostController/makefile +++ b/src/drivers/PCI/USB/hostController/makefile @@ -1,4 +1,5 @@ SUBDIRS = OBS = USBHostController.o USBEHCIController.o + include ../../../../../makefile.inc \ No newline at end of file From e2c952c49f3d67208bb1c05c85b247df958dad5a Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 26 Mar 2018 12:55:40 -0500 Subject: [PATCH 139/171] debugging prints --- src/drivers/PCI/USB/USB.c | 2 ++ src/drivers/PCI/USB/USB_hubs/USBHub.h | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/drivers/PCI/USB/USB.c b/src/drivers/PCI/USB/USB.c index 2cb8f8d05..028314205 100644 --- a/src/drivers/PCI/USB/USB.c +++ b/src/drivers/PCI/USB/USB.c @@ -23,6 +23,7 @@ void USBInit(){ //todo types void addUSBHostController(int bus, int device, int function){ uint8_t progIF = getPCIProgIF(bus, device, function); + printf("progIF: %d", progIF); switch (progIF){ case 0x00:{ //UHCI @@ -34,6 +35,7 @@ void addUSBHostController(int bus, int device, int function){ } case 0x20:{ //EHCI + printf("making a host controller"); usbControllers[1] = new USBEHCIController(); testRoot=new USBEHCIRootHub((USBEHCIController*)usbControllers[1]); testRoot->findDevices(); diff --git a/src/drivers/PCI/USB/USB_hubs/USBHub.h b/src/drivers/PCI/USB/USB_hubs/USBHub.h index 4d077aa18..5c2b15ca5 100644 --- a/src/drivers/PCI/USB/USB_hubs/USBHub.h +++ b/src/drivers/PCI/USB/USB_hubs/USBHub.h @@ -5,6 +5,8 @@ #include "Global.h" #include "drivers/PCI/USB/hostController/USBHostController.h" #include "drivers/generic/SpecialDevice.h" +#include "utils/printf/Printf.h" + //TODO superclass class USBHub :public SpecialDevice{ protected: @@ -23,7 +25,7 @@ class USBHub :public SpecialDevice{ } virtual void findDevices(){ - + printf("Virtual funcs arent working"); } }; From abde5852d58dfd32e9fa4d0a9605ee18fa072d5d Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Thu, 29 Mar 2018 16:48:46 -0500 Subject: [PATCH 140/171] page in 1 page for each BAR --- src/drivers/PCI/PCI.c | 9 +++++---- src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp | 11 +++++++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/drivers/PCI/PCI.c b/src/drivers/PCI/PCI.c index 56352cc6d..5961492a2 100644 --- a/src/drivers/PCI/PCI.c +++ b/src/drivers/PCI/PCI.c @@ -13,10 +13,12 @@ uint8_t MAX_PCI_FUNCTIONS = 7; uint8_t MAX_PCI_DEVICES_PER_BUS = 32; uint8_t getPCIProgIF(uint8_t bus, uint8_t device, uint8_t function){ - return (readPCIConfigWord(bus, device, function, 0x08) >> 8) & 0xFFFF; + auto progIF = readPCIConfigWord(bus, device, function, 0x08); + printf("reading progIF and got: %d", progIF); + return (progIF>> 8) & 0xFFFF; } -uint32_t readPCIConfigWord/*New*/(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset) +uint32_t readPCIConfigWord(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset) { ConfigAddress addr; addr.enable = 1; @@ -34,7 +36,6 @@ uint32_t readPCIConfigWord/*New*/(uint8_t bus, uint8_t device, uint8_t function, void enumPCIDevices() { - //printf("old: 0x%x, new: 0x%x", readPCIConfigWord(0,2,4,8), readPCIConfigWordNew(0,2,4,8) ); for (uint8_t func = 0; func <= MAX_PCI_FUNCTIONS; func++) { if (getPCIVender(0, 0, func) != 0xFFFF) @@ -90,8 +91,8 @@ void checkPCIFunction(uint8_t bus, uint8_t device, uint8_t func) if (subClass == 0x03){ addUSBHostController(bus, device, func); printf(" This is a USB host controller\n"); + break; } - break; } default: { diff --git a/src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp b/src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp index 71a0708ae..ef1bda9c3 100644 --- a/src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp +++ b/src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp @@ -7,14 +7,21 @@ #include "drivers/PCI/PCI_devices/PCIStandardDevice.h" #include "drivers/PCI/PCI.h" - +#include "Kernel.h" PCIStandardDevice::PCIStandardDevice( ) : PCIDevice( ) { // TODO Auto-generated constructor stub } PCIStandardDevice::PCIStandardDevice(uint8_t bus, uint8_t device, uint8_t function, bool page):PCIDevice(bus, device, function, page) { - + if (page){ + pageTable.page(BAR0(), BAR0(),1) ; + pageTable.page(BAR1(), BAR1(),1) ; + pageTable.page(BAR2(), BAR2(),1) ; + pageTable.page(BAR3(), BAR3(),1) ; + pageTable.page(BAR4(), BAR4(),1) ; + pageTable.page(BAR5(), BAR5(),1) ; + } } PCIStandardDevice::~PCIStandardDevice( ) { // TODO Auto-generated destructor stub From 64991d00cac64b9683b06fc293e0ea47588625cf Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Fri, 30 Mar 2018 12:29:17 -0500 Subject: [PATCH 141/171] debugging issue #60/#61 --- makefile | 3 ++- src/Global.h | 2 +- src/drivers/PCI/PCI.c | 1 - src/drivers/PCI/PCI_devices/PCIDevice.cpp | 7 ------- src/drivers/PCI/PCI_devices/PCIDevice.h | 4 ++-- src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp | 4 ---- src/drivers/PCI/PCI_devices/PCIStandardDevice.h | 5 +++-- src/drivers/PCI/USB/{USB.c => USB.cpp} | 8 ++++---- src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h | 7 ++++--- src/drivers/PCI/USB/hostController/USBEHCIController.h | 4 +++- src/drivers/PCI/USB/hostController/USBHostController.h | 3 ++- src/interrupts/InterruptHandler.cpp | 4 +++- src/memory/alloc/New.cpp | 7 ++++--- 13 files changed, 28 insertions(+), 31 deletions(-) rename src/drivers/PCI/USB/{USB.c => USB.cpp} (81%) diff --git a/makefile b/makefile index 4a62b3e18..8a994b0b1 100644 --- a/makefile +++ b/makefile @@ -10,4 +10,5 @@ kernel.bin: $(SUBDIRS) @sync clean: - rm $(OBJ_DIR)/*.o \ No newline at end of file + rm $(OBJ_DIR)/*.o + rm $(BUILD_TO) \ No newline at end of file diff --git a/src/Global.h b/src/Global.h index 73462221c..02ac4d4b2 100755 --- a/src/Global.h +++ b/src/Global.h @@ -24,7 +24,7 @@ #include "utils/string/StrLen.h" //bochs breakpoing ASM -#define BREAKPOINT asm("xchgw %%bx, %%bx" : : : "%bx"); +#define BREAKPOINT printf("hitbreakpoint");asm("hlt");asm("hlt"); //helpful constant #define FOUR_KB 4096 diff --git a/src/drivers/PCI/PCI.c b/src/drivers/PCI/PCI.c index 5961492a2..e7bb8e0c9 100644 --- a/src/drivers/PCI/PCI.c +++ b/src/drivers/PCI/PCI.c @@ -14,7 +14,6 @@ uint8_t MAX_PCI_DEVICES_PER_BUS = 32; uint8_t getPCIProgIF(uint8_t bus, uint8_t device, uint8_t function){ auto progIF = readPCIConfigWord(bus, device, function, 0x08); - printf("reading progIF and got: %d", progIF); return (progIF>> 8) & 0xFFFF; } diff --git a/src/drivers/PCI/PCI_devices/PCIDevice.cpp b/src/drivers/PCI/PCI_devices/PCIDevice.cpp index 2a5f819f5..bd32df7e1 100644 --- a/src/drivers/PCI/PCI_devices/PCIDevice.cpp +++ b/src/drivers/PCI/PCI_devices/PCIDevice.cpp @@ -8,13 +8,6 @@ #include "drivers/PCI/PCI_devices/PCIDevice.h" #include "drivers/PCI/PCI.h" -PCIDevice::PCIDevice() -{ - // TODO Auto-generated constructor stub -} -PCIDevice::~PCIDevice(){ - -} PCIDevice::PCIDevice(uint8_t bus, uint8_t device, uint8_t function, bool page) { _bus = bus; _device = device; diff --git a/src/drivers/PCI/PCI_devices/PCIDevice.h b/src/drivers/PCI/PCI_devices/PCIDevice.h index 92d4bce59..e688a995c 100644 --- a/src/drivers/PCI/PCI_devices/PCIDevice.h +++ b/src/drivers/PCI/PCI_devices/PCIDevice.h @@ -18,9 +18,9 @@ class PCIDevice: public SpecialDevice { uint8_t _function; bool _page; public: - PCIDevice( ); + PCIDevice( ){} PCIDevice(uint8_t bus, uint8_t device, uint8_t function, bool page); - virtual ~PCIDevice( )=0; + virtual ~PCIDevice( ){} uint16_t deviceID(); uint16_t venderID(); uint16_t status(); diff --git a/src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp b/src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp index ef1bda9c3..089b85787 100644 --- a/src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp +++ b/src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp @@ -8,11 +8,7 @@ #include "drivers/PCI/PCI_devices/PCIStandardDevice.h" #include "drivers/PCI/PCI.h" #include "Kernel.h" -PCIStandardDevice::PCIStandardDevice( ) : - PCIDevice( ) { - // TODO Auto-generated constructor stub -} PCIStandardDevice::PCIStandardDevice(uint8_t bus, uint8_t device, uint8_t function, bool page):PCIDevice(bus, device, function, page) { if (page){ pageTable.page(BAR0(), BAR0(),1) ; diff --git a/src/drivers/PCI/PCI_devices/PCIStandardDevice.h b/src/drivers/PCI/PCI_devices/PCIStandardDevice.h index 13339ec39..702cd03da 100644 --- a/src/drivers/PCI/PCI_devices/PCIStandardDevice.h +++ b/src/drivers/PCI/PCI_devices/PCIStandardDevice.h @@ -16,9 +16,10 @@ class PCIStandardDevice: public PCIDevice { public: - PCIStandardDevice( ); + PCIStandardDevice( ):PCIDevice( ) { + } PCIStandardDevice(uint8_t bus, uint8_t device, uint8_t function, bool page); - virtual ~PCIStandardDevice( ); + virtual ~PCIStandardDevice( ){} uint32_t BAR0(); uint32_t BAR1(); uint32_t BAR2(); diff --git a/src/drivers/PCI/USB/USB.c b/src/drivers/PCI/USB/USB.cpp similarity index 81% rename from src/drivers/PCI/USB/USB.c rename to src/drivers/PCI/USB/USB.cpp index 028314205..d53a87116 100644 --- a/src/drivers/PCI/USB/USB.c +++ b/src/drivers/PCI/USB/USB.cpp @@ -23,7 +23,6 @@ void USBInit(){ //todo types void addUSBHostController(int bus, int device, int function){ uint8_t progIF = getPCIProgIF(bus, device, function); - printf("progIF: %d", progIF); switch (progIF){ case 0x00:{ //UHCI @@ -35,10 +34,11 @@ void addUSBHostController(int bus, int device, int function){ } case 0x20:{ //EHCI - printf("making a host controller"); + printf(" Is an EHCI controller\n"); usbControllers[1] = new USBEHCIController(); - testRoot=new USBEHCIRootHub((USBEHCIController*)usbControllers[1]); - testRoot->findDevices(); + printf("done building EHCI controller \n"); + //testRoot=new USBEHCIRootHub((USBEHCIController*)usbControllers[1]); + //testRoot->findDevices(); break; } case 0x30:{ diff --git a/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h b/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h index 19446e4b6..604db025d 100644 --- a/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h +++ b/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h @@ -5,8 +5,8 @@ #include "USBHub.h" #include "drivers/PCI/USB/hostController/USBEHCIController.h" #include "utils/printf/Printf.h" - - +#include "Kernel.h" +#include "memory/structures/PageTable.h" class USBEHCIRootHub : public USBHub { private: EHCIPortStatCont* _ports; @@ -15,9 +15,10 @@ class USBEHCIRootHub : public USBHub { } USBEHCIRootHub(USBEHCIController* host):USBHub(host, true){ + pageTable.page((void*)(((uint32_t)(((USBEHCIController*)_host)->caps()->capLeng ))+ 0x44), (void*)(((uint32_t)(((USBEHCIController*)_host)->caps()->capLeng ))+ 0x44), + sizeof(EHCIPortStatCont) * ((USBEHCIController*)_host)->caps()->structParams.numOfPorts ); _ports = (EHCIPortStatCont*)(((uint32_t)(((USBEHCIController*)_host)->caps()->capLeng ))+ 0x44); //TODO add properly, CAPLENGTH (from host) + 44 _portCount = ((USBEHCIController*)_host)->caps()->structParams.numOfPorts; - } virtual void findDevices(){ for (int i = 0; i < _portCount; i++){ diff --git a/src/drivers/PCI/USB/hostController/USBEHCIController.h b/src/drivers/PCI/USB/hostController/USBEHCIController.h index 59c03b85b..9926c1b89 100644 --- a/src/drivers/PCI/USB/hostController/USBEHCIController.h +++ b/src/drivers/PCI/USB/hostController/USBEHCIController.h @@ -3,7 +3,7 @@ #include "Global.h" #include "USBHostController.h" - +#include "utils/printf/Printf.h" struct HWVersion{ uint8_t major; uint8_t minor; @@ -158,7 +158,9 @@ class USBEHCIController: public USBHostController{ } USBEHCIController(int bus, int device, int function) : USBHostController(bus,device,function){ + printf("making EHCI controller \n"); _caps = (CapReg*)BAR0(); + printf("bar0 = %x\n", BAR0()); _oper = (operReg*)((uint32_t) _caps + _caps->capLeng); switch (_oper->cmd.frameSizeList){ diff --git a/src/drivers/PCI/USB/hostController/USBHostController.h b/src/drivers/PCI/USB/hostController/USBHostController.h index d4ba9d6b3..e70e8e48d 100644 --- a/src/drivers/PCI/USB/hostController/USBHostController.h +++ b/src/drivers/PCI/USB/hostController/USBHostController.h @@ -3,7 +3,7 @@ #include "Global.h" #include "drivers/PCI/PCI_devices/PCIStandardDevice.h" - +#include "utils/printf/Printf.h" //TODO superclass class USBHostController : public PCIStandardDevice { protected: @@ -12,6 +12,7 @@ class USBHostController : public PCIStandardDevice { } USBHostController(int bus, int device, int function):PCIStandardDevice(bus, device,function, true){ + printf("making base Host controller\n"); } }; diff --git a/src/interrupts/InterruptHandler.cpp b/src/interrupts/InterruptHandler.cpp index e7958ece3..253fbf54e 100644 --- a/src/interrupts/InterruptHandler.cpp +++ b/src/interrupts/InterruptHandler.cpp @@ -10,6 +10,8 @@ #include "drivers/Keyboard.h" #include "drivers/TTY/Console.h" #include "drivers/ProgrammableInterruptController.h" +#include "utils/printf/Printf.h" + #if defined(__cplusplus) extern "C" {/* Use C linkage for kernel_main. */ #endif @@ -40,7 +42,7 @@ extern "C" {/* Use C linkage for kernel_main. */ //print the interrupt number terminalPutChar(' '); writeInt((uint32_t) interruptNumber); - + BREAKPOINT } #undef return diff --git a/src/memory/alloc/New.cpp b/src/memory/alloc/New.cpp index d97976c8c..0614e76d4 100644 --- a/src/memory/alloc/New.cpp +++ b/src/memory/alloc/New.cpp @@ -6,13 +6,14 @@ */ #include "memory/alloc/New.h" - +#include "utils/printf/Printf.h" //TODO fix this file void * operator new(size_t size) { //just call malloc, the compiler will run the constructor automaticly - void * p = malloc(size); - return p; + printf("called new\n"); + //void * p = /*malloc(size);*/ ::operator new(size); + return malloc(size); } void operator delete(void * p) { From 47e232d8a35e53415a4d69a01c4eab200141f39e Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Fri, 30 Mar 2018 14:26:51 -0500 Subject: [PATCH 142/171] fixed issue #61. still working on issue #60. part of the problem was calling the wrong constructor but there is still an issue with the constructor. probly has to do with paging --- src/drivers/PCI/PCI.c | 3 +- .../PCI/PCI_devices/PCIStandardDevice.cpp | 16 ++++---- src/drivers/PCI/USB/USB.cpp | 9 ++--- .../USB/hostController/USBEHCIController.h | 15 ++++++-- .../USB/hostController/USBHostController.h | 1 - src/drivers/PCI/makefile | 2 +- src/memory/alloc/New.cpp | 38 +++++++++++-------- 7 files changed, 46 insertions(+), 38 deletions(-) diff --git a/src/drivers/PCI/PCI.c b/src/drivers/PCI/PCI.c index e7bb8e0c9..f18f24b0e 100644 --- a/src/drivers/PCI/PCI.c +++ b/src/drivers/PCI/PCI.c @@ -66,7 +66,6 @@ void checkPCIBus(uint8_t bus) void checkPCIFunction(uint8_t bus, uint8_t device, uint8_t func) { - asm("hlt"); printf(" Found device at bus: %d, device: %d, func: %d\n", bus, device, func); printf(" The vender id is %x\n", getPCIVender(bus, device, func)); uint32_t classCode = getPCIClass(bus, device, func); @@ -88,8 +87,8 @@ void checkPCIFunction(uint8_t bus, uint8_t device, uint8_t func) case 0x0C: { if (subClass == 0x03){ - addUSBHostController(bus, device, func); printf(" This is a USB host controller\n"); + addUSBHostController(bus, device, func); break; } } diff --git a/src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp b/src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp index 089b85787..e2d5b27d2 100644 --- a/src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp +++ b/src/drivers/PCI/PCI_devices/PCIStandardDevice.cpp @@ -8,20 +8,18 @@ #include "drivers/PCI/PCI_devices/PCIStandardDevice.h" #include "drivers/PCI/PCI.h" #include "Kernel.h" +#include "memory/structures/PageTable.h" PCIStandardDevice::PCIStandardDevice(uint8_t bus, uint8_t device, uint8_t function, bool page):PCIDevice(bus, device, function, page) { if (page){ - pageTable.page(BAR0(), BAR0(),1) ; - pageTable.page(BAR1(), BAR1(),1) ; - pageTable.page(BAR2(), BAR2(),1) ; - pageTable.page(BAR3(), BAR3(),1) ; - pageTable.page(BAR4(), BAR4(),1) ; - pageTable.page(BAR5(), BAR5(),1) ; + pageTable.page((void*)BAR0(), (void*) BAR0(),1) ; + pageTable.page((void*)BAR1(), (void*) BAR1(),1) ; + pageTable.page((void*)BAR2(), (void*) BAR2(),1) ; + pageTable.page((void*)BAR3(), (void*) BAR3(),1) ; + pageTable.page((void*)BAR4(), (void*) BAR4(),1) ; + pageTable.page((void*)BAR5(), (void*) BAR5(),1) ; } } -PCIStandardDevice::~PCIStandardDevice( ) { - // TODO Auto-generated destructor stub -} uint32_t PCIStandardDevice::BAR0( ) { return readPCIConfigWord(_bus, _device, _function, 0x10); diff --git a/src/drivers/PCI/USB/USB.cpp b/src/drivers/PCI/USB/USB.cpp index d53a87116..adfaaddde 100644 --- a/src/drivers/PCI/USB/USB.cpp +++ b/src/drivers/PCI/USB/USB.cpp @@ -34,11 +34,10 @@ void addUSBHostController(int bus, int device, int function){ } case 0x20:{ //EHCI - printf(" Is an EHCI controller\n"); - usbControllers[1] = new USBEHCIController(); - printf("done building EHCI controller \n"); - //testRoot=new USBEHCIRootHub((USBEHCIController*)usbControllers[1]); - //testRoot->findDevices(); + printf(" Is an EHCI controller\n"); + usbControllers[1] = new USBEHCIController(bus, device, function); + testRoot=new USBEHCIRootHub((USBEHCIController*)usbControllers[1]); + testRoot->findDevices(); break; } case 0x30:{ diff --git a/src/drivers/PCI/USB/hostController/USBEHCIController.h b/src/drivers/PCI/USB/hostController/USBEHCIController.h index 9926c1b89..9591dc8ab 100644 --- a/src/drivers/PCI/USB/hostController/USBEHCIController.h +++ b/src/drivers/PCI/USB/hostController/USBEHCIController.h @@ -158,11 +158,11 @@ class USBEHCIController: public USBHostController{ } USBEHCIController(int bus, int device, int function) : USBHostController(bus,device,function){ - printf("making EHCI controller \n"); + BREAKPOINT _caps = (CapReg*)BAR0(); - printf("bar0 = %x\n", BAR0()); + BREAKPOINT _oper = (operReg*)((uint32_t) _caps + _caps->capLeng); - +BREAKPOINT switch (_oper->cmd.frameSizeList){ case 0b00:{ _frameListSize =1024; @@ -180,16 +180,23 @@ class USBEHCIController: public USBHostController{ //error } } - +BREAKPOINT _frameList = new FrameListLinkPointer[_frameListSize]; + BREAKPOINT for (size_t i =0; i < _frameListSize; i++){ _frameList[i].t =1; } + BREAKPOINT _oper->intEnable.ErrIntEnable = 1; + BREAKPOINT _oper->intEnable.portChangeIntEnable =1; + BREAKPOINT _oper->intEnable.hostSystemIntEnable =1; + BREAKPOINT _oper->frameListBase.baseAddr = (uint32_t)_frameList >> 12; + BREAKPOINT _oper->cmd.runStop =1; + BREAKPOINT _oper->flags.configFlag =1; } auto caps(){ diff --git a/src/drivers/PCI/USB/hostController/USBHostController.h b/src/drivers/PCI/USB/hostController/USBHostController.h index e70e8e48d..e3093efa9 100644 --- a/src/drivers/PCI/USB/hostController/USBHostController.h +++ b/src/drivers/PCI/USB/hostController/USBHostController.h @@ -12,7 +12,6 @@ class USBHostController : public PCIStandardDevice { } USBHostController(int bus, int device, int function):PCIStandardDevice(bus, device,function, true){ - printf("making base Host controller\n"); } }; diff --git a/src/drivers/PCI/makefile b/src/drivers/PCI/makefile index 841df0454..2d6c2bad8 100644 --- a/src/drivers/PCI/makefile +++ b/src/drivers/PCI/makefile @@ -1,4 +1,4 @@ -SUBDIRS = USB #PCI_devices +SUBDIRS = USB PCI_devices#PCI_devices OBS = PCI.o PCIDeviceList.o include ../../../makefile.inc diff --git a/src/memory/alloc/New.cpp b/src/memory/alloc/New.cpp index 0614e76d4..d07078fe9 100644 --- a/src/memory/alloc/New.cpp +++ b/src/memory/alloc/New.cpp @@ -7,25 +7,31 @@ #include "memory/alloc/New.h" #include "utils/printf/Printf.h" -//TODO fix this file +#include + +void *operator new(size_t size) +{ + return malloc(size); +} + +void *operator new[](size_t size) +{ + return malloc(size); +} + +void operator delete(void* p, unsigned long size){ -void * operator new(size_t size) { - //just call malloc, the compiler will run the constructor automaticly - printf("called new\n"); - //void * p = /*malloc(size);*/ ::operator new(size); - return malloc(size); } -void operator delete(void * p) { - free(p); +void operator delete(void *p) +{ + free(p); } -void operator delete(void* ptr, long unsigned int size/*maybe?*/) { - (void) size; - free(ptr); + +void operator delete[](void *p) +{ + free(p); } +void operator delete [](void* p, long unsigned int size){ -void* operator new[](unsigned long size){ - //new for arrays, ame as the other new - void * p = malloc(size); - return p; -} +} \ No newline at end of file From 2d6c6b0c368485addf77df4cc7fe64241b2c9683 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sun, 1 Apr 2018 21:34:26 -0500 Subject: [PATCH 143/171] fix for issue #61 there are still debug prints and breakpoints. will be removed later --- .bochsrc | 43 +++++++------- .bochsrc.old | 57 ------------------- src/Global.h | 2 +- src/Kernel.cpp | 2 +- src/drivers/PCI/USB/USB.cpp | 7 +++ .../USB/hostController/USBEHCIController.h | 16 ++---- src/memory/alloc/Malloc.c | 27 +++++++-- src/memory/structures/PageTable.cpp | 4 +- 8 files changed, 61 insertions(+), 97 deletions(-) delete mode 100644 .bochsrc.old diff --git a/.bochsrc b/.bochsrc index a8a3491b8..e0db481a2 100644 --- a/.bochsrc +++ b/.bochsrc @@ -1,22 +1,23 @@ # configuration file generated by Bochs -plugin_ctrl: unmapped=1, biosdev=1, speaker=1, extfpuirq=1, parallel=1, serial=1, iodebug=1 + +plugin_ctrl: unmapped=true, biosdev=true, speaker=true, extfpuirq=true, parallel=true, serial=true, iodebug=1, gameport=true, usb_ehci=true config_interface: textconfig -#display_library: x, options="gui_debug" +display_library: x, options="gui_debug" memory: host=32, guest=32 -romimage: file="/usr/share/bochs/BIOS-bochs-latest", address=0x0, options=none +romimage: file="/usr/share/bochs/BIOS-bochs-latest", address=0x00000000, options=none vgaromimage: file="/usr/share/bochs/VGABIOS-lgpl-latest" boot: floppy floppy_bootsig_check: disabled=0 floppya: type=1_44, 1_44="/dev/sdc", status=inserted, write_protected=0 # no floppyb -ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 +ata0: enabled=true, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 ata0-master: type=none ata0-slave: type=none -ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15 +ata1: enabled=true, ioaddr1=0x170, ioaddr2=0x370, irq=15 ata1-master: type=none ata1-slave: type=none -ata2: enabled=0 -ata3: enabled=0 +ata2: enabled=false +ata3: enabled=false optromimage1: file=none optromimage2: file=none optromimage3: file=none @@ -25,13 +26,13 @@ optramimage1: file=none optramimage2: file=none optramimage3: file=none optramimage4: file=none -pci: enabled=1, chipset=i440fx, slot1=usb_uhci, slot2=usb_ehci, slot3=usb_xhci +pci: enabled=1, chipset=i440fx, slot2=usb_ehci vga: extension=vbe, update_freq=5, realtime=1 cpu: count=1:1:1, ips=4000000, quantum=16, model=bx_generic, reset_on_triple_fault=0, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0 -cpuid: level=6, stepping=3, model=3, family=6, vendor_string="AuthenticAMD", brand_string="AMD Athlon(tm) processor" -cpuid: mmx=1, apic=xapic, simd=sse2, sse4a=0, misaligned_sse=0, sep=1, movbe=0, adx=0 -cpuid: aes=0, sha=0, xsave=0, xsaveopt=0, avx_f16c=0, avx_fma=0, bmi=0, xop=0, fma4=0 -cpuid: tbm=0, x86_64=1, 1g_pages=0, pcid=0, fsgsbase=0, smep=0, smap=0, mwait=1 +cpuid: level=6, stepping=3, model=3, family=6, vendor_string="GenuineIntel", brand_string=" Intel(R) Pentium(R) 4 CPU " +cpuid: mmx=true, apic=xapic, simd=sse2, sse4a=false, misaligned_sse=false, sep=true +cpuid: movbe=false, adx=false, aes=false, sha=false, xsave=false, xsaveopt=false, x86_64=true +cpuid: 1g_pages=false, pcid=false, fsgsbase=false, smep=false, smap=false, mwait=true print_timestamps: enabled=0 debugger_log: - magic_break: enabled=1 @@ -39,7 +40,6 @@ port_e9_hack: enabled=0 private_colormap: enabled=0 clock: sync=none, time0=local, rtc_sync=0 # no cmosimage -# no loader log: - logprefix: %t%e%d debug: action=ignore @@ -47,11 +47,12 @@ info: action=report error: action=report panic: action=ask keyboard: type=mf, serial_delay=250, paste_delay=100000, user_shortcut=none -mouse: type=ps2, enabled=0, toggle=ctrl+mbutton -speaker: enabled=1, mode=system -parport1: enabled=1, file=none -parport2: enabled=0 -com1: enabled=1, mode=null -com2: enabled=0 -com3: enabled=0 -com4: enabled=0 +mouse: type=ps2, enabled=false, toggle=ctrl+mbutton +speaker: enabled=true, mode=system +parport1: enabled=true, file=none +parport2: enabled=false +com1: enabled=true, mode=null +com2: enabled=false +com3: enabled=false +com4: enabled=false +usb_ehci: enabled=1, port1=none, options1=none, port2=none, options2=none, port3=none, options3=none, port4=none, options4=none, port5=none, options5=none, port6=none, options6=none diff --git a/.bochsrc.old b/.bochsrc.old deleted file mode 100644 index a8a3491b8..000000000 --- a/.bochsrc.old +++ /dev/null @@ -1,57 +0,0 @@ -# configuration file generated by Bochs -plugin_ctrl: unmapped=1, biosdev=1, speaker=1, extfpuirq=1, parallel=1, serial=1, iodebug=1 -config_interface: textconfig -#display_library: x, options="gui_debug" -memory: host=32, guest=32 -romimage: file="/usr/share/bochs/BIOS-bochs-latest", address=0x0, options=none -vgaromimage: file="/usr/share/bochs/VGABIOS-lgpl-latest" -boot: floppy -floppy_bootsig_check: disabled=0 -floppya: type=1_44, 1_44="/dev/sdc", status=inserted, write_protected=0 -# no floppyb -ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 -ata0-master: type=none -ata0-slave: type=none -ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15 -ata1-master: type=none -ata1-slave: type=none -ata2: enabled=0 -ata3: enabled=0 -optromimage1: file=none -optromimage2: file=none -optromimage3: file=none -optromimage4: file=none -optramimage1: file=none -optramimage2: file=none -optramimage3: file=none -optramimage4: file=none -pci: enabled=1, chipset=i440fx, slot1=usb_uhci, slot2=usb_ehci, slot3=usb_xhci -vga: extension=vbe, update_freq=5, realtime=1 -cpu: count=1:1:1, ips=4000000, quantum=16, model=bx_generic, reset_on_triple_fault=0, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0 -cpuid: level=6, stepping=3, model=3, family=6, vendor_string="AuthenticAMD", brand_string="AMD Athlon(tm) processor" -cpuid: mmx=1, apic=xapic, simd=sse2, sse4a=0, misaligned_sse=0, sep=1, movbe=0, adx=0 -cpuid: aes=0, sha=0, xsave=0, xsaveopt=0, avx_f16c=0, avx_fma=0, bmi=0, xop=0, fma4=0 -cpuid: tbm=0, x86_64=1, 1g_pages=0, pcid=0, fsgsbase=0, smep=0, smap=0, mwait=1 -print_timestamps: enabled=0 -debugger_log: - -magic_break: enabled=1 -port_e9_hack: enabled=0 -private_colormap: enabled=0 -clock: sync=none, time0=local, rtc_sync=0 -# no cmosimage -# no loader -log: - -logprefix: %t%e%d -debug: action=ignore -info: action=report -error: action=report -panic: action=ask -keyboard: type=mf, serial_delay=250, paste_delay=100000, user_shortcut=none -mouse: type=ps2, enabled=0, toggle=ctrl+mbutton -speaker: enabled=1, mode=system -parport1: enabled=1, file=none -parport2: enabled=0 -com1: enabled=1, mode=null -com2: enabled=0 -com3: enabled=0 -com4: enabled=0 diff --git a/src/Global.h b/src/Global.h index 02ac4d4b2..71842d02a 100755 --- a/src/Global.h +++ b/src/Global.h @@ -24,7 +24,7 @@ #include "utils/string/StrLen.h" //bochs breakpoing ASM -#define BREAKPOINT printf("hitbreakpoint");asm("hlt");asm("hlt"); +#define BREAKPOINT printf("hit breakpoint");asm("hlt"); asm("hlt"); //helpful constant #define FOUR_KB 4096 diff --git a/src/Kernel.cpp b/src/Kernel.cpp index 9500ba0bb..f68dcf772 100644 --- a/src/Kernel.cpp +++ b/src/Kernel.cpp @@ -70,7 +70,7 @@ void kernelMain(multiboot_info_t *mbd) //find the (3 or less) USB host controllers. all have the same class/subclass code. //PCIDeviceList usbHostControllers(0x0C, 0x03, false); //terminalWriteLine(" Done!"); - terminalWriteLine("!!!!ExOS fully booted!!!!"); + terminalWriteLine("!!!!ExOS fully booted!!!! 1"); //dont return. while (true) { asm("hlt"); diff --git a/src/drivers/PCI/USB/USB.cpp b/src/drivers/PCI/USB/USB.cpp index adfaaddde..a5293b56f 100644 --- a/src/drivers/PCI/USB/USB.cpp +++ b/src/drivers/PCI/USB/USB.cpp @@ -23,13 +23,16 @@ void USBInit(){ //todo types void addUSBHostController(int bus, int device, int function){ uint8_t progIF = getPCIProgIF(bus, device, function); + switch (progIF){ case 0x00:{ //UHCI + printf(" Is an UHCI controller\n"); break; } case 0x10:{ //OHCI + printf(" Is an OHCI controller\n"); break; } case 0x20:{ @@ -42,18 +45,22 @@ void addUSBHostController(int bus, int device, int function){ } case 0x30:{ //XHCI + printf(" Is an UHCI controller\n"); break; } case 0x80:{ //OTHER HCI + printf(" Is an Other HCI controller\n"); break; } case 0xFE:{ //Not a HCI + printf(" Is an not a controller\n"); break; } default:{ //error } + BREAKPOINT } } diff --git a/src/drivers/PCI/USB/hostController/USBEHCIController.h b/src/drivers/PCI/USB/hostController/USBEHCIController.h index 9591dc8ab..e49f842f6 100644 --- a/src/drivers/PCI/USB/hostController/USBEHCIController.h +++ b/src/drivers/PCI/USB/hostController/USBEHCIController.h @@ -158,11 +158,8 @@ class USBEHCIController: public USBHostController{ } USBEHCIController(int bus, int device, int function) : USBHostController(bus,device,function){ - BREAKPOINT _caps = (CapReg*)BAR0(); - BREAKPOINT _oper = (operReg*)((uint32_t) _caps + _caps->capLeng); -BREAKPOINT switch (_oper->cmd.frameSizeList){ case 0b00:{ _frameListSize =1024; @@ -180,23 +177,18 @@ BREAKPOINT //error } } -BREAKPOINT - _frameList = new FrameListLinkPointer[_frameListSize]; - BREAKPOINT + auto toMalloc = sizeof(FrameListLinkPointer) *_frameListSize; + printf("mallocing\n"); + auto malloced = malloc (toMalloc); + _frameList = (FrameListLinkPointer*) malloced; for (size_t i =0; i < _frameListSize; i++){ _frameList[i].t =1; } - BREAKPOINT _oper->intEnable.ErrIntEnable = 1; - BREAKPOINT _oper->intEnable.portChangeIntEnable =1; - BREAKPOINT _oper->intEnable.hostSystemIntEnable =1; - BREAKPOINT _oper->frameListBase.baseAddr = (uint32_t)_frameList >> 12; - BREAKPOINT _oper->cmd.runStop =1; - BREAKPOINT _oper->flags.configFlag =1; } auto caps(){ diff --git a/src/memory/alloc/Malloc.c b/src/memory/alloc/Malloc.c index 10b0eec13..a21359933 100644 --- a/src/memory/alloc/Malloc.c +++ b/src/memory/alloc/Malloc.c @@ -10,6 +10,7 @@ #include "memory/structures/PageTable.h" #include "memory/alloc/PageFrameAllocator.h" #include "memory/Mem.h" +#include "utils/printf/Printf.h" void *top; @@ -19,8 +20,10 @@ void *top; */ void mallocInit() { - top = (void*)((((size_t)(&kernelSize) + (uint32_t) & kernelStart - (uint32_t)pageTable.getKernelStart()) / FOUR_KB + 1) * FOUR_KB + - FOUR_KB - 1); + top = (void*)((((size_t)(&kernelSize) + (uint32_t) & kernelStart - (uint32_t)pageTable.getKernelStart()) / FOUR_KB + 1) * FOUR_KB /*+ + FOUR_KB*/ - 1); + printf("top = %x", top); + BREAKPOINT ((memHeader*)&kernelEnd)->used = false; ((memHeader*)&kernelEnd)->next = nullptr; @@ -36,27 +39,41 @@ extern "C" {/* Use C linkage for kernel_main. */ */ void *malloc(size_t size) { + BREAKPOINT + printf("in Malloc\n"); memHeader* c = (memHeader*)&kernelEnd; + printf("set c to %x\n", c); for (; c != nullptr; c = c->next) { + printf("looped\n"); if (c->next == nullptr) { - if ((uint32_t)c - (uint32_t)top >= (size + sizeof(memHeader)) && !c->used) { + printf("next is nullptr\n"); + if (((uint32_t)c - (uint32_t)top >= (size + 2*sizeof(memHeader))) && !c->used) { + printf("have space\n"); //TODO this may not work memHeader* temp = (memHeader*)(((uint8_t*)(c+1)) + size); - temp->next = c->next; + printf("set temp to, %x\n", temp); + temp->next = nullptr; + printf("set temps next\n"); temp->used = false; + printf("set temp as unsed\n"); c->next = temp; + printf("set c-> next to temp\n"); c->used = true; + printf("set c as used \n"); return c+1; } else { + printf("dont have space\n"); void* startOfNewMem = frameAlloc.allocatePhysMem(size,pageTable.getKernelStart()); size_t sizeOfNewMem = ((size)/FOUR_KB + ( (size & 0xFFF) != 0)) * FOUR_KB; top = (void*) ((size_t) top + sizeOfNewMem + ((size_t)startOfNewMem - (size_t)top) ); return malloc(size); } } else if (!c->used && (unsigned)(c->next - c) == size) { + printf("next is just enough space\n"); c->used = true; return c+1; } else if (!c->used && (unsigned)(c->next - c) >= (size + sizeof(memHeader))) { + printf("next is too big\n"); memHeader* temp = (memHeader*)(((uint8_t*)(c+1)) + size); temp->next = c->next; temp->used = false; @@ -64,9 +81,11 @@ void *malloc(size_t size) c->used = true; return c+1; } else { + printf("continuing \n"); continue; } } + printf("returning nullptr\n"); return nullptr; } diff --git a/src/memory/structures/PageTable.cpp b/src/memory/structures/PageTable.cpp index e26e92830..0ea771e96 100755 --- a/src/memory/structures/PageTable.cpp +++ b/src/memory/structures/PageTable.cpp @@ -6,7 +6,7 @@ */ #include "memory/structures/PageTable.h" - +#include "utils/printf/Printf.h" PageTable::PageTable( ) { } PageTable::PageTable(bool buildFlag) { @@ -96,6 +96,8 @@ void PageTable::build(){ } size_t kernelPages = ( ( (size_t)( &kernelSize) + (uint32_t) & kernelStart - vKernelStart) / FOUR_KB + 1); + printf("kernel pages = %d", kernelPages ); + //BREAKPOINT size_t kernelDirs = (kernelPages / 1024) + 1; for (size_t i = 0; i < kernelDirs; i++) { pageDir[KERNEL_PAGE_DIR_START + i].present = 1; From 8c462fcf21445517fb3578db1092443cb944c23b Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 2 Apr 2018 12:45:04 -0500 Subject: [PATCH 144/171] fixed issue #62 Will remove debuggin prints ans stuff next --- src/memory/alloc/Malloc.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/memory/alloc/Malloc.c b/src/memory/alloc/Malloc.c index a21359933..ccf248dd7 100644 --- a/src/memory/alloc/Malloc.c +++ b/src/memory/alloc/Malloc.c @@ -20,7 +20,7 @@ void *top; */ void mallocInit() { - top = (void*)((((size_t)(&kernelSize) + (uint32_t) & kernelStart - (uint32_t)pageTable.getKernelStart()) / FOUR_KB + 1) * FOUR_KB /*+ + top = (void*)((((size_t)(&kernelSize) + (uint32_t) & kernelStart) / FOUR_KB + 1) * FOUR_KB /*+ FOUR_KB*/ - 1); printf("top = %x", top); BREAKPOINT @@ -40,17 +40,21 @@ extern "C" {/* Use C linkage for kernel_main. */ void *malloc(size_t size) { BREAKPOINT - printf("in Malloc\n"); + printf("in Malloc, top = %x\n", top); memHeader* c = (memHeader*)&kernelEnd; - printf("set c to %x\n", c); + for (; c != nullptr; c = c->next) { printf("looped\n"); + printf("set c to %x\n", c); if (c->next == nullptr) { + printf("set c to %x\n", c); printf("next is nullptr\n"); - if (((uint32_t)c - (uint32_t)top >= (size + 2*sizeof(memHeader))) && !c->used) { + printf("top addr = %x\n (uint32_t)top = %x", (uint32_t)c + sizeof(memHeader) + size + sizeof(memHeader), (uint32_t)top); + if ( ((uint32_t)top >= (uint32_t)c + sizeof(memHeader) + size + sizeof(memHeader)) && !c->used) { printf("have space\n"); //TODO this may not work - memHeader* temp = (memHeader*)(((uint8_t*)(c+1)) + size); + printf("set c to %x\n", c); + memHeader* temp = (memHeader*)((uint32_t)c + sizeof(c) + size); printf("set temp to, %x\n", temp); temp->next = nullptr; printf("set temps next\n"); From 78c8c5eb0d1b7911ffccd57d8229c61b1a02179a Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 2 Apr 2018 12:50:33 -0500 Subject: [PATCH 145/171] removed all debug prints and breaks --- .../USB/hostController/USBEHCIController.h | 1 - src/interrupts/InterruptHandler.cpp | 1 - src/memory/alloc/Malloc.c | 22 ------------------- 3 files changed, 24 deletions(-) diff --git a/src/drivers/PCI/USB/hostController/USBEHCIController.h b/src/drivers/PCI/USB/hostController/USBEHCIController.h index e49f842f6..79f22972e 100644 --- a/src/drivers/PCI/USB/hostController/USBEHCIController.h +++ b/src/drivers/PCI/USB/hostController/USBEHCIController.h @@ -178,7 +178,6 @@ class USBEHCIController: public USBHostController{ } } auto toMalloc = sizeof(FrameListLinkPointer) *_frameListSize; - printf("mallocing\n"); auto malloced = malloc (toMalloc); _frameList = (FrameListLinkPointer*) malloced; for (size_t i =0; i < _frameListSize; i++){ diff --git a/src/interrupts/InterruptHandler.cpp b/src/interrupts/InterruptHandler.cpp index 253fbf54e..3179b1b73 100644 --- a/src/interrupts/InterruptHandler.cpp +++ b/src/interrupts/InterruptHandler.cpp @@ -42,7 +42,6 @@ extern "C" {/* Use C linkage for kernel_main. */ //print the interrupt number terminalPutChar(' '); writeInt((uint32_t) interruptNumber); - BREAKPOINT } #undef return diff --git a/src/memory/alloc/Malloc.c b/src/memory/alloc/Malloc.c index ccf248dd7..01beb1d88 100644 --- a/src/memory/alloc/Malloc.c +++ b/src/memory/alloc/Malloc.c @@ -22,8 +22,6 @@ void mallocInit() { top = (void*)((((size_t)(&kernelSize) + (uint32_t) & kernelStart) / FOUR_KB + 1) * FOUR_KB /*+ FOUR_KB*/ - 1); - printf("top = %x", top); - BREAKPOINT ((memHeader*)&kernelEnd)->used = false; ((memHeader*)&kernelEnd)->next = nullptr; @@ -39,45 +37,27 @@ extern "C" {/* Use C linkage for kernel_main. */ */ void *malloc(size_t size) { - BREAKPOINT - printf("in Malloc, top = %x\n", top); memHeader* c = (memHeader*)&kernelEnd; - for (; c != nullptr; c = c->next) { - printf("looped\n"); - printf("set c to %x\n", c); if (c->next == nullptr) { - printf("set c to %x\n", c); - printf("next is nullptr\n"); - printf("top addr = %x\n (uint32_t)top = %x", (uint32_t)c + sizeof(memHeader) + size + sizeof(memHeader), (uint32_t)top); if ( ((uint32_t)top >= (uint32_t)c + sizeof(memHeader) + size + sizeof(memHeader)) && !c->used) { - printf("have space\n"); //TODO this may not work - printf("set c to %x\n", c); memHeader* temp = (memHeader*)((uint32_t)c + sizeof(c) + size); - printf("set temp to, %x\n", temp); temp->next = nullptr; - printf("set temps next\n"); temp->used = false; - printf("set temp as unsed\n"); c->next = temp; - printf("set c-> next to temp\n"); c->used = true; - printf("set c as used \n"); return c+1; } else { - printf("dont have space\n"); void* startOfNewMem = frameAlloc.allocatePhysMem(size,pageTable.getKernelStart()); size_t sizeOfNewMem = ((size)/FOUR_KB + ( (size & 0xFFF) != 0)) * FOUR_KB; top = (void*) ((size_t) top + sizeOfNewMem + ((size_t)startOfNewMem - (size_t)top) ); return malloc(size); } } else if (!c->used && (unsigned)(c->next - c) == size) { - printf("next is just enough space\n"); c->used = true; return c+1; } else if (!c->used && (unsigned)(c->next - c) >= (size + sizeof(memHeader))) { - printf("next is too big\n"); memHeader* temp = (memHeader*)(((uint8_t*)(c+1)) + size); temp->next = c->next; temp->used = false; @@ -85,11 +65,9 @@ void *malloc(size_t size) c->used = true; return c+1; } else { - printf("continuing \n"); continue; } } - printf("returning nullptr\n"); return nullptr; } From 781fd7739a27858f1fe58edc997c481f9c15214a Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 2 Apr 2018 12:52:48 -0500 Subject: [PATCH 146/171] Update README.MD --- README.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.MD b/README.MD index 70199fec7..20ad20469 100755 --- a/README.MD +++ b/README.MD @@ -19,7 +19,7 @@ ExOS extends the [MIT exokernel](https://pdos.csail.mit.edu/archive/exo/) by rem - [ ] USB abstract class - [ ] OHCI driver - [ ] UHCI driver - - [ ] EHCI driver + - [x] EHCI driver - mostly, still may have some issues with the root hub - [ ] XHCI driver * Oskari From ac811ffccc21a1622778c80d1f377356bca8e16f Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 2 Apr 2018 12:58:09 -0500 Subject: [PATCH 147/171] looks like the device detection code works --- src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h b/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h index 604db025d..55e8b6737 100644 --- a/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h +++ b/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h @@ -22,7 +22,9 @@ class USBEHCIRootHub : public USBHub { } virtual void findDevices(){ for (int i = 0; i < _portCount; i++){ - printf("found a device\n"); + if (_ports[i].conStat == 1){ + printf("found a device\n"); + } } } }; From c9a4ffb8389a558c491d7708f259c55bb2ccbefc Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 2 Apr 2018 13:00:07 -0500 Subject: [PATCH 148/171] Delete org.eclipse.cdt.core.prefs --- .settings/org.eclipse.cdt.core.prefs | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 .settings/org.eclipse.cdt.core.prefs diff --git a/.settings/org.eclipse.cdt.core.prefs b/.settings/org.eclipse.cdt.core.prefs deleted file mode 100644 index 0ba3e5387..000000000 --- a/.settings/org.eclipse.cdt.core.prefs +++ /dev/null @@ -1,15 +0,0 @@ -eclipse.preferences.version=1 -indexer/indexAllFiles=true -indexer/indexAllHeaderVersions=true -indexer/indexAllVersionsSpecificHeaders= -indexer/indexOnOpen=true -indexer/indexUnusedHeadersWithAlternateLang=true -indexer/indexUnusedHeadersWithDefaultLang=true -indexer/indexerId=org.eclipse.cdt.core.fastIndexer -indexer/skipFilesLargerThanMB=8 -indexer/skipImplicitReferences=false -indexer/skipIncludedFilesLargerThanMB=16 -indexer/skipMacroReferences=false -indexer/skipReferences=false -indexer/skipTypeReferences=false -indexer/useHeuristicIncludeResolution=true From 1b94bd9014e2869652edce29149736378824d41c Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 2 Apr 2018 13:00:19 -0500 Subject: [PATCH 149/171] Delete language.settings.xml --- .settings/language.settings.xml | 91 --------------------------------- 1 file changed, 91 deletions(-) delete mode 100755 .settings/language.settings.xml diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml deleted file mode 100755 index 3bd2729cb..000000000 --- a/.settings/language.settings.xml +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From eb425760ed731ed0b219f63eb5d6dbf88d18db2d Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 2 Apr 2018 13:00:28 -0500 Subject: [PATCH 150/171] Delete org.eclipse.cdt.codan.core.prefs --- .settings/org.eclipse.cdt.codan.core.prefs | 72 ---------------------- 1 file changed, 72 deletions(-) delete mode 100755 .settings/org.eclipse.cdt.codan.core.prefs diff --git a/.settings/org.eclipse.cdt.codan.core.prefs b/.settings/org.eclipse.cdt.codan.core.prefs deleted file mode 100755 index 8e1a30fbb..000000000 --- a/.settings/org.eclipse.cdt.codan.core.prefs +++ /dev/null @@ -1,72 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.cdt.codan.checkers.errnoreturn=-Warning -org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return\\")",implicit\=>false} -org.eclipse.cdt.codan.checkers.errreturnvalue=-Error -org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused return value\\")"} -org.eclipse.cdt.codan.checkers.nocommentinside=-Error -org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Nesting comments\\")"} -org.eclipse.cdt.codan.checkers.nolinecomment=-Error -org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Line comments\\")"} -org.eclipse.cdt.codan.checkers.noreturn=-Error -org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return value\\")",implicit\=>false} -org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=-Error -org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Abstract class cannot be instantiated\\")"} -org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=-Error -org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Ambiguous problem\\")"} -org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment in condition\\")"} -org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=-Error -org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment to itself\\")"} -org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No break at end of case\\")",no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false} -org.eclipse.cdt.codan.internal.checkers.CatchByReference=-Warning -org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Catching by reference is recommended\\")",unknown\=>false,exceptions\=>()} -org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=-Error -org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Circular inheritance\\")"} -org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=-Warning -org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class members should be properly initialized\\")",skip\=>true} -org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=-Error -org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Field cannot be resolved\\")"} -org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=-Error -org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Function cannot be resolved\\")"} -org.eclipse.cdt.codan.internal.checkers.InvalidArguments=-Error -org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid arguments\\")"} -org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=-Error -org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid template argument\\")"} -org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=-Error -org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Label statement not found\\")"} -org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=-Error -org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Member declaration not found\\")"} -org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=-Error -org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Method cannot be resolved\\")"} -org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info -org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Name convention for function\\")",pattern\=>"^[a-z]",macro\=>true,exceptions\=>()} -org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class has a virtual method and non-virtual destructor\\")"} -org.eclipse.cdt.codan.internal.checkers.OverloadProblem=-Error -org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid overload\\")"} -org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=-Error -org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redeclaration\\")"} -org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=-Error -org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redefinition\\")"} -org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Return with parenthesis\\")"} -org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Format String Vulnerability\\")"} -org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Statement has no effect\\")",macro\=>true,exceptions\=>()} -org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suggested parenthesis around expression\\")",paramNot\=>false} -org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suspicious semicolon\\")",else\=>false,afterelse\=>false} -org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=-Error -org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Type cannot be resolved\\")"} -org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused function declaration\\")",macro\=>true} -org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused static function\\")",macro\=>true} -org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused variable declaration in file scope\\")",macro\=>true,exceptions\=>("@(\#)","$Id")} -org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=-Error -org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Symbol is not resolved\\")"} -useParentScope=false From 68d232925febde44825c54241449d310dc35ec4e Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 2 Apr 2018 13:00:38 -0500 Subject: [PATCH 151/171] Delete #.bochsrc# --- #.bochsrc# | 55 ------------------------------------------------------ 1 file changed, 55 deletions(-) delete mode 100644 #.bochsrc# diff --git a/#.bochsrc# b/#.bochsrc# deleted file mode 100644 index e45fd4ca7..000000000 --- a/#.bochsrc# +++ /dev/null @@ -1,55 +0,0 @@ -# configuration file generated by Bochs -plugin_ctrl: unmapped=1, biosdev=1, speaker=1, extfpuirq=1, parallel=1, serial=1, gameport=1 -config_interface: textconfig -display_library: x -memory: host=32, guest=32 -romimage: file="/usr/share/bochs/BIOS-bochs-latest", address=0x0, options=none -vgaromimage: file="/usr/share/bochs/VGABIOS-lgpl-latest" -boot: floppy -floppy_bootsig_check: disabled=0 -floppya: type=1_44, 1_44="/dev/sdf", status=inserted, write_protected=0 -# no floppyb -ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 -ata0-master: type=none -ata0-slave: type=none -ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15 -ata1-master: type=none -ata1-slave: type=none -ata2: enabled=0 -ata3: enabled=0 -optromimage1: file=none -optromimage2: file=none -optromimage3: file=none -optromimage4: file=none -optramimage1: file=none -optramimage2: file=none -optramimage3: file=none -optramimage4: file=none -pci: enabled=1, chipset=i440fx -vga: extension=vbe, update_freq=5, realtime=1 -cpu: count=1:1:1, ips=4000000, quantum=16, model=bx_generic, reset_on_triple_fault=1, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0 -cpuid: level=6, stepping=3, model=3, family=6, vendor_string="GenuineIntel", brand_string=" Intel(R) Pentium(R) 4 CPU " -cpuid: mmx=1, apic=xapic, simd=sse2, sse4a=0, misaligned_sse=0, sep=1, movbe=0, adx=0 -cpuid: aes=0, sha=0, xsave=0, xsaveopt=0, x86_64=1, 1g_pages=0, pcid=0, fsgsbase=0 -cpuid: smep=0, smap=0, mwait=1 -print_timestamps: enabled=0 -port_e9_hack: enabled=0 -private_colormap: enabled=0 -clock: sync=none, time0=local, rtc_sync=0 -# no cmosimage -# no loader -log: - -logprefix: %t%e%d -debug: action=ignore -info: action=report -error: action=report -panic: action=ask -keyboard: type=mf, serial_delay=250, paste_delay=100000, user_shortcut=none -mouse: type=ps2, enabled=0, toggle=ctrl+mbutton -speaker: enabled=1, mode=system -parport1: enabled=1, file=none -parport2: enabled=0 -com1: enabled=1, mode=null -com2: enabled=0 -com3: enabled=0 -com4: enabled=0 From 01412c5b813e17c038d81e0bb84454269d9f5898 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 2 Apr 2018 13:00:51 -0500 Subject: [PATCH 152/171] Delete .cproject --- .cproject | 450 ------------------------------------------------------ 1 file changed, 450 deletions(-) delete mode 100755 .cproject diff --git a/.cproject b/.cproject deleted file mode 100755 index 9ac014a30..000000000 --- a/.cproject +++ /dev/null @@ -1,450 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 1377b866afede32e308ee6657c35f73912799442 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 2 Apr 2018 13:01:16 -0500 Subject: [PATCH 153/171] Delete .project --- .project | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100755 .project diff --git a/.project b/.project deleted file mode 100755 index b151407ee..000000000 --- a/.project +++ /dev/null @@ -1,27 +0,0 @@ - - - OS C++ - - - - - - org.eclipse.cdt.managedbuilder.core.genmakebuilder - clean, - - - - - org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder - full,incremental, - - - - - - org.eclipse.cdt.core.cnature - org.eclipse.cdt.core.ccnature - org.eclipse.cdt.managedbuilder.core.managedBuildNature - org.eclipse.cdt.managedbuilder.core.ScannerConfigNature - - From 9d405c9b73a093f0a3adf864ef4fde2de5665d29 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 2 Apr 2018 13:01:31 -0500 Subject: [PATCH 154/171] Delete syscall numbers.ods --- syscall numbers.ods | Bin 14565 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 syscall numbers.ods diff --git a/syscall numbers.ods b/syscall numbers.ods deleted file mode 100644 index 6d9da4208360f8bcc641beb9bd610af47c6ce1fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14565 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 RY Date: Mon, 2 Apr 2018 14:36:06 -0500 Subject: [PATCH 155/171] base files for the PIT --- src/drivers/makefile | 2 +- .../programmableIntervalTimer/ProgrammableIntervalTimer.cpp | 1 + .../programmableIntervalTimer/ProgrammableIntervalTimer.h | 6 ++++++ src/drivers/programmableIntervalTimer/makefile | 5 +++++ 4 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 src/drivers/programmableIntervalTimer/ProgrammableIntervalTimer.cpp create mode 100644 src/drivers/programmableIntervalTimer/ProgrammableIntervalTimer.h create mode 100644 src/drivers/programmableIntervalTimer/makefile diff --git a/src/drivers/makefile b/src/drivers/makefile index 42db213c5..21868b47f 100644 --- a/src/drivers/makefile +++ b/src/drivers/makefile @@ -1,4 +1,4 @@ -SUBDIRS = PCI TTY generic filesys +SUBDIRS = PCI TTY generic filesys programmableIntervalTimer OBS= Keyboard.o ProgrammableInterruptController.o include ../../makefile.inc diff --git a/src/drivers/programmableIntervalTimer/ProgrammableIntervalTimer.cpp b/src/drivers/programmableIntervalTimer/ProgrammableIntervalTimer.cpp new file mode 100644 index 000000000..a34f10be0 --- /dev/null +++ b/src/drivers/programmableIntervalTimer/ProgrammableIntervalTimer.cpp @@ -0,0 +1 @@ +#include "ProgrammableIntervalTimer.h" \ No newline at end of file diff --git a/src/drivers/programmableIntervalTimer/ProgrammableIntervalTimer.h b/src/drivers/programmableIntervalTimer/ProgrammableIntervalTimer.h new file mode 100644 index 000000000..189a552d8 --- /dev/null +++ b/src/drivers/programmableIntervalTimer/ProgrammableIntervalTimer.h @@ -0,0 +1,6 @@ +#ifndef _PROGRAMMABLE_INTERVAL_TIMER_H_ +#define _PROGRAMMABLE_INTERVAL_TIMER_H_ + +#include "Global.h" + +#endif \ No newline at end of file diff --git a/src/drivers/programmableIntervalTimer/makefile b/src/drivers/programmableIntervalTimer/makefile new file mode 100644 index 000000000..b5ce8aa41 --- /dev/null +++ b/src/drivers/programmableIntervalTimer/makefile @@ -0,0 +1,5 @@ +SUBDIRS = +OBS= ProgrammableIntervalTimer.o + +include ../../../makefile.inc + From 9aed5246ed3aa7c707a98dbd38c087ca342db26e Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 2 Apr 2018 21:18:13 -0500 Subject: [PATCH 156/171] created interval timer also added to main --- src/Kernel.cpp | 5 ++++- src/Kernel.h | 3 ++- .../ProgrammableIntervalTimer.cpp | 3 ++- .../ProgrammableIntervalTimer.h | 19 +++++++++++++++++++ 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/Kernel.cpp b/src/Kernel.cpp index f68dcf772..d94220b37 100644 --- a/src/Kernel.cpp +++ b/src/Kernel.cpp @@ -19,12 +19,13 @@ #include "multiboot_spec/Multiboot.h" #include "memory/Mem.h" #include "utils/printf/Printf.h" - +#include "drivers/programmableIntervalTimer/ProgrammableIntervalTimer.h" InterruptDescriptorTable idt; GlobalDescriptorTable gdt; PageTable pageTable; Keyboard KB; PageFrameAllocator frameAlloc; +ProgrammableIntervalTimer pit; #if defined(__cplusplus) extern "C" {/* Use C linkage for kernel_main. */ @@ -53,6 +54,8 @@ void kernelMain(multiboot_info_t *mbd) //sets up interrups and enables them interruptSetUp(); terminalWriteLine(" Done!"); + terminalWriteString(" Setting up PIT..."); + pit = ProgrammableIntervalTimer(); terminalWriteString(" Preparing the memory allocator..."); //get the memory map from grub getMemMap(mbd); diff --git a/src/Kernel.h b/src/Kernel.h index 01bfe16c3..4f7d88a3c 100644 --- a/src/Kernel.h +++ b/src/Kernel.h @@ -15,12 +15,13 @@ class GlobalDescriptorTable; class PageFrameAllocator; class Keyboard; class PageTable; - +class ProgrammableIntervalTimer; extern GlobalDescriptorTable gdt; extern InterruptDescriptorTable idt; extern PageTable pageTable; extern Keyboard KB; extern PageFrameAllocator frameAlloc; +extern ProgrammableIntervalTimer pit; void interruptSetUp(); diff --git a/src/drivers/programmableIntervalTimer/ProgrammableIntervalTimer.cpp b/src/drivers/programmableIntervalTimer/ProgrammableIntervalTimer.cpp index a34f10be0..cbbf9d7b8 100644 --- a/src/drivers/programmableIntervalTimer/ProgrammableIntervalTimer.cpp +++ b/src/drivers/programmableIntervalTimer/ProgrammableIntervalTimer.cpp @@ -1 +1,2 @@ -#include "ProgrammableIntervalTimer.h" \ No newline at end of file +#include "ProgrammableIntervalTimer.h" + diff --git a/src/drivers/programmableIntervalTimer/ProgrammableIntervalTimer.h b/src/drivers/programmableIntervalTimer/ProgrammableIntervalTimer.h index 189a552d8..62f1bc5a9 100644 --- a/src/drivers/programmableIntervalTimer/ProgrammableIntervalTimer.h +++ b/src/drivers/programmableIntervalTimer/ProgrammableIntervalTimer.h @@ -2,5 +2,24 @@ #define _PROGRAMMABLE_INTERVAL_TIMER_H_ #include "Global.h" +#include "drivers/generic/SpecialDevice.h" +struct PIT_CMD{ + uint8_t BCD:1; + uint8_t opMode:3; + uint8_t accessMode:2; + uint8_t channel:2; +}__attribute__((__packed__)); + +class ProgrammableIntervalTimer : public SpecialDevice{ + private: + uint16_t divisor = 1000; + public: + ProgrammableIntervalTimer() : SpecialDevice(){ + PIT_CMD cmd = {0,3,3,0}; + outb(0x43, *(uint8_t*)&cmd); + outb(0x40, divisor & 0xFF); + outb(0x40, (divisor >>8) & 0xFF); + } +}; #endif \ No newline at end of file From ee752fd627c5a1c8a796a7395506116559657911 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 3 Apr 2018 08:56:36 -0500 Subject: [PATCH 157/171] milisleep i hope... --- src/Kernel.cpp | 2 +- src/drivers/makefile | 2 +- .../ProgrammableIntervalTimer.cpp | 0 .../ProgrammableIntervalTimer.h | 18 ++++++++++++++++++ src/drivers/timers/Sleep.cpp | 6 ++++++ src/drivers/timers/Sleep.h | 8 ++++++++ .../makefile | 2 +- 7 files changed, 35 insertions(+), 3 deletions(-) rename src/drivers/{programmableIntervalTimer => timers}/ProgrammableIntervalTimer.cpp (100%) rename src/drivers/{programmableIntervalTimer => timers}/ProgrammableIntervalTimer.h (54%) create mode 100644 src/drivers/timers/Sleep.cpp create mode 100644 src/drivers/timers/Sleep.h rename src/drivers/{programmableIntervalTimer => timers}/makefile (51%) diff --git a/src/Kernel.cpp b/src/Kernel.cpp index d94220b37..ad2c667fd 100644 --- a/src/Kernel.cpp +++ b/src/Kernel.cpp @@ -19,7 +19,7 @@ #include "multiboot_spec/Multiboot.h" #include "memory/Mem.h" #include "utils/printf/Printf.h" -#include "drivers/programmableIntervalTimer/ProgrammableIntervalTimer.h" +#include "drivers/timers/ProgrammableIntervalTimer.h" InterruptDescriptorTable idt; GlobalDescriptorTable gdt; PageTable pageTable; diff --git a/src/drivers/makefile b/src/drivers/makefile index 21868b47f..a708c2685 100644 --- a/src/drivers/makefile +++ b/src/drivers/makefile @@ -1,4 +1,4 @@ -SUBDIRS = PCI TTY generic filesys programmableIntervalTimer +SUBDIRS = PCI TTY generic filesys timers OBS= Keyboard.o ProgrammableInterruptController.o include ../../makefile.inc diff --git a/src/drivers/programmableIntervalTimer/ProgrammableIntervalTimer.cpp b/src/drivers/timers/ProgrammableIntervalTimer.cpp similarity index 100% rename from src/drivers/programmableIntervalTimer/ProgrammableIntervalTimer.cpp rename to src/drivers/timers/ProgrammableIntervalTimer.cpp diff --git a/src/drivers/programmableIntervalTimer/ProgrammableIntervalTimer.h b/src/drivers/timers/ProgrammableIntervalTimer.h similarity index 54% rename from src/drivers/programmableIntervalTimer/ProgrammableIntervalTimer.h rename to src/drivers/timers/ProgrammableIntervalTimer.h index 62f1bc5a9..9dff43da1 100644 --- a/src/drivers/programmableIntervalTimer/ProgrammableIntervalTimer.h +++ b/src/drivers/timers/ProgrammableIntervalTimer.h @@ -3,6 +3,8 @@ #include "Global.h" #include "drivers/generic/SpecialDevice.h" +#include "Kernel.h" +#include "drivers/ProgrammableInterruptController.h" struct PIT_CMD{ uint8_t BCD:1; uint8_t opMode:3; @@ -13,12 +15,28 @@ struct PIT_CMD{ class ProgrammableIntervalTimer : public SpecialDevice{ private: uint16_t divisor = 1000; + //TODO eventually there will be more then one timer + volatile uint64_t ticksRemaining = 0; + static const int interruptLine = 0; public: ProgrammableIntervalTimer() : SpecialDevice(){ PIT_CMD cmd = {0,3,3,0}; outb(0x43, *(uint8_t*)&cmd); outb(0x40, divisor & 0xFF); outb(0x40, (divisor >>8) & 0xFF); + + } + void tick(){ + ticksRemaining--; + } + void setTimer(unsigned int ticks){ + ticksRemaining = ticks; + IRQClearMask(interruptLine); + while(ticks != 0){ + ; + } + IRQSetMask(interruptLine); + } }; diff --git a/src/drivers/timers/Sleep.cpp b/src/drivers/timers/Sleep.cpp new file mode 100644 index 000000000..1bb7c81d0 --- /dev/null +++ b/src/drivers/timers/Sleep.cpp @@ -0,0 +1,6 @@ +#include "Sleep.h" +#include "Kernel.h" +#include "ProgrammableIntervalTimer.h" +unsigned int milisleep(unsigned int miliseconds){ + pit.setTimer(miliseconds); +} \ No newline at end of file diff --git a/src/drivers/timers/Sleep.h b/src/drivers/timers/Sleep.h new file mode 100644 index 000000000..5199d2d52 --- /dev/null +++ b/src/drivers/timers/Sleep.h @@ -0,0 +1,8 @@ +#ifndef SLEEP_H_ +#define SLEEP_H_ + +#include "Global.h" + +unsigned int milisleep(unsigned int miliseconds); + +#endif \ No newline at end of file diff --git a/src/drivers/programmableIntervalTimer/makefile b/src/drivers/timers/makefile similarity index 51% rename from src/drivers/programmableIntervalTimer/makefile rename to src/drivers/timers/makefile index b5ce8aa41..8683d29da 100644 --- a/src/drivers/programmableIntervalTimer/makefile +++ b/src/drivers/timers/makefile @@ -1,5 +1,5 @@ SUBDIRS = -OBS= ProgrammableIntervalTimer.o +OBS= ProgrammableIntervalTimer.o Sleep.o include ../../../makefile.inc From b75e6aa817186e39ad2888a43c852277010cbf20 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 3 Apr 2018 09:18:56 -0500 Subject: [PATCH 158/171] tiemr done and tested --- src/Kernel.cpp | 3 +++ .../timers/ProgrammableIntervalTimer.h | 3 ++- src/drivers/timers/Sleep.cpp | 4 +++ src/drivers/timers/Sleep.h | 1 + src/interrupts/InterruptHandler.cpp | 26 ++++++++++++------- 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/Kernel.cpp b/src/Kernel.cpp index ad2c667fd..6bd673cc1 100644 --- a/src/Kernel.cpp +++ b/src/Kernel.cpp @@ -20,6 +20,8 @@ #include "memory/Mem.h" #include "utils/printf/Printf.h" #include "drivers/timers/ProgrammableIntervalTimer.h" +#include "drivers/timers/Sleep.h" + InterruptDescriptorTable idt; GlobalDescriptorTable gdt; PageTable pageTable; @@ -56,6 +58,7 @@ void kernelMain(multiboot_info_t *mbd) terminalWriteLine(" Done!"); terminalWriteString(" Setting up PIT..."); pit = ProgrammableIntervalTimer(); + terminalWriteLine(" Done!"); terminalWriteString(" Preparing the memory allocator..."); //get the memory map from grub getMemMap(mbd); diff --git a/src/drivers/timers/ProgrammableIntervalTimer.h b/src/drivers/timers/ProgrammableIntervalTimer.h index 9dff43da1..b6cfb1506 100644 --- a/src/drivers/timers/ProgrammableIntervalTimer.h +++ b/src/drivers/timers/ProgrammableIntervalTimer.h @@ -5,6 +5,7 @@ #include "drivers/generic/SpecialDevice.h" #include "Kernel.h" #include "drivers/ProgrammableInterruptController.h" +#include "utils/printf/Printf.h" struct PIT_CMD{ uint8_t BCD:1; uint8_t opMode:3; @@ -32,7 +33,7 @@ class ProgrammableIntervalTimer : public SpecialDevice{ void setTimer(unsigned int ticks){ ticksRemaining = ticks; IRQClearMask(interruptLine); - while(ticks != 0){ + while(ticksRemaining != 0){ ; } IRQSetMask(interruptLine); diff --git a/src/drivers/timers/Sleep.cpp b/src/drivers/timers/Sleep.cpp index 1bb7c81d0..6d58bbe7a 100644 --- a/src/drivers/timers/Sleep.cpp +++ b/src/drivers/timers/Sleep.cpp @@ -3,4 +3,8 @@ #include "ProgrammableIntervalTimer.h" unsigned int milisleep(unsigned int miliseconds){ pit.setTimer(miliseconds); +} + +unsigned int sleep(unsigned int seconds){ + pit.setTimer(1000*seconds); } \ No newline at end of file diff --git a/src/drivers/timers/Sleep.h b/src/drivers/timers/Sleep.h index 5199d2d52..9f05e854b 100644 --- a/src/drivers/timers/Sleep.h +++ b/src/drivers/timers/Sleep.h @@ -4,5 +4,6 @@ #include "Global.h" unsigned int milisleep(unsigned int miliseconds); +unsigned int sleep(unsigned int seconds); #endif \ No newline at end of file diff --git a/src/interrupts/InterruptHandler.cpp b/src/interrupts/InterruptHandler.cpp index 3179b1b73..2d64c7bc0 100644 --- a/src/interrupts/InterruptHandler.cpp +++ b/src/interrupts/InterruptHandler.cpp @@ -11,6 +11,7 @@ #include "drivers/TTY/Console.h" #include "drivers/ProgrammableInterruptController.h" #include "utils/printf/Printf.h" +#include "drivers/timers/ProgrammableIntervalTimer.h" #if defined(__cplusplus) extern "C" {/* Use C linkage for kernel_main. */ @@ -20,16 +21,21 @@ extern "C" {/* Use C linkage for kernel_main. */ * @param line from the PIC */ void IRQHandler(int line) { - if (line == 1/*KB*/) { - uint8_t scanCode = KB.getScancode( ); - uint8_t key = KB.getKey(scanCode); - //if printable key - if (key != '\0' && ! (scanCode & 0x80)) { - //put the key - terminalPutChar(key); - } else { - //handle the special key - terminalHandleSpecialKey(scanCode, KB.getModkeys( )); + switch (line) { + case 0:{ + pit.tick(); + } + case 1: { + uint8_t scanCode = KB.getScancode( ); + uint8_t key = KB.getKey(scanCode); + //if printable key + if (key != '\0' && ! (scanCode & 0x80)) { + //put the key + terminalPutChar(key); + } else { + //handle the special key + terminalHandleSpecialKey(scanCode, KB.getModkeys( )); + } } } PICSendEOI(line); From 4a79e3a1de3746360b519dad951a23236de47823 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 3 Apr 2018 10:39:44 -0500 Subject: [PATCH 159/171] reset and enable port --- src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h b/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h index 55e8b6737..ecd78e86b 100644 --- a/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h +++ b/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h @@ -7,6 +7,7 @@ #include "utils/printf/Printf.h" #include "Kernel.h" #include "memory/structures/PageTable.h" +#include "drivers/timers/Sleep.h" class USBEHCIRootHub : public USBHub { private: EHCIPortStatCont* _ports; @@ -24,6 +25,15 @@ class USBEHCIRootHub : public USBHub { for (int i = 0; i < _portCount; i++){ if (_ports[i].conStat == 1){ printf("found a device\n"); + printf("resetting device\n"); + _ports[i].portEnable =0; + _ports[i].reset =1; + milisleep(80); + printf("done resetting\n"); + _ports[i].reset = 0; + milisleep(5); + printf("port enabled\n"); + } } } From 64d1c4948598033ed7efa823b34afe8941af0f99 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 3 Apr 2018 11:10:07 -0500 Subject: [PATCH 160/171] refactor hub tree --- src/drivers/PCI/USB/USB.cpp | 4 ++-- src/drivers/PCI/USB/USBFunction.cpp | 6 +----- src/drivers/PCI/USB/USBFunction.h | 4 ++-- src/drivers/PCI/USB/USB_hubs/RootHub.cpp | 0 src/drivers/PCI/USB/USB_hubs/RootHub.h | 17 +++++++++++++++++ src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h | 10 ++++++---- src/drivers/PCI/USB/USB_hubs/USBHub.cpp | 1 - src/drivers/PCI/USB/USB_hubs/USBHubAbstract.cpp | 1 + .../USB/USB_hubs/{USBHub.h => USBHubAbstract.h} | 16 +++++----------- src/drivers/PCI/USB/USB_hubs/makefile | 2 +- 10 files changed, 35 insertions(+), 26 deletions(-) create mode 100644 src/drivers/PCI/USB/USB_hubs/RootHub.cpp create mode 100644 src/drivers/PCI/USB/USB_hubs/RootHub.h delete mode 100644 src/drivers/PCI/USB/USB_hubs/USBHub.cpp create mode 100644 src/drivers/PCI/USB/USB_hubs/USBHubAbstract.cpp rename src/drivers/PCI/USB/USB_hubs/{USBHub.h => USBHubAbstract.h} (50%) diff --git a/src/drivers/PCI/USB/USB.cpp b/src/drivers/PCI/USB/USB.cpp index a5293b56f..149375a72 100644 --- a/src/drivers/PCI/USB/USB.cpp +++ b/src/drivers/PCI/USB/USB.cpp @@ -9,12 +9,12 @@ #include "drivers/PCI/PCI.h" #include "hostController/USBHostController.h" #include "hostController/USBEHCIController.h" -#include "USB_hubs/USBHub.h" +#include "USB_hubs/RootHub.h" #include "USB_hubs/USBEHCIRootHub.h" USBHostController* usbControllers[3]; -USBHub* testRoot; +USBRootHub* testRoot; void USBInit(){ memSet(usbControllers, 3*sizeof(USBHostController*), 0); diff --git a/src/drivers/PCI/USB/USBFunction.cpp b/src/drivers/PCI/USB/USBFunction.cpp index 3348cec92..31f4054a3 100644 --- a/src/drivers/PCI/USB/USBFunction.cpp +++ b/src/drivers/PCI/USB/USBFunction.cpp @@ -4,11 +4,7 @@ USBFunction::USBFunction(){ } -USBFunction::USBFunction(USBHub hub){ - //find out about device - //wait 100MS - //enable port - //send reset for > 50MS +USBFunction::USBFunction(USBHubAbstract* hub){ //address device //read max data payload //read configs diff --git a/src/drivers/PCI/USB/USBFunction.h b/src/drivers/PCI/USB/USBFunction.h index e3c661739..b5e78ba87 100644 --- a/src/drivers/PCI/USB/USBFunction.h +++ b/src/drivers/PCI/USB/USBFunction.h @@ -3,7 +3,7 @@ #include "drivers/generic/Device.h" #include "hostController/USBHostController.h" -#include "USB_hubs/USBHub.h" +#include "USB_hubs/USBHubAbstract.h" #include "USBConfiguration.h" @@ -18,7 +18,7 @@ class USBFunction :public Device{ USBHostController _host; public: USBFunction(); - USBFunction(USBHub hub); + USBFunction(USBHubAbstract* hub); }; diff --git a/src/drivers/PCI/USB/USB_hubs/RootHub.cpp b/src/drivers/PCI/USB/USB_hubs/RootHub.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/drivers/PCI/USB/USB_hubs/RootHub.h b/src/drivers/PCI/USB/USB_hubs/RootHub.h new file mode 100644 index 000000000..80ae529e5 --- /dev/null +++ b/src/drivers/PCI/USB/USB_hubs/RootHub.h @@ -0,0 +1,17 @@ +#ifndef ROOT_HUB_H_ +#define ROOT_HUB_H_ + +#include "Global.h" +#include "USBHubAbstract.h" + +class USBRootHub: public USBHubAbstract{ + public: + USBRootHub():USBHubAbstract(){ + + } + USBRootHub(USBHostController* host): USBHubAbstract(host){ + + } +}; + +#endif \ No newline at end of file diff --git a/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h b/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h index ecd78e86b..38cc1cfab 100644 --- a/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h +++ b/src/drivers/PCI/USB/USB_hubs/USBEHCIRootHub.h @@ -2,20 +2,22 @@ #define USB_EHCI_ROOT_HUB_H_ #include "Global.h" -#include "USBHub.h" +#include "USBHubAbstract.h" #include "drivers/PCI/USB/hostController/USBEHCIController.h" #include "utils/printf/Printf.h" #include "Kernel.h" #include "memory/structures/PageTable.h" #include "drivers/timers/Sleep.h" -class USBEHCIRootHub : public USBHub { +#include "RootHub.h" + +class USBEHCIRootHub : public USBRootHub { private: EHCIPortStatCont* _ports; public: - USBEHCIRootHub():USBHub(){ + USBEHCIRootHub():USBRootHub(){ } - USBEHCIRootHub(USBEHCIController* host):USBHub(host, true){ + USBEHCIRootHub(USBEHCIController* host):USBRootHub((USBHostController*)host){ pageTable.page((void*)(((uint32_t)(((USBEHCIController*)_host)->caps()->capLeng ))+ 0x44), (void*)(((uint32_t)(((USBEHCIController*)_host)->caps()->capLeng ))+ 0x44), sizeof(EHCIPortStatCont) * ((USBEHCIController*)_host)->caps()->structParams.numOfPorts ); _ports = (EHCIPortStatCont*)(((uint32_t)(((USBEHCIController*)_host)->caps()->capLeng ))+ 0x44); //TODO add properly, CAPLENGTH (from host) + 44 diff --git a/src/drivers/PCI/USB/USB_hubs/USBHub.cpp b/src/drivers/PCI/USB/USB_hubs/USBHub.cpp deleted file mode 100644 index c11a9aa60..000000000 --- a/src/drivers/PCI/USB/USB_hubs/USBHub.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "USBHub.h" \ No newline at end of file diff --git a/src/drivers/PCI/USB/USB_hubs/USBHubAbstract.cpp b/src/drivers/PCI/USB/USB_hubs/USBHubAbstract.cpp new file mode 100644 index 000000000..70e93dad1 --- /dev/null +++ b/src/drivers/PCI/USB/USB_hubs/USBHubAbstract.cpp @@ -0,0 +1 @@ +#include "USBHubAbstract.h" \ No newline at end of file diff --git a/src/drivers/PCI/USB/USB_hubs/USBHub.h b/src/drivers/PCI/USB/USB_hubs/USBHubAbstract.h similarity index 50% rename from src/drivers/PCI/USB/USB_hubs/USBHub.h rename to src/drivers/PCI/USB/USB_hubs/USBHubAbstract.h index 5c2b15ca5..ead6f1823 100644 --- a/src/drivers/PCI/USB/USB_hubs/USBHub.h +++ b/src/drivers/PCI/USB/USB_hubs/USBHubAbstract.h @@ -8,25 +8,19 @@ #include "utils/printf/Printf.h" //TODO superclass -class USBHub :public SpecialDevice{ +class USBHubAbstract :public SpecialDevice{ protected: //TODO size int _portCount; USBHostController* _host; public: - USBHub(){ + USBHubAbstract():SpecialDevice(){ } - USBHub(USBHostController* host):_host(host){ - //TODO port count - } - USBHub(USBHostController* host, bool rootHubOnly):_host(host){ - (void) rootHubOnly; - - } - virtual void findDevices(){ - printf("Virtual funcs arent working"); + USBHubAbstract(USBHostController* host): _host(host){ + } + virtual void findDevices()=0; }; diff --git a/src/drivers/PCI/USB/USB_hubs/makefile b/src/drivers/PCI/USB/USB_hubs/makefile index dc4d29124..8eec6abc6 100644 --- a/src/drivers/PCI/USB/USB_hubs/makefile +++ b/src/drivers/PCI/USB/USB_hubs/makefile @@ -1,4 +1,4 @@ SUBDIRS = -OBS = USBHub.o USBEHCIRootHub.o +OBS = USBHubAbstract.o USBEHCIRootHub.o RootHub.o include ../../../../../makefile.inc \ No newline at end of file From 5f7358f121ed46d811328f62ebb15739d4d10943 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 21 May 2018 09:44:44 -0500 Subject: [PATCH 161/171] got rid of all old makefiles --- makefile.inc => makefile.inc.old | 0 makefile => makefile.old | 0 src/boot/{makefile => makefile.old} | 0 src/clib_misc/{makefile => makefile.old} | 0 src/drivers/PCI/PCI_devices/{makefile => makefile.old} | 0 src/drivers/PCI/USB/USB_hubs/{makefile => makefile.old} | 0 src/drivers/PCI/USB/hostController/{makefile => makefile.old} | 0 src/drivers/PCI/USB/{makefile => makefile.old} | 0 src/drivers/PCI/{makefile => makefile.old} | 0 src/drivers/TTY/{makefile => makefile.old} | 0 src/drivers/filesys/fat/fat12/{makefile => makefile.old} | 0 src/drivers/filesys/fat/{makefile => makefile.old} | 0 src/drivers/filesys/general/{makefile => makefile.old} | 0 src/drivers/filesys/{makefile => makefile.old} | 0 src/drivers/generic/{makefile => makefile.old} | 0 src/drivers/{makefile => makefile.old} | 0 src/drivers/timers/{makefile => makefile.old} | 0 src/interrupts/{makefile => makefile.old} | 0 src/{makefile => makefile.old} | 0 src/memory/alloc/{makefile => makefile.old} | 0 src/memory/{makefile => makefile.old} | 0 src/memory/structures/{makefile => makefile.old} | 0 src/multiboot_spec/{makefile => makefile.old} | 0 src/utils/linked_list/{makefile => makefile.old} | 0 src/utils/{makefile => makefile.old} | 0 src/utils/printf/{makefile => makefile.old} | 0 src/utils/string/{makefile => makefile.old} | 0 27 files changed, 0 insertions(+), 0 deletions(-) rename makefile.inc => makefile.inc.old (100%) rename makefile => makefile.old (100%) rename src/boot/{makefile => makefile.old} (100%) rename src/clib_misc/{makefile => makefile.old} (100%) rename src/drivers/PCI/PCI_devices/{makefile => makefile.old} (100%) rename src/drivers/PCI/USB/USB_hubs/{makefile => makefile.old} (100%) rename src/drivers/PCI/USB/hostController/{makefile => makefile.old} (100%) rename src/drivers/PCI/USB/{makefile => makefile.old} (100%) rename src/drivers/PCI/{makefile => makefile.old} (100%) rename src/drivers/TTY/{makefile => makefile.old} (100%) rename src/drivers/filesys/fat/fat12/{makefile => makefile.old} (100%) rename src/drivers/filesys/fat/{makefile => makefile.old} (100%) rename src/drivers/filesys/general/{makefile => makefile.old} (100%) rename src/drivers/filesys/{makefile => makefile.old} (100%) rename src/drivers/generic/{makefile => makefile.old} (100%) rename src/drivers/{makefile => makefile.old} (100%) rename src/drivers/timers/{makefile => makefile.old} (100%) rename src/interrupts/{makefile => makefile.old} (100%) rename src/{makefile => makefile.old} (100%) rename src/memory/alloc/{makefile => makefile.old} (100%) rename src/memory/{makefile => makefile.old} (100%) rename src/memory/structures/{makefile => makefile.old} (100%) rename src/multiboot_spec/{makefile => makefile.old} (100%) rename src/utils/linked_list/{makefile => makefile.old} (100%) rename src/utils/{makefile => makefile.old} (100%) rename src/utils/printf/{makefile => makefile.old} (100%) rename src/utils/string/{makefile => makefile.old} (100%) diff --git a/makefile.inc b/makefile.inc.old similarity index 100% rename from makefile.inc rename to makefile.inc.old diff --git a/makefile b/makefile.old similarity index 100% rename from makefile rename to makefile.old diff --git a/src/boot/makefile b/src/boot/makefile.old similarity index 100% rename from src/boot/makefile rename to src/boot/makefile.old diff --git a/src/clib_misc/makefile b/src/clib_misc/makefile.old similarity index 100% rename from src/clib_misc/makefile rename to src/clib_misc/makefile.old diff --git a/src/drivers/PCI/PCI_devices/makefile b/src/drivers/PCI/PCI_devices/makefile.old similarity index 100% rename from src/drivers/PCI/PCI_devices/makefile rename to src/drivers/PCI/PCI_devices/makefile.old diff --git a/src/drivers/PCI/USB/USB_hubs/makefile b/src/drivers/PCI/USB/USB_hubs/makefile.old similarity index 100% rename from src/drivers/PCI/USB/USB_hubs/makefile rename to src/drivers/PCI/USB/USB_hubs/makefile.old diff --git a/src/drivers/PCI/USB/hostController/makefile b/src/drivers/PCI/USB/hostController/makefile.old similarity index 100% rename from src/drivers/PCI/USB/hostController/makefile rename to src/drivers/PCI/USB/hostController/makefile.old diff --git a/src/drivers/PCI/USB/makefile b/src/drivers/PCI/USB/makefile.old similarity index 100% rename from src/drivers/PCI/USB/makefile rename to src/drivers/PCI/USB/makefile.old diff --git a/src/drivers/PCI/makefile b/src/drivers/PCI/makefile.old similarity index 100% rename from src/drivers/PCI/makefile rename to src/drivers/PCI/makefile.old diff --git a/src/drivers/TTY/makefile b/src/drivers/TTY/makefile.old similarity index 100% rename from src/drivers/TTY/makefile rename to src/drivers/TTY/makefile.old diff --git a/src/drivers/filesys/fat/fat12/makefile b/src/drivers/filesys/fat/fat12/makefile.old similarity index 100% rename from src/drivers/filesys/fat/fat12/makefile rename to src/drivers/filesys/fat/fat12/makefile.old diff --git a/src/drivers/filesys/fat/makefile b/src/drivers/filesys/fat/makefile.old similarity index 100% rename from src/drivers/filesys/fat/makefile rename to src/drivers/filesys/fat/makefile.old diff --git a/src/drivers/filesys/general/makefile b/src/drivers/filesys/general/makefile.old similarity index 100% rename from src/drivers/filesys/general/makefile rename to src/drivers/filesys/general/makefile.old diff --git a/src/drivers/filesys/makefile b/src/drivers/filesys/makefile.old similarity index 100% rename from src/drivers/filesys/makefile rename to src/drivers/filesys/makefile.old diff --git a/src/drivers/generic/makefile b/src/drivers/generic/makefile.old similarity index 100% rename from src/drivers/generic/makefile rename to src/drivers/generic/makefile.old diff --git a/src/drivers/makefile b/src/drivers/makefile.old similarity index 100% rename from src/drivers/makefile rename to src/drivers/makefile.old diff --git a/src/drivers/timers/makefile b/src/drivers/timers/makefile.old similarity index 100% rename from src/drivers/timers/makefile rename to src/drivers/timers/makefile.old diff --git a/src/interrupts/makefile b/src/interrupts/makefile.old similarity index 100% rename from src/interrupts/makefile rename to src/interrupts/makefile.old diff --git a/src/makefile b/src/makefile.old similarity index 100% rename from src/makefile rename to src/makefile.old diff --git a/src/memory/alloc/makefile b/src/memory/alloc/makefile.old similarity index 100% rename from src/memory/alloc/makefile rename to src/memory/alloc/makefile.old diff --git a/src/memory/makefile b/src/memory/makefile.old similarity index 100% rename from src/memory/makefile rename to src/memory/makefile.old diff --git a/src/memory/structures/makefile b/src/memory/structures/makefile.old similarity index 100% rename from src/memory/structures/makefile rename to src/memory/structures/makefile.old diff --git a/src/multiboot_spec/makefile b/src/multiboot_spec/makefile.old similarity index 100% rename from src/multiboot_spec/makefile rename to src/multiboot_spec/makefile.old diff --git a/src/utils/linked_list/makefile b/src/utils/linked_list/makefile.old similarity index 100% rename from src/utils/linked_list/makefile rename to src/utils/linked_list/makefile.old diff --git a/src/utils/makefile b/src/utils/makefile.old similarity index 100% rename from src/utils/makefile rename to src/utils/makefile.old diff --git a/src/utils/printf/makefile b/src/utils/printf/makefile.old similarity index 100% rename from src/utils/printf/makefile rename to src/utils/printf/makefile.old diff --git a/src/utils/string/makefile b/src/utils/string/makefile.old similarity index 100% rename from src/utils/string/makefile rename to src/utils/string/makefile.old From 8392b94bbc4f7538a6c7a008f2eff601f1240a6a Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 21 May 2018 10:49:03 -0500 Subject: [PATCH 162/171] improved makefile needs some cleanup --- makefile | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 makefile diff --git a/makefile b/makefile new file mode 100644 index 000000000..740c762e1 --- /dev/null +++ b/makefile @@ -0,0 +1,126 @@ +TOPDIR = $(shell git rev-parse --show-toplevel) +SRCDIR = src + +NAME = ExOS +BIN_NAME = kernel.bin +VERSION = 0.0.1A +FULL_NAME = $(NAME)-$(VERSION) + + +COMMIT = $(shell git log -n 1 --format="%h") + + +SRC_SUBDIRS = $(shell find $(SRCDIR) -type d -print) +C_SRC_FILES = $(foreach dir, $(SRC_SUBDIRS), $(wildcard $(dir)/*.c)) +CPP_SRC_FILES = $(foreach dir, $(SRC_SUBDIRS), $(wildcard $(dir)/*.cpp)) +SPECIAL_SRC_FILES = Boot.s ISRWrapper.s +OBJDIR = .build +OBJFILES = $(patsubst %.c,$(OBJDIR)/%.o,$(C_SRC_FILES)) \ +$(patsubst %.cpp,$(OBJDIR)/%.o,$(CPP_SRC_FILES)) \ +$(OBJDIR)/Boot.o $(OBJDIR)/ISRWrapper.o + + +AS = i686-elf-as +GPP = i686-elf-g++ +GCC = i686-elf-gcc + +MKDIR = mkdir --parents + +INCLUDES = -I$(TOPDIR)/src +LDFLAGS = -T $(TOPDIR)/linker.ld -ffreestanding -O2 -fno-rtti -fno-exceptions -nostartfiles -nostdlib -lgcc +CFLAGS = -c -ffreestanding -O2 -Wno-packed-bitfield-compat -Wall -Wextra -fno-rtti -fno-exceptions -g -std=gnu++14 $(INCLUDES) + +# Text Coloring +RED = $$(tput setaf 1) +BLUE = $$(tput setaf 4) +GREEN = $$(tput setaf 2) +WHITE = $$(tput setaf 7) +YELLOW = $$(tput setaf 3) + +# Text Weighting +BOLD = $$(tput bold) +NORMAL = $$(tput sgr0) + +TIMESTAMP = $(shell date +'%Y%m%d.%H%M') + +ifeq ($(VERBOSE), yes) +RUN = +else +RUN = @ +VERBOSE = no +endif + +HOSTTYPE := $(shell uname -s) + +ifdef MAKECMDGOALS +TARGETGOAL += $(MAKECMDGOALS) +else +TARGETGOAL = $(.DEFAULT_GOAL) +endif + + +all: config $(BIN_NAME) + +warning: + ifeq ($(VERBOSE),no) + @echo + @echo 'For a more verbose output' + @echo ' make '$(GREEN)'VERBOSE=yes' $(NORMAL)$(TARGETGOAL) + @echo + endif + +config: + @echo + @echo 'TARGET' $(TARGETGOAL) + @echo 'VERBOSE' $(VERBOSE) + @echo + @echo 'VERSION ' $(VERSION) + @echo 'COMMIT '$(COMMIT) + @echo 'DATE ' $(TIMESTAMP) + @echo 'HOST ' $(HOSTTYPE) + +clean: + rm -rf $(OBJDIR) + rm $(BIN_NAME) + +$(BIN_NAME): $(OBJFILES) +ifeq ($(VERBOSE),no) + @echo 'Constructing' $(RED)$@$(NORMAL) +else + @echo +endif + $(RUN)$(GCC) -T $(TOPDIR)/linker.ld -o '$@' -ffreestanding -O2 -fno-rtti -fno-exceptions -nostartfiles -nostdlib $(OBJFILES) -lgcc + @#$(RUN)$(GCC) $(LDFLAGS) -o '$@' $(OBJFILES) $(INCLUDES) + + +$(OBJDIR)/%.o: %.c +ifeq ($(VERBOSE),no) + @echo 'Building' $(YELLOW)$<$(NORMAL) +endif + @test -d $(OBJDIR)/$(dir $<) || $(MKDIR) $(OBJDIR)/$(dir $<) + $(RUN)$(GPP) -o '$@' $(CFLAGS) "$<" + +$(OBJDIR)/%.o: %.cpp +ifeq ($(VERBOSE),no) + @echo 'Building' $(YELLOW)$<$(NORMAL) +endif + @test -d $(OBJDIR)/$(dir $<) || $(MKDIR) $(OBJDIR)/$(dir $<) + $(RUN)$(GPP) -o '$@' $(CFLAGS) "$<" + +$(OBJDIR)/Boot.o: $(TOPDIR)/src/boot/Boot.s +ifeq ($(VERBOSE),no) + @echo 'Building' $(YELLOW)$<$(NORMAL) +endif + @test -d $(OBJDIR)/$(dir $<) || $(MKDIR) $(OBJDIR)/$(dir $<) + $(RUN)nasm $(TOPDIR)/src/boot/Boot.s -felf -o $(OBJDIR)/Boot.o + + +$(OBJDIR)/ISRWrapper.o: $(TOPDIR)/src/interrupts/ISRWrapper.s +ifeq ($(VERBOSE),no) + @echo 'Building' $(YELLOW)$<$(NORMAL) +endif + @test -d $(OBJDIR)/$(dir $<) || $(MKDIR) $(OBJDIR)/$(dir $<) + $(RUN)$(AS) $(TOPDIR)/src/interrupts/ISRWrapper.s -o $(OBJDIR)/ISRWrapper.o + +.PHONY: all warning config clean + From 20fa32dbcbb5f72037a1ea12fe1daa69a8da77ab Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 21 May 2018 12:06:57 -0500 Subject: [PATCH 163/171] cleaned up makefile --- makefile | 118 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 61 insertions(+), 57 deletions(-) diff --git a/makefile b/makefile index 740c762e1..e94ab3fd5 100644 --- a/makefile +++ b/makefile @@ -1,73 +1,73 @@ -TOPDIR = $(shell git rev-parse --show-toplevel) -SRCDIR = src - -NAME = ExOS -BIN_NAME = kernel.bin -VERSION = 0.0.1A +#name and versioning +NAME = ExOS +BIN_NAME = kernel.bin +VERSION = 0.0.1A FULL_NAME = $(NAME)-$(VERSION) +COMMIT = $(shell git log -n 1 --format="%h") +TIMESTAMP = $(shell date +'%Y%m%d.%H%M') +#top level dirs +TOPDIR = $(shell git rev-parse --show-toplevel) +SRCDIR = src +OBJDIR = .build -COMMIT = $(shell git log -n 1 --format="%h") - - -SRC_SUBDIRS = $(shell find $(SRCDIR) -type d -print) -C_SRC_FILES = $(foreach dir, $(SRC_SUBDIRS), $(wildcard $(dir)/*.c)) -CPP_SRC_FILES = $(foreach dir, $(SRC_SUBDIRS), $(wildcard $(dir)/*.cpp)) +#source files and dirs +SRC_SUBDIRS = $(shell find $(SRCDIR) -type d -print) +C_SRC_FILES = $(foreach dir, $(SRC_SUBDIRS), $(wildcard $(dir)/*.c)) +CPP_SRC_FILES = $(foreach dir, $(SRC_SUBDIRS), $(wildcard $(dir)/*.cpp)) SPECIAL_SRC_FILES = Boot.s ISRWrapper.s -OBJDIR = .build + +#object files OBJFILES = $(patsubst %.c,$(OBJDIR)/%.o,$(C_SRC_FILES)) \ $(patsubst %.cpp,$(OBJDIR)/%.o,$(CPP_SRC_FILES)) \ $(OBJDIR)/Boot.o $(OBJDIR)/ISRWrapper.o +#programs +AS = i686-elf-as +GPP = i686-elf-g++ +GCC = i686-elf-gcc +MKDIR = mkdir --parents -AS = i686-elf-as -GPP = i686-elf-g++ -GCC = i686-elf-gcc - -MKDIR = mkdir --parents - +#flags INCLUDES = -I$(TOPDIR)/src -LDFLAGS = -T $(TOPDIR)/linker.ld -ffreestanding -O2 -fno-rtti -fno-exceptions -nostartfiles -nostdlib -lgcc -CFLAGS = -c -ffreestanding -O2 -Wno-packed-bitfield-compat -Wall -Wextra -fno-rtti -fno-exceptions -g -std=gnu++14 $(INCLUDES) - -# Text Coloring -RED = $$(tput setaf 1) -BLUE = $$(tput setaf 4) -GREEN = $$(tput setaf 2) -WHITE = $$(tput setaf 7) -YELLOW = $$(tput setaf 3) - -# Text Weighting -BOLD = $$(tput bold) -NORMAL = $$(tput sgr0) - -TIMESTAMP = $(shell date +'%Y%m%d.%H%M') - +LDFLAGS = -ffreestanding -O2 -fno-rtti -fno-exceptions -nostartfiles -nostdlib -lgcc +CFLAGS = -c -ffreestanding -O2 -Wno-packed-bitfield-compat -Wall -Wextra -fno-rtti -fno-exceptions -g -std=gnu++14 $(INCLUDES) + +#Text minip +RED = $$(tput setaf 1) +BLUE = $$(tput setaf 4) +GREEN = $$(tput setaf 2) +WHITE = $$(tput setaf 7) +YELLOW = $$(tput setaf 3) +BOLD = $$(tput bold) +NORMAL = $$(tput sgr0) + +#verbose option ifeq ($(VERBOSE), yes) -RUN = +RUN = else -RUN = @ -VERBOSE = no +RUN = @ +VERBOSE = no endif -HOSTTYPE := $(shell uname -s) - +#general info +HOSTTYPE = $(shell uname -s) ifdef MAKECMDGOALS -TARGETGOAL += $(MAKECMDGOALS) +TARGETGOAL = $(MAKECMDGOALS) else -TARGETGOAL = $(.DEFAULT_GOAL) +TARGETGOAL = $(.DEFAULT_GOAL) endif -all: config $(BIN_NAME) +all: warning config $(BIN_NAME) finish warning: - ifeq ($(VERBOSE),no) - @echo - @echo 'For a more verbose output' - @echo ' make '$(GREEN)'VERBOSE=yes' $(NORMAL)$(TARGETGOAL) - @echo - endif +ifeq ($(VERBOSE),no) + @echo + @echo 'For a more verbose output' + @echo ' make '$(GREEN)'VERBOSE=yes' $(NORMAL)$(TARGETGOAL) + @echo +endif config: @echo @@ -78,21 +78,16 @@ config: @echo 'COMMIT '$(COMMIT) @echo 'DATE ' $(TIMESTAMP) @echo 'HOST ' $(HOSTTYPE) - -clean: - rm -rf $(OBJDIR) - rm $(BIN_NAME) + @echo $(BIN_NAME): $(OBJFILES) ifeq ($(VERBOSE),no) @echo 'Constructing' $(RED)$@$(NORMAL) -else - @echo endif $(RUN)$(GCC) -T $(TOPDIR)/linker.ld -o '$@' -ffreestanding -O2 -fno-rtti -fno-exceptions -nostartfiles -nostdlib $(OBJFILES) -lgcc @#$(RUN)$(GCC) $(LDFLAGS) -o '$@' $(OBJFILES) $(INCLUDES) - +#general rules $(OBJDIR)/%.o: %.c ifeq ($(VERBOSE),no) @echo 'Building' $(YELLOW)$<$(NORMAL) @@ -107,6 +102,8 @@ endif @test -d $(OBJDIR)/$(dir $<) || $(MKDIR) $(OBJDIR)/$(dir $<) $(RUN)$(GPP) -o '$@' $(CFLAGS) "$<" + +#special rules $(OBJDIR)/Boot.o: $(TOPDIR)/src/boot/Boot.s ifeq ($(VERBOSE),no) @echo 'Building' $(YELLOW)$<$(NORMAL) @@ -122,5 +119,12 @@ endif @test -d $(OBJDIR)/$(dir $<) || $(MKDIR) $(OBJDIR)/$(dir $<) $(RUN)$(AS) $(TOPDIR)/src/interrupts/ISRWrapper.s -o $(OBJDIR)/ISRWrapper.o -.PHONY: all warning config clean +finish: + @echo 'Finished' $(BOLD)$(GREEN)$(TARGETGOAL)$(NORMAL) +clean: + $(RUN)rm -rf $(OBJDIR) + $(RUN)rm $(BIN_NAME) + @echo 'Finished' $(BOLD)$(GREEN)$(TARGETGOAL)$(NORMAL) + +.PHONY: all warning config clean finish \ No newline at end of file From fed9fc07932f60ac0d960a82a8a7be038f7b8488 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 21 May 2018 12:14:50 -0500 Subject: [PATCH 164/171] fixed link command --- makefile | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/makefile b/makefile index e94ab3fd5..de33da174 100644 --- a/makefile +++ b/makefile @@ -16,11 +16,12 @@ SRC_SUBDIRS = $(shell find $(SRCDIR) -type d -print) C_SRC_FILES = $(foreach dir, $(SRC_SUBDIRS), $(wildcard $(dir)/*.c)) CPP_SRC_FILES = $(foreach dir, $(SRC_SUBDIRS), $(wildcard $(dir)/*.cpp)) SPECIAL_SRC_FILES = Boot.s ISRWrapper.s +LINKER_FILE = $(TOPDIR)/linker.ld #object files OBJFILES = $(patsubst %.c,$(OBJDIR)/%.o,$(C_SRC_FILES)) \ -$(patsubst %.cpp,$(OBJDIR)/%.o,$(CPP_SRC_FILES)) \ -$(OBJDIR)/Boot.o $(OBJDIR)/ISRWrapper.o + $(patsubst %.cpp,$(OBJDIR)/%.o,$(CPP_SRC_FILES)) \ + $(OBJDIR)/Boot.o $(OBJDIR)/ISRWrapper.o #programs AS = i686-elf-as @@ -30,8 +31,9 @@ MKDIR = mkdir --parents #flags INCLUDES = -I$(TOPDIR)/src -LDFLAGS = -ffreestanding -O2 -fno-rtti -fno-exceptions -nostartfiles -nostdlib -lgcc +LDFLAGS = -ffreestanding -O2 -fno-rtti -fno-exceptions -nostartfiles -nostdlib $(INCLUDES) -lgcc CFLAGS = -c -ffreestanding -O2 -Wno-packed-bitfield-compat -Wall -Wextra -fno-rtti -fno-exceptions -g -std=gnu++14 $(INCLUDES) +LINK = -lgcc #Text minip RED = $$(tput setaf 1) @@ -84,8 +86,7 @@ $(BIN_NAME): $(OBJFILES) ifeq ($(VERBOSE),no) @echo 'Constructing' $(RED)$@$(NORMAL) endif - $(RUN)$(GCC) -T $(TOPDIR)/linker.ld -o '$@' -ffreestanding -O2 -fno-rtti -fno-exceptions -nostartfiles -nostdlib $(OBJFILES) -lgcc - @#$(RUN)$(GCC) $(LDFLAGS) -o '$@' $(OBJFILES) $(INCLUDES) + $(RUN)$(GCC) -T $(LINKER_FILE) -o '$@' $(LDFLAGS) $(OBJFILES) $(LINK) #general rules $(OBJDIR)/%.o: %.c From 5c175be9d8b6276334e2b67dfcc44251b3a490da Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 21 May 2018 12:16:48 -0500 Subject: [PATCH 165/171] trimed line length --- makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/makefile b/makefile index de33da174..dfb8574fe 100644 --- a/makefile +++ b/makefile @@ -31,8 +31,10 @@ MKDIR = mkdir --parents #flags INCLUDES = -I$(TOPDIR)/src -LDFLAGS = -ffreestanding -O2 -fno-rtti -fno-exceptions -nostartfiles -nostdlib $(INCLUDES) -lgcc -CFLAGS = -c -ffreestanding -O2 -Wno-packed-bitfield-compat -Wall -Wextra -fno-rtti -fno-exceptions -g -std=gnu++14 $(INCLUDES) +LDFLAGS = -ffreestanding -O2 -fno-rtti -fno-exceptions -nostartfiles \ + -nostdlib +CFLAGS = -c -ffreestanding -O2 -Wno-packed-bitfield-compat -Wall -Wextra \ + -fno-rtti -fno-exceptions -g -std=gnu++14 $(INCLUDES) LINK = -lgcc #Text minip From d957b22f037075cc3204e73a61b183057ec13f7d Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sun, 26 Aug 2018 17:23:34 -0500 Subject: [PATCH 166/171] Update README.MD --- README.MD | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/README.MD b/README.MD index 20ad20469..e9bcd6ba2 100755 --- a/README.MD +++ b/README.MD @@ -15,16 +15,9 @@ ExOS extends the [MIT exokernel](https://pdos.csail.mit.edu/archive/exo/) by rem ## Short term work * Garrett - - [x] Read USB spec - still going, its long - - [ ] USB abstract class - - [ ] OHCI driver - - [ ] UHCI driver - - [x] EHCI driver - mostly, still may have some issues with the root hub - - [ ] XHCI driver - -* Oskari - - [ ] Floppy drive driver - + - [x] read multiboot 2 system information (MB2I) + - [ ] read the new memory map format + - [ ] make sure MB2I structures are protected from paging ## Long term work * Load files from floppy drives @@ -80,12 +73,10 @@ If you can't code theres still stuff for you. If you can write our readme or wik * If you're contributing ***please test on real hardware*** not just an emulator. 3. Set up a ***multiboot compliant*** bootloader * I'm using [grub legacy](http://wiki.osdev.org/GRUB_Legacy) as my bootloader but you can use whatever as long as it's ***multiboot compliant***. - * I'm not 100% sure that all of them work the more i look into it. I will try grub and see. + * I'm not 100% sure that all of them work the more I look into it. I will try grub and see. + * A new branch has been started to move to multiboot2 and modern grub. be prepared to change. 4. Test the bootloader installation * Just boot to the bootloader's menu screen to make sure it works. -5. Configure the makefile (makefile.inc) - * Assumes that the compiler toolchain (i686-elf-*) is in the path. The floppy drive output is hardcoded based on who used the makefile last. - * Will possibly be fixed in the future. You must manually change them to match your system for now. ## Compilation From bd3e4c9af2088a6484351e615279d53059b63465 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Thu, 20 Sep 2018 09:21:14 -0500 Subject: [PATCH 167/171] Delete CODE_OF_CONDUCT.md --- CODE_OF_CONDUCT.md | 47 ---------------------------------------------- 1 file changed, 47 deletions(-) delete mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index cef8465c6..000000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,47 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members -***Note that mild NSFW language is allowed*** - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at exos@garrettbattaglia.info. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] - -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ From 767eb5093208a879ce19e0d890b7972e416c4242 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Tue, 30 Oct 2018 14:46:51 -0500 Subject: [PATCH 168/171] Update README.MD --- README.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.MD b/README.MD index e9bcd6ba2..7514fde8c 100755 --- a/README.MD +++ b/README.MD @@ -51,7 +51,7 @@ ExOS extends the [MIT exokernel](https://pdos.csail.mit.edu/archive/exo/) by rem ### Contacting us * [slack](https://join.slack.com/t/exos-dev/shared_invite/enQtMjI2OTE2NjYzOTU4LTJhZTIyOTNkYmY2MjcxN2RjZTUzZjhkYTAzZTNlOThkODZkZmE5ODI3ODA0MjBlNDY3Mjg3OWNjODQ0ZGM3NDU) * Email - * Garrett: exos@garrettbattaglia.info + * Garrett: garrett@garrettbattaglia.com * Oskari: xxc3ncoredxx@gmail.com (the typo is intentional) ### But, what can ***I*** do??? From 98448418606accd1d855368e0da9a2c966120409 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sat, 8 Dec 2018 19:37:46 -0600 Subject: [PATCH 169/171] fixed multiboot header --- linker.ld | 1 + src/boot/Boot.s | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/linker.ld b/linker.ld index fd0f5913c..2f1176d40 100755 --- a/linker.ld +++ b/linker.ld @@ -10,6 +10,7 @@ SECTIONS { kernelStart = .; .text : AT(ADDR(.text) - 0xC0000000) { + *(.multiboot) *(.text) *(.rodata*) } diff --git a/src/boot/Boot.s b/src/boot/Boot.s index 5603993d9..7cf9ac3b0 100755 --- a/src/boot/Boot.s +++ b/src/boot/Boot.s @@ -37,14 +37,16 @@ BootPageDirectory: dd 0x00C00083 times (1024 - KERNEL_PAGE_NUMBER - 2) dd 0 ; Pages after the kernel image. - -section .text +section .multiboot align 4 MultiBootHeader: dd MAGIC dd FLAGS dd CHECKSUM - + + +section .text +align 4 ; reserve initial kernel stack space -- that's 16k. STACKSIZE equ 0x4000 From bf71c5c9b105e48c9e509ee1baf860edeb8e0fc4 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Sun, 9 Dec 2018 12:52:55 -0600 Subject: [PATCH 170/171] fixed loading --- .bochsrc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.bochsrc b/.bochsrc index e0db481a2..71a3a1087 100644 --- a/.bochsrc +++ b/.bochsrc @@ -1,6 +1,6 @@ # configuration file generated by Bochs -plugin_ctrl: unmapped=true, biosdev=true, speaker=true, extfpuirq=true, parallel=true, serial=true, iodebug=1, gameport=true, usb_ehci=true +#plugin_ctrl: unmapped=true, biosdev=true, speaker=true, extfpuirq=true, parallel=true, serial=true, iodebug=1, gameport=true, usb_ehci=true config_interface: textconfig display_library: x, options="gui_debug" memory: host=32, guest=32 @@ -8,7 +8,7 @@ romimage: file="/usr/share/bochs/BIOS-bochs-latest", address=0x00000000, options vgaromimage: file="/usr/share/bochs/VGABIOS-lgpl-latest" boot: floppy floppy_bootsig_check: disabled=0 -floppya: type=1_44, 1_44="/dev/sdc", status=inserted, write_protected=0 +floppya: type=1_44, 1_44="/dev/sdd", status=inserted, write_protected=0 # no floppyb ata0: enabled=true, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 ata0-master: type=none @@ -55,4 +55,4 @@ com1: enabled=true, mode=null com2: enabled=false com3: enabled=false com4: enabled=false -usb_ehci: enabled=1, port1=none, options1=none, port2=none, options2=none, port3=none, options3=none, port4=none, options4=none, port5=none, options5=none, port6=none, options6=none +#usb_ehci: enabled=1, port1=none, options1=none, port2=none, options2=none, port3=none, options3=none, port4=none, options4=none, port5=none, options5=none, port6=none, options6=none From 438af284dc87023b6ccd7b8def5c2d303951c701 Mon Sep 17 00:00:00 2001 From: Garrett Battaglia Date: Mon, 15 Apr 2019 10:18:52 -0500 Subject: [PATCH 171/171] Update README.MD --- README.MD | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.MD b/README.MD index 7514fde8c..940c45845 100755 --- a/README.MD +++ b/README.MD @@ -14,10 +14,13 @@ ExOS extends the [MIT exokernel](https://pdos.csail.mit.edu/archive/exo/) by rem * Live relinking to allow unmodified programs to be run ## Short term work -* Garrett - - [x] read multiboot 2 system information (MB2I) - - [ ] read the new memory map format - - [ ] make sure MB2I structures are protected from paging +* Garrett - in driver_bundle branch + - [x] Define driver bundle format + - [x] read grub (multiboot) module format + - [ ] parse driver bundle + - [ ] load drivers from bundle + - [ ] init drivers + - [ ] enumerate devices ## Long term work * Load files from floppy drives