summaryrefslogtreecommitdiffhomepage
path: root/dev
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-03-25 15:35:28 +0100
committerAmlal El Mahrouss <amlal@nekernel.org>2025-03-25 15:35:28 +0100
commit0ead895f52d24dad009f738037a7795d4e3d840a (patch)
tree863fd1c881fc7bf26ab78b932421e6416bbef288 /dev
parent59dbe4cffc7c633709ef8b45f49c46daf7f74e92 (diff)
kernel: Refactor AHCI I/O path, enhance memory allocators, and cleanup obsolete script
- Removed unused `build_gcc.sh` script. - Namespaced CPU feature flags under `NeOS` and transitioned from enum to unnamed enum for scoping. - Renamed `drv_std_input_output` to `drv_std_input_output_ahci` for clarity. - Improved AHCI driver documentation and added zeroing for read buffers. - Added optional `pad` parameter to memory allocators: `mm_alloc_bitmap`, `mm_new_heap`, `PageMgr::Request`, etc. - Updated bitmap allocator to correctly handle and align with padded sizes. - Added `fPad` field to memory header block. - Fixed `ATA-DMA` mode comment, corrected PRD usage and logic. - Improved code documentation and formatting in `UserProcessScheduler`, `PageMgr`, and related components. - Enhanced safety in process memory cleanup (e.g., `StackReserve` cleanup). Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'dev')
-rw-r--r--dev/kernel/HALKit/AMD64/CPUID.h131
-rw-r--r--dev/kernel/HALKit/AMD64/Paging.h2
-rw-r--r--dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc48
-rw-r--r--dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc36
-rw-r--r--dev/kernel/KernelKit/MemoryMgr.h2
-rw-r--r--dev/kernel/KernelKit/UserProcessScheduler.h57
-rw-r--r--dev/kernel/NewKit/Macros.h5
-rw-r--r--dev/kernel/NewKit/PageMgr.h2
-rw-r--r--dev/kernel/src/BitMapMgr.cc55
-rw-r--r--dev/kernel/src/MemoryMgr.cc9
-rw-r--r--dev/kernel/src/PageMgr.cc4
-rw-r--r--dev/kernel/src/Pmm.cc4
-rw-r--r--dev/kernel/src/UserProcessScheduler.cc29
13 files changed, 246 insertions, 138 deletions
diff --git a/dev/kernel/HALKit/AMD64/CPUID.h b/dev/kernel/HALKit/AMD64/CPUID.h
index 7f04ac27..6ea84106 100644
--- a/dev/kernel/HALKit/AMD64/CPUID.h
+++ b/dev/kernel/HALKit/AMD64/CPUID.h
@@ -15,72 +15,73 @@
#include <NewKit/Defines.h>
-enum CPUFeatureEnum
-{
- kCPUFeatureSSE3 = 1 << 0,
- kCPUFeaturePCLMUL = 1 << 1,
- kCPUFeatureDTES64 = 1 << 2,
- kCPUFeatureMONITOR = 1 << 3,
- kCPUFeatureDS_CPL = 1 << 4,
- kCPUFeatureVMX = 1 << 5,
- kCPUFeatureSMX = 1 << 6,
- kCPUFeatureEST = 1 << 7,
- kCPUFeatureTM2 = 1 << 8,
- kCPUFeatureSSSE3 = 1 << 9,
- kCPUFeatureCID = 1 << 10,
- kCPUFeatureSDBG = 1 << 11,
- kCPUFeatureFMA = 1 << 12,
- kCPUFeatureCX16 = 1 << 13,
- kCPUFeatureXTPR = 1 << 14,
- kCPUFeaturePDCM = 1 << 15,
- kCPUFeaturePCID = 1 << 17,
- kCPUFeatureDCA = 1 << 18,
- kCPUFeatureSSE4_1 = 1 << 19,
- kCPUFeatureSSE4_2 = 1 << 20,
- kCPUFeatureX2APIC = 1 << 21,
- kCPUFeatureMOVBE = 1 << 22,
- kCPUFeaturePOP3C = 1 << 23,
- kCPUFeatureECXTSC = 1 << 24,
- kCPUFeatureAES = 1 << 25,
- kCPUFeatureXSAVE = 1 << 26,
- kCPUFeatureOSXSAVE = 1 << 27,
- kCPUFeatureAVX = 1 << 28,
- kCPUFeatureF16C = 1 << 29,
- kCPUFeatureRDRAND = 1 << 30,
- kCPUFeatureHYPERVISOR = 1 << 31,
- kCPUFeatureFPU = 1 << 0,
- kCPUFeatureVME = 1 << 1,
- kCPUFeatureDE = 1 << 2,
- kCPUFeaturePSE = 1 << 3,
- kCPUFeatureEDXTSC = 1 << 4,
- kCPUFeatureMSR = 1 << 5,
- kCPUFeaturePAE = 1 << 6,
- kCPUFeatureMCE = 1 << 7,
- kCPUFeatureCX8 = 1 << 8,
- kCPUFeatureAPIC = 1 << 9,
- kCPUFeatureSEP = 1 << 11,
- kCPUFeatureMTRR = 1 << 12,
- kCPUFeaturePGE = 1 << 13,
- kCPUFeatureMCA = 1 << 14,
- kCPUFeatureCMOV = 1 << 15,
- kCPUFeaturePAT = 1 << 16,
- kCPUFeaturePSE36 = 1 << 17,
- kCPUFeaturePSN = 1 << 18,
- kCPUFeatureCLFLUSH = 1 << 19,
- kCPUFeatureDS = 1 << 21,
- kCPUFeatureACPI = 1 << 22,
- kCPUFeatureMMX = 1 << 23,
- kCPUFeatureFXSR = 1 << 24,
- kCPUFeatureSSE = 1 << 25,
- kCPUFeatureSSE2 = 1 << 26,
- kCPUFeatureSS = 1 << 27,
- kCPUFeatureHTT = 1 << 28,
- kCPUFeatureTM = 1 << 29,
- kCPUFeatureIA64 = 1 << 30,
- kCPUFeaturePBE = 1 << 31
-};
-
namespace NeOS
{
+
+ enum
+ {
+ kCPUFeatureSSE3 = 1 << 0,
+ kCPUFeaturePCLMUL = 1 << 1,
+ kCPUFeatureDTES64 = 1 << 2,
+ kCPUFeatureMONITOR = 1 << 3,
+ kCPUFeatureDS_CPL = 1 << 4,
+ kCPUFeatureVMX = 1 << 5,
+ kCPUFeatureSMX = 1 << 6,
+ kCPUFeatureEST = 1 << 7,
+ kCPUFeatureTM2 = 1 << 8,
+ kCPUFeatureSSSE3 = 1 << 9,
+ kCPUFeatureCID = 1 << 10,
+ kCPUFeatureSDBG = 1 << 11,
+ kCPUFeatureFMA = 1 << 12,
+ kCPUFeatureCX16 = 1 << 13,
+ kCPUFeatureXTPR = 1 << 14,
+ kCPUFeaturePDCM = 1 << 15,
+ kCPUFeaturePCID = 1 << 17,
+ kCPUFeatureDCA = 1 << 18,
+ kCPUFeatureSSE4_1 = 1 << 19,
+ kCPUFeatureSSE4_2 = 1 << 20,
+ kCPUFeatureX2APIC = 1 << 21,
+ kCPUFeatureMOVBE = 1 << 22,
+ kCPUFeaturePOP3C = 1 << 23,
+ kCPUFeatureECXTSC = 1 << 24,
+ kCPUFeatureAES = 1 << 25,
+ kCPUFeatureXSAVE = 1 << 26,
+ kCPUFeatureOSXSAVE = 1 << 27,
+ kCPUFeatureAVX = 1 << 28,
+ kCPUFeatureF16C = 1 << 29,
+ kCPUFeatureRDRAND = 1 << 30,
+ kCPUFeatureHYPERVISOR = 1 << 31,
+ kCPUFeatureFPU = 1 << 0,
+ kCPUFeatureVME = 1 << 1,
+ kCPUFeatureDE = 1 << 2,
+ kCPUFeaturePSE = 1 << 3,
+ kCPUFeatureEDXTSC = 1 << 4,
+ kCPUFeatureMSR = 1 << 5,
+ kCPUFeaturePAE = 1 << 6,
+ kCPUFeatureMCE = 1 << 7,
+ kCPUFeatureCX8 = 1 << 8,
+ kCPUFeatureAPIC = 1 << 9,
+ kCPUFeatureSEP = 1 << 11,
+ kCPUFeatureMTRR = 1 << 12,
+ kCPUFeaturePGE = 1 << 13,
+ kCPUFeatureMCA = 1 << 14,
+ kCPUFeatureCMOV = 1 << 15,
+ kCPUFeaturePAT = 1 << 16,
+ kCPUFeaturePSE36 = 1 << 17,
+ kCPUFeaturePSN = 1 << 18,
+ kCPUFeatureCLFLUSH = 1 << 19,
+ kCPUFeatureDS = 1 << 21,
+ kCPUFeatureACPI = 1 << 22,
+ kCPUFeatureMMX = 1 << 23,
+ kCPUFeatureFXSR = 1 << 24,
+ kCPUFeatureSSE = 1 << 25,
+ kCPUFeatureSSE2 = 1 << 26,
+ kCPUFeatureSS = 1 << 27,
+ kCPUFeatureHTT = 1 << 28,
+ kCPUFeatureTM = 1 << 29,
+ kCPUFeatureIA64 = 1 << 30,
+ kCPUFeaturePBE = 1 << 31
+ };
+
typedef Int64 CPUID;
} // namespace NeOS
diff --git a/dev/kernel/HALKit/AMD64/Paging.h b/dev/kernel/HALKit/AMD64/Paging.h
index 4e2ac1b1..09b6ade3 100644
--- a/dev/kernel/HALKit/AMD64/Paging.h
+++ b/dev/kernel/HALKit/AMD64/Paging.h
@@ -88,7 +88,7 @@ namespace NeOS::HAL
NE_PTE* ALIGN(kPageAlign) fEntries[kPageMax];
};
- auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page) -> VoidPtr;
+ auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page, const SizeT pad = 0) -> VoidPtr;
auto mm_free_bitmap(VoidPtr page_ptr) -> Bool;
} // namespace NeOS::HAL
diff --git a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc
index bd5c86f4..b1584c80 100644
--- a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc
+++ b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc
@@ -63,7 +63,7 @@ STATIC Char kCurrentDiskModel[50] = {"UNKNOWN AHCI DRIVE"};
STATIC UInt16 kSATAPortsImplemented = 0U;
template <BOOL Write, BOOL CommandOrCTRL, BOOL Identify>
-STATIC Void drv_std_input_output(UInt64 lba, UInt8* buffer, SizeT sector_sz, SizeT size_buffer) noexcept;
+STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz, SizeT size_buffer) noexcept;
STATIC Int32 drv_find_cmd_slot(HbaPort* port) noexcept;
@@ -73,21 +73,29 @@ STATIC Void drv_compute_disk_ahci() noexcept
{
kSATASectorCount = 0UL;
+ /// Normally 512 bytes, but add an additional 512 bytes to make 1 KIB.
const UInt16 kSzIdent = kib_cast(1);
+ /// Push it to the stack
UInt8 identify_data[kSzIdent] = {0};
rt_set_memory(identify_data, 0, kSzIdent);
- drv_std_input_output<NO, YES, YES>(0, identify_data, kAHCISectorSize, kSzIdent);
+ /// Send AHCI command.
+ drv_std_input_output_ahci<NO, YES, YES>(0, identify_data, kAHCISectorSize, kSzIdent);
+ /// Extract 28-bit LBA.
kSATASectorCount = (identify_data[61] << 16) | identify_data[60];
+ /// Show what we got.
kout << "Disk Model: " << kCurrentDiskModel << kendl;
kout << "Disk Size: " << number(drv_get_size()) << kendl;
kout << "Disk Sector Count: " << number(kSATASectorCount) << kendl;
}
+/// @brief Finds a command slot for a HBA port.
+/// @param port The port to search on.
+/// @return The slot, or ~0.
STATIC Int32 drv_find_cmd_slot(HbaPort* port) noexcept
{
UInt32 slots = (port->Sact | port->Ci);
@@ -103,8 +111,13 @@ STATIC Int32 drv_find_cmd_slot(HbaPort* port) noexcept
return ~0;
}
+/// @brief Send an AHCI command, according to the template parameters.
+/// @param lba Logical Block Address to look for.
+/// @param buffer The data buffer to transfer.
+/// @param sector_sz The disk's sector size (unused)
+/// @param size_buffer The size of the **buffer** parameter.
template <BOOL Write, BOOL CommandOrCTRL, BOOL Identify>
-STATIC Void drv_std_input_output(UInt64 lba, UInt8* buffer, SizeT sector_sz, SizeT size_buffer) noexcept
+STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz, SizeT size_buffer) noexcept
{
UIntPtr slot = 0UL;
@@ -113,6 +126,12 @@ STATIC Void drv_std_input_output(UInt64 lba, UInt8* buffer, SizeT sector_sz, Siz
if (slot == ~0)
return;
+ if (!Write)
+ {
+ // Zero-memory the buffer field.
+ rt_set_memory(buffer, 0, size_buffer);
+ }
+
volatile HbaCmdHeader* command_header = ((HbaCmdHeader*)(((UInt64)kSATAHba->Ports[kSATAIndex].Clb)));
command_header += slot;
@@ -310,6 +329,8 @@ STATIC Bool drv_std_init_ahci(UInt16& pi, BOOL& atapi)
return NO;
}
+/// @brief Checks if an AHCI device is detected.
+/// @return Either if detected, or not found.
Bool drv_std_detected_ahci()
{
return kSATADev.DeviceId() != (UShort)PCI::PciConfigKind::Invalid && kSATADev.Bar(kSATABar5) != 0;
@@ -317,6 +338,7 @@ Bool drv_std_detected_ahci()
namespace NeOS
{
+ /// @brief Initialize an AHCI device (StorageKit)
UInt16 sk_init_ahci_device(BOOL atapi)
{
UInt16 pi = 0;
@@ -327,6 +349,7 @@ namespace NeOS
return pi;
}
+ /// @brief Implementation details namespace.
namespace Detail
{
/// @brief Read AHCI device.
@@ -344,7 +367,7 @@ namespace NeOS
if (!disk)
return;
- drv_std_input_output<NO, YES, NO>(disk->fPacket.fPacketLba, (UInt8*)disk->fPacket.fPacketContent, kAHCISectorSize, disk->fPacket.fPacketSize);
+ drv_std_input_output_ahci<NO, YES, NO>(disk->fPacket.fPacketLba, (UInt8*)disk->fPacket.fPacketContent, kAHCISectorSize, disk->fPacket.fPacketSize);
}
/// @brief Write AHCI device.
@@ -362,10 +385,13 @@ namespace NeOS
if (!disk)
return;
- drv_std_input_output<YES, YES, NO>(disk->fPacket.fPacketLba, (UInt8*)disk->fPacket.fPacketContent, kAHCISectorSize, disk->fPacket.fPacketSize);
+ drv_std_input_output_ahci<YES, YES, NO>(disk->fPacket.fPacketLba, (UInt8*)disk->fPacket.fPacketContent, kAHCISectorSize, disk->fPacket.fPacketSize);
}
} // namespace Detail
+ /// @brief Acquires a new AHCI device with drv_index in mind.
+ /// @param drv_index The drive index to assign.
+ /// @return A wrapped device interface if successful, or error code.
ErrorOr<AHCIDeviceInterface> sk_acquire_ahci_device(Int32 drv_index)
{
if (!drv_std_detected_ahci())
@@ -382,16 +408,24 @@ namespace NeOS
}
} // namespace NeOS
+// ================================================================================================
+
+//
+// This applies only if we compile with AHCI as a default disk driver.
+//
+
+// ================================================================================================
+
#ifdef __AHCI__
Void drv_std_write(UInt64 lba, Char* buffer, SizeT sector_sz, SizeT size_buffer)
{
- drv_std_input_output<YES, YES, NO>(lba, (UInt8*)buffer, sector_sz, size_buffer);
+ drv_std_input_output_ahci<YES, YES, NO>(lba, (UInt8*)buffer, sector_sz, size_buffer);
}
Void drv_std_read(UInt64 lba, Char* buffer, SizeT sector_sz, SizeT size_buffer)
{
- drv_std_input_output<NO, YES, NO>(lba, (UInt8*)buffer, sector_sz, size_buffer);
+ drv_std_input_output_ahci<NO, YES, NO>(lba, (UInt8*)buffer, sector_sz, size_buffer);
}
Bool drv_std_init(UInt16& pi)
diff --git a/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc
index 0a03dafc..9624ea5b 100644
--- a/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc
+++ b/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc
@@ -7,7 +7,7 @@
/**
* @file ATA-PIO.cc
* @author Amlal EL Mahrouss (amlal@nekernel.org)
- * @brief ATA driver (PIO mode).
+ * @brief ATA driver (DMA mode).
* @version 0.1
* @date 2024-02-02
*
@@ -131,17 +131,15 @@ Boolean drv_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster)
return NO;
}
-namespace Detail
+namespace NeOS::Detail
{
- using namespace NeOS;
-
struct PRDEntry
{
UInt32 mAddress;
UInt16 mByteCount;
UInt16 mFlags;
};
-} // namespace Detail
+} // namespace NeOS::Detail
static UIntPtr kReadAddr = mib_cast(2);
static UIntPtr kWriteAddr = mib_cast(4);
@@ -151,7 +149,7 @@ Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz
Lba /= SectorSz;
if (Size > kib_cast(64))
- ke_panic(RUNTIME_CHECK_FAILED, "ATA-DMA only supports < 64kb DMA transfers.");
+ return;
UInt8 Command = ((!Master) ? 0xE0 : 0xF0);
@@ -168,7 +166,7 @@ Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz
rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16);
rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24);
- Detail::PRDEntry* prd = (Detail::PRDEntry*)(kATADevice.Bar(0x20) + 4); // The PRDEntry is not correct.
+ NeOS::Detail::PRDEntry* prd = (NeOS::Detail::PRDEntry*)(kATADevice.Bar(0x20) + 4); // The PRDEntry is not correct.
prd->mAddress = (UInt32)(UIntPtr)kReadAddr;
prd->mByteCount = Size - 1;
@@ -196,7 +194,7 @@ Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorS
Lba /= SectorSz;
if (Size > kib_cast(64))
- ke_panic(RUNTIME_CHECK_FAILED, "ATA-DMA only supports < 64kb DMA transfers.");
+ return;
UInt8 Command = ((!Master) ? 0xE0 : 0xF0);
@@ -211,10 +209,11 @@ Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorS
rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16);
rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24);
- Detail::PRDEntry* prd = (Detail::PRDEntry*)(kATADevice.Bar(0x20) + 4);
- prd->mAddress = (UInt32)(UIntPtr)kWriteAddr;
- prd->mByteCount = Size - 1;
- prd->mFlags = 0x8000;
+ NeOS::Detail::PRDEntry* prd = (NeOS::Detail::PRDEntry*)(kATADevice.Bar(0x20) + 4);
+
+ prd->mAddress = (UInt32)(UIntPtr)kWriteAddr;
+ prd->mByteCount = Size - 1;
+ prd->mFlags = 0x8000;
rt_out32(kATADevice.Bar(0x20) + 0x04, (UInt32)(UIntPtr)prd);
rt_out8(kATADevice.Bar(0x20) + ATA_REG_COMMAND, ATA_CMD_WRITE_DMA);
@@ -230,21 +229,28 @@ Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorS
prd = nullptr;
}
-/// @brief is ATA detected?
+/***********************************************************************************/
+/// @brief Is ATA detected?
+/***********************************************************************************/
Boolean drv_std_detected(Void)
{
return kATADetected;
}
+/***********************************************************************************/
/***
- @brief Getter, gets the number of sectors inside the drive.
+ @brief Gets the number of sectors inside the drive.
+ @return Number of sectors, or zero.
*/
+/***********************************************************************************/
NeOS::SizeT drv_get_sector_count()
{
return (kATAData[61] << 16) | kATAData[60];
}
-/// @brief Get the drive size.
+/***********************************************************************************/
+/// @brief Get the size of the current drive.
+/***********************************************************************************/
NeOS::SizeT drv_get_size()
{
return (drv_get_sector_count()) * kATASectorSize;
diff --git a/dev/kernel/KernelKit/MemoryMgr.h b/dev/kernel/KernelKit/MemoryMgr.h
index 139ae7aa..23a4721b 100644
--- a/dev/kernel/KernelKit/MemoryMgr.h
+++ b/dev/kernel/KernelKit/MemoryMgr.h
@@ -37,7 +37,7 @@ namespace NeOS
/// @param wr Read Write bit.
/// @param user User enable bit.
/// @return The newly allocated pointer, or nullptr.
- VoidPtr mm_new_heap(const SizeT sz, const Bool wr, const Bool user);
+ VoidPtr mm_new_heap(const SizeT sz, const Bool wr, const Bool user, const SizeT pad_amount = 0);
/// @brief Protect the heap with a CRC value.
/// @param heap_ptr pointer.
diff --git a/dev/kernel/KernelKit/UserProcessScheduler.h b/dev/kernel/KernelKit/UserProcessScheduler.h
index 10a08e0f..a2006db1 100644
--- a/dev/kernel/KernelKit/UserProcessScheduler.h
+++ b/dev/kernel/KernelKit/UserProcessScheduler.h
@@ -38,10 +38,14 @@ namespace NeOS
typedef UInt64 PTime;
+ /***********************************************************************************/
//! @brief Local Process identifier.
+ /***********************************************************************************/
typedef Int64 ProcessID;
+ /***********************************************************************************/
//! @brief Local Process status enum.
+ /***********************************************************************************/
enum class ProcessStatusKind : Int32
{
kInvalid,
@@ -53,8 +57,9 @@ namespace NeOS
kCount,
};
- //! @brief Affinity is the amount of nano-seconds this process is going
- //! to run.
+ /***********************************************************************************/
+ //! @brief Affinity is the amount of nano-seconds this process is going to run.
+ /***********************************************************************************/
enum class AffinityKind : Int32
{
kRealTime = 500,
@@ -65,7 +70,9 @@ namespace NeOS
kVeryLowUsage = 2000,
};
- // operator overloading.
+ /***********************************************************************************/
+ //! Operators for AffinityKind
+ /***********************************************************************************/
inline bool operator<(AffinityKind lhs, AffinityKind rhs)
{
@@ -99,7 +106,9 @@ namespace NeOS
return lhs_int >= rhs_int;
}
- // end of operator overloading.
+ /***********************************************************************************/
+ /// @brief Subsystem enum type.
+ /***********************************************************************************/
enum class ProcessSubsystem : Int32
{
@@ -114,7 +123,9 @@ namespace NeOS
using ProcessTime = UInt64;
using PID = Int64;
- // for permission manager, tells where we run the code.
+ /***********************************************************************************/
+ /// @note For User manager, tells where we run the code.
+ /***********************************************************************************/
enum class ProcessLevelRing : Int32
{
kRingStdUser = 1,
@@ -123,7 +134,9 @@ namespace NeOS
kRingCount = 5,
};
+ /***********************************************************************************/
/// @brief Helper type to describe a code image.
+ /***********************************************************************************/
using ImagePtr = VoidPtr;
struct UserProcessImage final
@@ -144,8 +157,10 @@ namespace NeOS
}
};
+ /***********************************************************************************/
/// @name UserProcess
/// @brief User process class, holds information about the running process/thread.
+ /***********************************************************************************/
class UserProcess final
{
public:
@@ -207,38 +222,58 @@ namespace NeOS
Int32 Kind{kExectuableKind};
public:
+ /***********************************************************************************/
//! @brief boolean operator, check status.
+ /***********************************************************************************/
operator bool();
+ /***********************************************************************************/
///! @brief Crashes the app, exits with code ~0.
+ /***********************************************************************************/
Void Crash();
+ /***********************************************************************************/
///! @brief Exits the app.
+ /***********************************************************************************/
Void Exit(const Int32& exit_code = 0);
+ /***********************************************************************************/
///! @brief TLS allocate.
- ///! @param sz size of new ptr.
+ ///! @param sz size of data structure.
+ ///! @param pad_amount amount to add after pointer.
+ ///! @return A wrapped pointer, or error code.
+ /***********************************************************************************/
ErrorOr<VoidPtr> New(const SizeT& sz, const SizeT& pad_amount = 0);
+ /***********************************************************************************/
///! @brief TLS free.
///! @param ptr the pointer to free.
///! @param sz the size of it.
+ /***********************************************************************************/
template <typename T>
Boolean Delete(ErrorOr<T*> ptr, const SizeT& sz);
- ///! @brief Wakes up threads.
+ /***********************************************************************************/
+ ///! @brief Wakes up thread.
+ /***********************************************************************************/
Void Wake(const Bool wakeup = false);
public:
+ /***********************************************************************************/
//! @brief Gets the local exit code.
+ /***********************************************************************************/
const UInt32& GetExitCode() noexcept;
+ /***********************************************************************************/
///! @brief Get the process's name
///! @example 'C Runtime Library'
+ /***********************************************************************************/
const Char* GetName() noexcept;
+ /***********************************************************************************/
//! @brief return local error code of process.
//! @return Int32 local error code.
+ /***********************************************************************************/
Int32& GetLocalCode() noexcept;
const User* GetOwner() noexcept;
@@ -278,8 +313,10 @@ namespace NeOS
using UserProcessRef = UserProcess&;
+ /***********************************************************************************/
/// @brief Process scheduler class.
/// The main class which you call to schedule user processes.
+ /***********************************************************************************/
class UserProcessScheduler final : public ISchedulable
{
friend class UserProcessHelper;
@@ -315,9 +352,11 @@ namespace NeOS
UserProcessTeam mTeam{};
};
- /*
+ /***********************************************************************************/
+ /**
* \brief UserProcess helper class, which contains needed utilities for the scheduler.
*/
+ /***********************************************************************************/
class UserProcessHelper final
{
@@ -335,9 +374,7 @@ namespace NeOS
#include <KernelKit/UserProcessScheduler.inl>
////////////////////////////////////////////////////
-
// END
-
////////////////////////////////////////////////////
#endif /* ifndef INC_PROCESS_SCHEDULER_H */
diff --git a/dev/kernel/NewKit/Macros.h b/dev/kernel/NewKit/Macros.h
index 637a2a30..1d270929 100644
--- a/dev/kernel/NewKit/Macros.h
+++ b/dev/kernel/NewKit/Macros.h
@@ -6,6 +6,11 @@
#pragma once
+/***********************************************************************************/
+/// @file NewKit/Macros.h
+/// @brief Core Types and Macros.
+/***********************************************************************************/
+
#ifndef KIB
#define KIB(X) (NeOS::UInt64)((X) / 1024)
#endif
diff --git a/dev/kernel/NewKit/PageMgr.h b/dev/kernel/NewKit/PageMgr.h
index 3d8e1f9a..00638f8a 100644
--- a/dev/kernel/NewKit/PageMgr.h
+++ b/dev/kernel/NewKit/PageMgr.h
@@ -68,7 +68,7 @@ namespace NeOS
PageMgr(const PageMgr&) = default;
public:
- PTEWrapper Request(Boolean Rw, Boolean User, Boolean ExecDisable, SizeT Sz);
+ PTEWrapper Request(Boolean Rw, Boolean User, Boolean ExecDisable, SizeT Sz, SizeT Pad);
bool Free(Ref<PTEWrapper>& wrapper);
private:
diff --git a/dev/kernel/src/BitMapMgr.cc b/dev/kernel/src/BitMapMgr.cc
index 18b1a156..f65df8c6 100644
--- a/dev/kernel/src/BitMapMgr.cc
+++ b/dev/kernel/src/BitMapMgr.cc
@@ -28,7 +28,9 @@ namespace NeOS
{
namespace Detail
{
- /// \brief Proxy Interface to allocate a bitmap.
+ /***********************************************************************************/
+ /// \brief Proxy Interface to manage a bitmap allocator.
+ /***********************************************************************************/
class IBitMapProxy final
{
public:
@@ -79,27 +81,36 @@ namespace NeOS
return flags;
}
- /// @brief Iterate over availables pages for a free one.
- /// @return The new address which was found.
- auto FindBitMap(VoidPtr base_ptr, SizeT size, Bool wr, Bool user) -> VoidPtr
+ /***********************************************************************************/
+ /// @brief Iterate over availables bitmap, until we find a free entry.
+ /// @param base_ptr base pointer to look on.
+ /// @param size the size of the requested data structure.
+ /// @param wr is writable flag?
+ /// @param user is user flag?
+ /// @param pad additional padding added to **size**
+ /// @return The new free address, or nullptr.
+ /***********************************************************************************/
+ auto FindBitMap(VoidPtr base_ptr, const SizeT size, const Bool wr, const Bool user, const SizeT pad) -> VoidPtr
{
if (!size)
return nullptr;
- VoidPtr base = reinterpret_cast<VoidPtr>(((UIntPtr)base_ptr) + kPageSize);
+ constexpr const UInt32 kStartOffset = 0x1000;
- static SizeT biggest_block = 0UL;
+ VoidPtr base = reinterpret_cast<VoidPtr>(((UIntPtr)base_ptr) + kStartOffset);
+
+ static SizeT biggest = 0UL;
while (YES)
{
UIntPtr* ptr_bit_set = reinterpret_cast<UIntPtr*>(base);
if (ptr_bit_set[kBitMapMagIdx] == kBitMapMagic &&
- ptr_bit_set[kBitMapSizeIdx] == size)
+ ptr_bit_set[kBitMapSizeIdx] == (size + pad))
{
if (ptr_bit_set[kBitMapUsedIdx] == No)
{
- ptr_bit_set[kBitMapSizeIdx] = size;
+ ptr_bit_set[kBitMapSizeIdx] = size + pad;
ptr_bit_set[kBitMapUsedIdx] = Yes;
this->GetBitMapStatus(ptr_bit_set);
@@ -107,8 +118,8 @@ namespace NeOS
UInt32 flags = this->MakeMMFlags(wr, user);
mm_map_page(ptr_bit_set, ptr_bit_set, flags);
- if (biggest_block < size)
- biggest_block = size;
+ if (biggest < (size + pad))
+ biggest = size + pad;
return (VoidPtr)ptr_bit_set;
}
@@ -116,7 +127,7 @@ namespace NeOS
else if (ptr_bit_set[kBitMapMagIdx] != kBitMapMagic)
{
ptr_bit_set[kBitMapMagIdx] = kBitMapMagic;
- ptr_bit_set[kBitMapSizeIdx] = size;
+ ptr_bit_set[kBitMapSizeIdx] = (size + pad);
ptr_bit_set[kBitMapUsedIdx] = Yes;
this->GetBitMapStatus(ptr_bit_set);
@@ -124,13 +135,13 @@ namespace NeOS
UInt32 flags = this->MakeMMFlags(wr, user);
mm_map_page(ptr_bit_set, ptr_bit_set, flags);
- if (biggest_block < size)
- biggest_block = size;
+ if (biggest < (size + pad))
+ biggest = (size + pad);
return (VoidPtr)ptr_bit_set;
}
- base = reinterpret_cast<VoidPtr>(reinterpret_cast<UIntPtr>(base) + ((ptr_bit_set[kBitMapMagIdx] != kBitMapMagic) ? (size) : ptr_bit_set[kBitMapSizeIdx]));
+ base = reinterpret_cast<VoidPtr>(reinterpret_cast<UIntPtr>(base) + ((ptr_bit_set[kBitMapMagIdx] != kBitMapMagic) ? (size + pad) : ptr_bit_set[kBitMapSizeIdx]));
}
return nullptr;
@@ -145,42 +156,46 @@ namespace NeOS
return;
}
- kout << "Magic Number: " << hex_number(ptr_bit_set[kBitMapMagIdx]) << kendl;
- kout << "Is Allocated: " << (ptr_bit_set[kBitMapUsedIdx] ? "Yes" : "No") << kendl;
+ kout << "Magic: " << hex_number(ptr_bit_set[kBitMapMagIdx]) << kendl;
+ kout << "Is Allocated? " << (ptr_bit_set[kBitMapUsedIdx] ? "YES" : "NO") << kendl;
kout << "Size of BitMap (B): " << number(ptr_bit_set[kBitMapSizeIdx]) << kendl;
kout << "Size of BitMap (KIB): " << number(KIB(ptr_bit_set[kBitMapSizeIdx])) << kendl;
kout << "Size of BitMap (MIB): " << number(MIB(ptr_bit_set[kBitMapSizeIdx])) << kendl;
kout << "Size of BitMap (GIB): " << number(GIB(ptr_bit_set[kBitMapSizeIdx])) << kendl;
kout << "Size of BitMap (TIB): " << number(TIB(ptr_bit_set[kBitMapSizeIdx])) << kendl;
- kout << "Address Of BitMap Header: " << hex_number((UIntPtr)ptr_bit_set) << kendl;
+ kout << "BitMap Address: " << hex_number((UIntPtr)ptr_bit_set) << kendl;
}
};
} // namespace Detail
- auto mm_is_bitmap(VoidPtr ptr) -> Bool
+ auto mm_is_bitmap(VoidPtr ptr) -> BOOL
{
Detail::IBitMapProxy bitmp;
return bitmp.IsBitMap(ptr);
}
+ /***********************************************************************************/
/// @brief Allocate a new page to be used by the OS.
/// @param wr read/write bit.
/// @param user user bit.
/// @return a new bitmap allocated pointer.
- auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page) -> VoidPtr
+ /***********************************************************************************/
+ auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page, const SizeT pad) -> VoidPtr
{
VoidPtr ptr_new = nullptr;
Detail::IBitMapProxy bitmp;
- ptr_new = bitmp.FindBitMap(kKernelBitMpStart, size, wr, user);
+ ptr_new = bitmp.FindBitMap(kKernelBitMpStart, size, wr, user, pad);
MUST_PASS(ptr_new);
return (UIntPtr*)ptr_new;
}
+ /***********************************************************************************/
/// @brief Free Bitmap, and mark it as absent.
/// @param ptr the pointer to free.
+ /***********************************************************************************/
auto mm_free_bitmap(VoidPtr ptr) -> Bool
{
if (!ptr)
diff --git a/dev/kernel/src/MemoryMgr.cc b/dev/kernel/src/MemoryMgr.cc
index 7a79b906..271dfa23 100644
--- a/dev/kernel/src/MemoryMgr.cc
+++ b/dev/kernel/src/MemoryMgr.cc
@@ -67,6 +67,9 @@ namespace NeOS
/// @brief 64-bit target offset pointer.
UIntPtr fOffset;
+ /// @brief Padding.
+ UInt32 fPad;
+
/// @brief Padding bytes for header.
UInt8 fPadding[kMemoryMgrAlignSz];
};
@@ -116,7 +119,7 @@ namespace NeOS
/// @param wr Read Write bit.
/// @param user User enable bit.
/// @return The newly allocated pointer.
- _Output VoidPtr mm_new_heap(const SizeT sz, const bool wr, const bool user)
+ _Output VoidPtr mm_new_heap(const SizeT sz, const Bool wr, const Bool user, const SizeT pad_amount)
{
auto sz_fix = sz;
@@ -126,7 +129,7 @@ namespace NeOS
sz_fix += sizeof(Detail::MM_INFORMATION_BLOCK);
PageMgr heap_mgr;
- auto wrapper = heap_mgr.Request(wr, user, No, sz_fix);
+ auto wrapper = heap_mgr.Request(wr, user, No, sz_fix, pad_amount);
Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr =
reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>(
@@ -140,6 +143,7 @@ namespace NeOS
heap_info_ptr->fWriteRead = wr;
heap_info_ptr->fUser = user;
heap_info_ptr->fPresent = Yes;
+ heap_info_ptr->fPad = pad_amount;
rt_set_memory(heap_info_ptr->fPadding, 0, kMemoryMgrAlignSz);
@@ -232,6 +236,7 @@ namespace NeOS
heap_info_ptr->fWriteRead = No;
heap_info_ptr->fUser = No;
heap_info_ptr->fMagic = 0;
+ heap_info_ptr->fPad = 0;
kout << "Address has been successfully freed: " << hex_number((UIntPtr)heap_info_ptr) << kendl;
diff --git a/dev/kernel/src/PageMgr.cc b/dev/kernel/src/PageMgr.cc
index eb7c7e03..6a8622ed 100644
--- a/dev/kernel/src/PageMgr.cc
+++ b/dev/kernel/src/PageMgr.cc
@@ -57,10 +57,10 @@ namespace NeOS
/// @param User user mode?
/// @param ExecDisable disable execution on page?
/// @return
- PTEWrapper PageMgr::Request(Boolean Rw, Boolean User, Boolean ExecDisable, SizeT Sz)
+ PTEWrapper PageMgr::Request(Boolean Rw, Boolean User, Boolean ExecDisable, SizeT Sz, SizeT Pad)
{
// Store PTE wrapper right after PTE.
- VoidPtr ptr = NeOS::HAL::mm_alloc_bitmap(Rw, User, Sz, false);
+ VoidPtr ptr = NeOS::HAL::mm_alloc_bitmap(Rw, User, Sz, NO, Pad);
return PTEWrapper{Rw, User, ExecDisable, reinterpret_cast<UIntPtr>(ptr)};
}
diff --git a/dev/kernel/src/Pmm.cc b/dev/kernel/src/Pmm.cc
index b3d5e79e..a5ba0dcd 100644
--- a/dev/kernel/src/Pmm.cc
+++ b/dev/kernel/src/Pmm.cc
@@ -23,7 +23,7 @@ namespace NeOS
Pmm::Pmm()
: fPageMgr()
{
- kout << "[PMM] Allocate PageMemoryMgr";
+ kout << "[PMM] Allocate PageMemoryMgr.\r";
}
Pmm::~Pmm() = default;
@@ -35,7 +35,7 @@ namespace NeOS
/***********************************************************************************/
Ref<PTEWrapper> Pmm::RequestPage(Boolean user, Boolean readWrite)
{
- PTEWrapper pt = fPageMgr.Leak().Request(user, readWrite, false, kPageSize);
+ PTEWrapper pt = fPageMgr.Leak().Request(user, readWrite, false, kPageSize, 0);
if (pt.fPresent)
{
diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc
index 19861dbe..98abe13c 100644
--- a/dev/kernel/src/UserProcessScheduler.cc
+++ b/dev/kernel/src/UserProcessScheduler.cc
@@ -111,11 +111,11 @@ namespace NeOS
auto vm_register = hal_read_cr3();
hal_write_cr3(this->VMRegister);
- auto ptr = mm_new_heap(sz + pad_amount, Yes, Yes);
+ auto ptr = mm_new_heap(sz, Yes, Yes, pad_amount);
hal_write_cr3(vm_register);
#else
- auto ptr = mm_new_heap(sz + pad_amount, Yes, Yes);
+ auto ptr = mm_new_heap(sz, Yes, Yes, pad_amount);
#endif
if (!this->ProcessMemoryHeap)
@@ -238,15 +238,23 @@ namespace NeOS
if (this->Image.fCode && mm_is_valid_heap(this->Image.fCode))
mm_delete_heap(this->Image.fCode);
+ //! Delete blob too.
if (this->Image.fBlob && mm_is_valid_heap(this->Image.fBlob))
mm_delete_heap(this->Image.fBlob);
+ //! Delete stack frame.
if (this->StackFrame && mm_is_valid_heap(this->StackFrame))
mm_delete_heap((VoidPtr)this->StackFrame);
- this->Image.fBlob = nullptr;
- this->Image.fCode = nullptr;
- this->StackFrame = nullptr;
+ //! Delete stack reserve.
+ if (this->StackReserve && mm_is_valid_heap(this->StackReserve))
+ mm_delete_heap(reinterpret_cast<VoidPtr>(this->StackReserve));
+
+ //! Avoid use after free.
+ this->Image.fBlob = nullptr;
+ this->Image.fCode = nullptr;
+ this->StackFrame = nullptr;
+ this->StackReserve = nullptr;
if (this->Kind == kExectuableDylibKind)
{
@@ -262,10 +270,7 @@ namespace NeOS
this->DylibDelegate = nullptr;
}
- if (this->StackReserve)
- mm_delete_heap(reinterpret_cast<VoidPtr>(this->StackReserve));
-
- this->ProcessId = 0;
+ this->ProcessId = 0UL;
this->Status = ProcessStatusKind::kFinished;
--this->ProcessParentTeam->mProcessCount;
@@ -311,7 +316,7 @@ namespace NeOS
flags |= HAL::kMMFlagsUser;
HAL::mm_map_page((VoidPtr)process.VMRegister, process.VMRegister, flags);
-#endif // __NE_VIRTUAL_MEMORY_SUPPORT__
+#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
process.StackFrame = new HAL::StackFrame();
@@ -327,7 +332,7 @@ namespace NeOS
flags |= HAL::kMMFlagsUser;
HAL::mm_map_page((VoidPtr)process.StackFrame, process.StackFrame, flags);
-#endif // __NE_VIRTUAL_MEMORY_SUPPORT__
+#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
// React according to process kind.
switch (process.Kind)
@@ -357,7 +362,7 @@ namespace NeOS
flags |= HAL::kMMFlagsUser;
HAL::mm_map_page((VoidPtr)process.StackReserve, process.StackReserve, flags);
-#endif // __NE_VIRTUAL_MEMORY_SUPPORT__
+#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
process.ProcessParentTeam = &mTeam;