Skip to content

Commit

Permalink
Style Corrections for system
Browse files Browse the repository at this point in the history
  • Loading branch information
maxtyson123 committed Jan 5, 2024
1 parent 39a9b9c commit 5aacd15
Show file tree
Hide file tree
Showing 20 changed files with 327 additions and 777 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ Kernel Cleanup
- [x] Cross-Compiler
- [x] Better Scripts
- [x] GUI Bug Fixes
- [ ] Better Commenting and Doxygen Documentation
- [ ] Use better c++ coding conventions
- [x] Better Commenting and Doxygen Documentation
- [x] Use better c++ coding conventions
- [ ] CMAKE Build System (and maybe get it building and debugging in CLion)
- [ ] Clean up all the TODOs
- [ ] Rewrite Readme
Expand Down
22 changes: 11 additions & 11 deletions docs/Notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ These are my notes relative to various parts of the OS
+ [Data Send and Receive](#data-send-and-receive)
+ [Interrupts](#interrupts)
+ [Peripheral Component Interconnect (PCI)](#peripheral-component-interconnect-pci)
+ [Base Address Registers](#base-address-registers)
+ [base Address Registers](#base-address-registers)
+ [RTC Timer](#rtc-timer)
- [Files And Drives](#files-and-drives)
+ [Hard-drives](#hard-drives)
Expand All @@ -19,7 +19,7 @@ These are my notes relative to various parts of the OS
+ [GUI - Framework](#gui-framework)
- [System Stuff](#system-stuff)
+ [Multitasking](#multitasking)
+ [Threads](#threads)
+ [m_threads](#threads)
+ [Dynamic Memory Management / Heap](#dynamic-memory-management-heap)
+ [System Calls](#system-calls)
- [Networking](#networking)
Expand Down Expand Up @@ -103,15 +103,15 @@ This relates to "pci.cpp", See also [PCI](https://www.lowlevel.eu/wiki/Periphera
- The PCI controller will also tell more general information such as class and subclass IDs, which are useful for compatibility modes
- Once the PCI driver is set up then it becomes easy to extend the OS as in future all that needs to be done is to get the device ID and write drivers for them
<!-- TOC --><a name="base-address-registers"></a>
### Base Address Registers
- The solution for having multiple PCI devices (two GPUS, two screens etc…) is to have a Base Address Registers (BAR)
- Base address registers are registers in the PCI configuration space, which in a more simple way is just storing the address of a PCI device in memory
### base Address Registers
- The solution for having multiple PCI devices (two GPUS, two screens etc…) is to have a base Address Registers (BAR)
- base address registers are registers in the PCI configuration space, which in a more simple way is just storing the address of a PCI device in memory
- There are two types of BARs, one is the I/O BAR, this is for devices that communicate bit by bit e.g. mouse where the m_position is read from the port each interrupt
- The I/O base address register is 4 bytes long:
- - Lowest bit: Type Of register: (I/O bit = 1)
- - Second-lowest bit: Reserved
- - Bits 3 - 16: Port Number (MUST BE MULTIPLE OF 4)
- Memory mapping is another type of BAR, this one is where the device takes x memory location, and to communicate with it just write/read from that location in memory. This is better performance-wise as the CPU can do other tasks while that is updating in the m_background
- Memory mapping is another type of BAR, this one is where the device takes x memory location, and to communicate with it just write/read from that location in memory. This is better performance-wise as the CPU can do other m_tasks while that is updating in the m_background
- The Memory Mapping BAR is 4 bytes long:
- - Lowest Bit: Type Of register: (MemMap bit = 0)
- - Second and third: (00 = 32bit BAR) or (01 = 20bit BAR) or (10 = 64bit BAR)
Expand Down Expand Up @@ -313,16 +313,16 @@ See also [Stack](https://wiki.osdev.org/Stack), **Note this needs better explain
- - Kernel will then execute the new task instead of executing function "X"
- To schedule processes fairly, a round-robin scheduler generally employs time-sharing, giving each job a time slot or quantum (its allowance of CPU time), and interrupting the job if it is not completed by then. The job is resumed next time a time slot is assigned to that task. If the task terminates or changes its state to waiting during its attributed time quantum, the scheduler selects the m_first_memory_chunk task in the ready queue to execute
<!-- TOC --><a name="threads"></a>
### Threads
### m_threads
See also: [Thread](https://wiki.osdev.org/Thread)
- A thread is a lightweight process. It is a sequence of instructions within a program that can be executed independently of other code. Threads can be created and managed by a thread library.
- Threads are often used in parallel computing, where they can be used to perform multiple tasks simultaneously. Threads are also used in multimedia, where they can be used to perform different tasks in real time. For example, a thread can be used to play a sound while another thread is used to display a graphic.
- Threads are also used in operating systems, where they can be used to perform different tasks simultaneously. For example, a thread can be used to play a sound while another thread is used to display a graphic.
- A thread is a lightweight process. It is a sequence of instructions within a program that can be executed independently of other code. m_threads can be created and managed by a thread library.
- m_threads are often used in parallel computing, where they can be used to perform multiple m_tasks simultaneously. m_threads are also used in multimedia, where they can be used to perform different m_tasks in real time. For example, a thread can be used to play a sound while another thread is used to display a graphic.
- m_threads are also used in operating systems, where they can be used to perform different m_tasks simultaneously. For example, a thread can be used to play a sound while another thread is used to display a graphic.
- The main difference between a thread and a process is that threads share the same address space, while processes have separate address spaces. This means that threads can share data and code, while processes cannot. This also means that threads are faster than processes, because they do not need to be loaded into memory.
- To implement threads in the OS, the kernel will have to implement a thread class. This class will have a function to create a thread, and a function to execute the thread. The thread class will also have a function to get the current thread.
- The thread class will also have a function to get the current thread. This function will be used to get the current thread, and then the thread will be able to access its own stack.
- Yeilding is when a thread gives up its time slice and allows another thread to run. This is done by calling the yeild function on the thread class.
- Processes and threads are different. A process is a program in execution. A thread is a component of a process. A process can have multiple threads. Threads are often used to implement concurrency within a process. Threads are also used to implement parallelism, where multiple processes can run simultaneously on a multi-core processor.
- Processes and threads are different. A process is a program in execution. A thread is a component of a process. A process can have multiple threads. m_threads are often used to implement concurrency within a process. m_threads are also used to implement parallelism, where multiple processes can run simultaneously on a multi-core processor.
<!-- TOC --><a name="dynamic-memory-management-heap"></a>
### Dynamic Memory Management / Heap
See also [Double Linked List](https://en.wikipedia.org/wiki/Linked_list#Doubly_linked_list)
Expand Down
2 changes: 1 addition & 1 deletion kernel/include/drivers/driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace maxOS

/**
* @class Driver
* @brief Base class for all drivers, handles the activation, deactivation, initialisation and reset of the driver as well as error messages and identifying the device
* @brief base class for all drivers, handles the activation, deactivation, initialisation and reset of the driver as well as error messages and identifying the device
*/
class Driver {
protected:
Expand Down
4 changes: 2 additions & 2 deletions kernel/include/hardwarecommunication/interrupts.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ namespace maxOS {
static common::OutputStream* s_error_messages;
uint16_t m_hardware_interrupt_offset;
InterruptHandler* m_interrupt_handlers[256]; //TODO: Make vector?
ThreadManager* m_thread_manager;
system::ThreadManager* m_thread_manager;

struct GateDescriptor {
uint16_t handler_address_low_bits;
Expand Down Expand Up @@ -135,7 +135,7 @@ namespace maxOS {


public:
InterruptManager(uint16_t hardware_interrupt_offset, system::GlobalDescriptorTable*global_descriptor_table, ThreadManager* thread_manager, common::OutputStream* handler);
InterruptManager(uint16_t hardware_interrupt_offset, system::GlobalDescriptorTable*global_descriptor_table, system::ThreadManager* thread_manager, common::OutputStream* handler);
~InterruptManager();

uint16_t hardware_interrupt_offset();
Expand Down
2 changes: 1 addition & 1 deletion kernel/include/hardwarecommunication/port.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace maxOS {

/**
* @class Port
* @brief Base class for all ports
* @brief base class for all ports
*/
class Port {
protected:
Expand Down
2 changes: 1 addition & 1 deletion kernel/include/memory/memoryIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace maxOS{

/**
* @class MemIO
* @brief Base class for all memory IO
* @brief base class for all memory IO
*/
class MemIO {
protected:
Expand Down
64 changes: 36 additions & 28 deletions kernel/include/system/gdt.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,43 +10,51 @@

namespace maxOS {
namespace system {
class GlobalDescriptorTable {
public:
class SegmentDescriptor {

/**
* @class SegmentDescriptor
* @brief Stores data for the segment descriptors in the GDT
*/
class SegmentDescriptor {
private:
uint16_t limit_lo; //Low Bytes of the pointer (Least Significant)
uint16_t base_lo; //Low Bytes of the pointer (Least Significant)
uint8_t base_hi; //One byte extension for the pointer
uint8_t type; //Excess Bytes
uint8_t flags_limit_hi; //High Bytes of the pointer (Most Significant)
uint8_t base_vhi; //High Bytes of the pointer (Most Significant)
uint16_t m_limit_lo;
uint16_t m_base_lo;
uint8_t m_base_hi;
uint8_t m_type;
uint8_t m_flags_limit_hi;
uint8_t m_base_vhi;

public:
SegmentDescriptor(uint32_t base, uint32_t limit,
uint8_t type);
SegmentDescriptor(uint32_t base, uint32_t limit, uint8_t type);

//Return Pointer and the limit
uint32_t Base();
uint32_t base();
uint32_t limit();

uint32_t Limit();
} __attribute__((packed));

} __attribute__((packed)); //Tell GCC not to change any of the alignment in the structure. The packed attribute specifies that a variable or structure field should have the smallest possible alignment, one byte for a variable, and one bit for a field, unless you specify a larger value with the aligned attribute.

private:
SegmentDescriptor nullSegmentSelector;
SegmentDescriptor unusedSegmentSelector;
SegmentDescriptor codeSegmentSelector;
SegmentDescriptor dataSegmentSelector;
SegmentDescriptor taskStateSegmentSelector;
/**
* @class GlobalDescriptorTable
* @brief Sets up the GDT in the CPU
*/
class GlobalDescriptorTable {

private:
SegmentDescriptor m_null_segment_selector;
SegmentDescriptor m_unused_segment_selector;
SegmentDescriptor m_code_segment_selector;
SegmentDescriptor m_data_segment_selector;
SegmentDescriptor m_task_state_segment_selector;

public:
public:

GlobalDescriptorTable(const multiboot_info& multibootHeader);
~GlobalDescriptorTable();
GlobalDescriptorTable(const multiboot_info& multiboot_header);
~GlobalDescriptorTable();

uint16_t CodeSegmentSelector();
uint16_t DataSegmentSelector();
uint16_t TaskStateSegmentSelector();
};
uint16_t code_segment_selector();
uint16_t data_segment_selector();
uint16_t task_state_segment_selector();
};
}
}

Expand Down
90 changes: 44 additions & 46 deletions kernel/include/system/multitasking.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,67 +5,65 @@
#ifndef MAXOS_SYSTEM_MULTITASKING_H
#define MAXOS_SYSTEM_MULTITASKING_H

#include <common/vector.h>
#include <stdint.h>
#include <system/gdt.h>

namespace maxOS{

namespace system{

struct CPUState_Task
{
//Pushed by kernel in interuptstubs

uint32_t eax; // Accumulating Register
uint32_t ebx; // Base Register
uint32_t ecx; // Counting Register
uint32_t edx; // Data Register

uint32_t esi; // Stack Index
uint32_t edi; // Data Index
uint32_t ebp; // Stack Base Pointer

//Elements that have been pushed so far
/*
uint32_t gs;
uint32_t fs;
uint32_t es;
uint32_t ds;
*/
uint32_t error; //One int for an error code

uint32_t eip; // Instruction Pointer
uint32_t cs; // Code Segment
uint32_t eflags; // Flags
uint32_t esp; // Stack Pointer
uint32_t ss; // Stack Segment
} __attribute__((packed));
struct CPUState {
//Pushed by kernel in interupt_stubs

uint32_t eax;
uint32_t ebx;
uint32_t ecx;
uint32_t edx;

uint32_t esi;
uint32_t edi;
uint32_t ebp;

uint32_t error;

uint32_t eip;
uint32_t cs;
uint32_t eflags;
uint32_t esp;
uint32_t ss;
} __attribute__((packed));

/**
* @class Task
* @brief A task that can be scheduled by the TaskManager
*/
class Task
{
friend class TaskManager; //Allow TaskManger class to acess private values of this class
private:
uint8_t stack[4096]; //Allocate 4kb for this tasks stack
CPUState_Task* cpuState;
public:
Task(system::GlobalDescriptorTable *gdt, void entrypoint());
~Task();
bool killMe = false;
friend class TaskManager;

private:
uint8_t m_stack[4096];
CPUState * m_cpu_state;
public:
Task(system::GlobalDescriptorTable *gdt, void entrypoint());
~Task();
};


/**
* @class TaskManager
* @brief Manages the scheduling of m_tasks
*/
class TaskManager
{
private:
Task* tasks[256];
int numTasks;
int currentTask; //Index of currently active task is used when the processor needs to go back to this task
public:
TaskManager();
~TaskManager();
bool AddTask(Task* task);
CPUState_Task* Schedule(CPUState_Task* cpuState); //function that does the scheduling (round-robin [https://en.wikipedia.org/wiki/Round-robin_scheduling])s
private:
common::Vector<Task*> m_tasks;
int m_current_task { -1 };
public:
TaskManager();
~TaskManager();
bool add_task(Task* task);
CPUState * schedule(CPUState * cpuState);
};

}
Expand Down
Loading

0 comments on commit 5aacd15

Please sign in to comment.