summaryrefslogtreecommitdiffhomepage
path: root/dev/boot/src
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-05-23 11:12:31 +0200
committerAmlal El Mahrouss <amlal@nekernel.org>2025-05-23 11:13:38 +0200
commit54a0f4c49d9bfb955174c87dae2f442d7f5a8b25 (patch)
treead59d31c9444fcfc6d5f0da7b17c8843710e6014 /dev/boot/src
parentfc67c4af554189c941c811486a0b2b21aa3f54ea (diff)
feat!(Kernel): Improvements on the BitMapMgr, HTS, and UPS.
other: - Add ZXD header file. - Reworking AMD64 interrupts. - Improved HTS's design implementation. - Improved UPS's balancing implementation. breaking changes: - Rename MemoryMgr to HeapMgr. Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'dev/boot/src')
-rw-r--r--dev/boot/src/HEL/AMD64/BootATA.cc256
-rw-r--r--dev/boot/src/HEL/AMD64/BootATAcc (renamed from dev/boot/src/HEL/AMD64/BootATA+Next.cc)4
-rw-r--r--dev/boot/src/HEL/AMD64/BootEFI.cc20
-rw-r--r--dev/boot/src/docs/KERN_VER.md18
-rw-r--r--dev/boot/src/docs/MKFS_HEFS.md106
5 files changed, 131 insertions, 273 deletions
diff --git a/dev/boot/src/HEL/AMD64/BootATA.cc b/dev/boot/src/HEL/AMD64/BootATA.cc
deleted file mode 100644
index 903a650d..00000000
--- a/dev/boot/src/HEL/AMD64/BootATA.cc
+++ /dev/null
@@ -1,256 +0,0 @@
-/* -------------------------------------------
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
-
-------------------------------------------- */
-
-/**
- * @file BootATA.cc
- * @author Amlal El Mahrouss (amlal@nekernel.org)
- * @brief ATA driver.
- * @version 0.1
- * @date 2024-02-02
- *
- * @copyright Copyright (c) Amlal El Mahrouss
- *
- */
-
-#include <BootKit/BootKit.h>
-#include <BootKit/HW/ATA.h>
-#include <FirmwareKit/EFI.h>
-
-#define kATADataLen (256)
-
-/// bugs: 0
-
-using namespace Boot;
-
-static Boolean kATADetected = false;
-static UInt16 kATAData[kATADataLen] = {0};
-
-Boolean boot_ata_detected(Void);
-
-STATIC Boolean boot_ata_wait_io(UInt16 IO) {
- for (int i = 0; i < 400; i++) rt_in8(IO + ATA_REG_STATUS);
-
-ATAWaitForIO_Retry:
- auto status_rdy = rt_in8(IO + ATA_REG_STATUS);
-
- if ((status_rdy & ATA_SR_BSY)) goto ATAWaitForIO_Retry;
-
-ATAWaitForIO_Retry2:
- status_rdy = rt_in8(IO + ATA_REG_STATUS);
-
- if (status_rdy & ATA_SR_ERR) return false;
-
- if (!(status_rdy & ATA_SR_DRDY)) goto ATAWaitForIO_Retry2;
-
- return true;
-}
-
-Void boot_ata_select(UInt16 Bus) {
- if (Bus == ATA_PRIMARY_IO)
- rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_PRIMARY_SEL);
- else
- rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_SECONDARY_SEL);
-}
-
-Boolean boot_ata_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) {
- NE_UNUSED(Drive);
-
- if (boot_ata_detected()) return true;
-
- BootTextWriter writer;
-
- UInt16 IO = Bus;
-
- boot_ata_select(IO);
-
- // Bus init, NEIN bit.
- rt_out8(IO + ATA_REG_NEIN, 1);
-
- // identify until it's good.
-ATAInit_Retry:
- auto status_rdy = rt_in8(IO + ATA_REG_STATUS);
-
- if (status_rdy & ATA_SR_ERR) {
- writer.Write(L"BootZ: ATA: Not an IDE based drive.\r");
-
- return false;
- }
-
- if ((status_rdy & ATA_SR_BSY)) goto ATAInit_Retry;
-
- rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY);
-
- /// fetch serial info
- /// model, speed, number of sectors...
-
- boot_ata_wait_io(IO);
-
- for (SizeT indexData = 0ul; indexData < kATADataLen; ++indexData) {
- kATAData[indexData] = Kernel::HAL::rt_in16(IO + ATA_REG_DATA);
- }
-
- OutBus = (Bus == ATA_PRIMARY_IO) ? BootDeviceATA::kPrimary : BootDeviceATA::kSecondary;
-
- OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE;
-
- // Why? the current disk driver writes whole word instead of a single byte (expected btw) so i'm
- // planning to finish +Next drivers for 0.0.3
- return NO;
-}
-
-Void boot_ata_read(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeASCII* Buf, SizeT SectorSz,
- SizeT Size) {
- Lba /= SectorSz;
-
- UInt8 Command = ((!Master) ? 0xE0 : 0xF0);
-
- boot_ata_wait_io(IO);
- boot_ata_select(IO);
-
- rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F));
-
- rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz));
-
- rt_out8(IO + ATA_REG_LBA0, (Lba) &0xFF);
- rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8);
- rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16);
- rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24);
-
- rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO);
-
- boot_ata_wait_io(IO);
-
- for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) {
- boot_ata_wait_io(IO);
- Buf[IndexOff] = Kernel::HAL::rt_in16(IO + ATA_REG_DATA);
- boot_ata_wait_io(IO);
- }
-}
-
-Void boot_ata_write(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeASCII* Buf, SizeT SectorSz,
- SizeT Size) {
- Lba /= SectorSz;
-
- UInt8 Command = ((!Master) ? 0xE0 : 0xF0);
-
- boot_ata_wait_io(IO);
- boot_ata_select(IO);
-
- rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F));
-
- rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + (SectorSz)) / SectorSz));
-
- rt_out8(IO + ATA_REG_LBA0, (Lba) &0xFF);
- rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8);
- rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16);
- rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24);
-
- rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO);
-
- boot_ata_wait_io(IO);
-
- for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) {
- boot_ata_wait_io(IO);
- rt_out16(IO + ATA_REG_DATA, Buf[IndexOff]);
- boot_ata_wait_io(IO);
- }
-
- boot_ata_wait_io(IO);
-}
-
-/// @check is ATA detected?
-Boolean boot_ata_detected(Void) {
- return kATADetected;
-}
-
-/***
- *
- *
- * @brief ATA Device class.
- *
- *
- */
-
-/**
- * @brief ATA Device constructor.
- * @param void none.
- */
-BootDeviceATA::BootDeviceATA() noexcept {
- if (boot_ata_init(ATA_PRIMARY_IO, true, this->Leak().mBus, this->Leak().mMaster) ||
- boot_ata_init(ATA_SECONDARY_IO, true, this->Leak().mBus, this->Leak().mMaster)) {
- kATADetected = true;
- }
-}
-/**
- * @brief Is ATA detected?
- */
-BootDeviceATA::operator bool() {
- return boot_ata_detected();
-}
-
-/**
- @brief Read Buf from disk
- @param Sz Sector size
- @param Buf buffer
-*/
-BootDeviceATA& BootDeviceATA::Read(CharacterTypeASCII* Buf, SizeT SectorSz) {
- if (!boot_ata_detected()) {
- Leak().mErr = true;
- return *this;
- }
-
- this->Leak().mErr = false;
-
- if (!Buf || SectorSz < 1) return *this;
-
- boot_ata_read(this->Leak().mBase, this->Leak().mBus, this->Leak().mMaster, Buf, SectorSz,
- this->Leak().mSize);
-
- return *this;
-}
-
-/**
- @brief Write Buf into disk
- @param Sz Sector size
- @param Buf buffer
-*/
-BootDeviceATA& BootDeviceATA::Write(CharacterTypeASCII* Buf, SizeT SectorSz) {
- if (!boot_ata_detected()) {
- Leak().mErr = true;
- return *this;
- }
-
- Leak().mErr = false;
-
- if (!Buf || SectorSz < 1 || this->Leak().mSize < 1) {
- Leak().mErr = true;
- return *this;
- }
-
- boot_ata_write(this->Leak().mBase, this->Leak().mBus, this->Leak().mMaster, Buf, SectorSz,
- this->Leak().mSize);
-
- return *this;
-}
-
-/**
- * @brief ATA trait getter.
- * @return BootDeviceATA::ATATrait& the drive config.
- */
-BootDeviceATA::ATATrait& BootDeviceATA::Leak() {
- return mTrait;
-}
-
-/***
- @brief Getter, gets the number of sectors inside the drive.
-*/
-SizeT BootDeviceATA::GetSectorsCount() noexcept {
- return (kATAData[61] << 16) | kATAData[60];
-}
-
-SizeT BootDeviceATA::GetDiskSize() noexcept {
- return this->GetSectorsCount() * BootDeviceATA::kSectorSize;
-}
diff --git a/dev/boot/src/HEL/AMD64/BootATA+Next.cc b/dev/boot/src/HEL/AMD64/BootATAcc
index 547d4f99..4fd6dc16 100644
--- a/dev/boot/src/HEL/AMD64/BootATA+Next.cc
+++ b/dev/boot/src/HEL/AMD64/BootATAcc
@@ -15,8 +15,6 @@
*
*/
-#if 0
-
#include <BootKit/BootKit.h>
#include <BootKit/HW/ATA.h>
#include <FirmwareKit/EFI.h>
@@ -266,5 +264,3 @@ SizeT BootDeviceATA::GetSectorsCount() noexcept {
SizeT BootDeviceATA::GetDiskSize() noexcept {
return this->GetSectorsCount() * BootDeviceATA::kSectorSize;
}
-
-#endif \ No newline at end of file
diff --git a/dev/boot/src/HEL/AMD64/BootEFI.cc b/dev/boot/src/HEL/AMD64/BootEFI.cc
index 1d46b731..84a4d295 100644
--- a/dev/boot/src/HEL/AMD64/BootEFI.cc
+++ b/dev/boot/src/HEL/AMD64/BootEFI.cc
@@ -196,16 +196,6 @@ EFI_EXTERN_C EFI_API Int32 BootloaderMain(EfiHandlePtr image_handle, EfiSystemTa
WideChar kernel_path[256U] = L"krnl.efi";
UInt32 kernel_path_sz = StrLen("krnl.efi");
- if (ST->RuntimeServices->GetVariable(L"/props/kernel_path", kEfiGlobalNamespaceVarGUID, nullptr,
- &kernel_path_sz, kernel_path) != kEfiOk) {
- /// access attributes (in order)
- /// EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS
- UInt32 attr = 0x00000001 | 0x00000002 | 0x00000004;
-
- ST->RuntimeServices->SetVariable(L"/props/kernel_path", kEfiGlobalNamespaceVarGUID, &attr,
- &kernel_path_sz, kernel_path);
- }
-
UInt32 sz_ver = sizeof(UInt64);
UInt64 ver = KERNEL_VERSION_BCD;
@@ -219,6 +209,16 @@ EFI_EXTERN_C EFI_API Int32 BootloaderMain(EfiHandlePtr image_handle, EfiSystemTa
&sz_ver, &ver);
writer.Write("BootZ: Version has been updated: ").Write(ver).Write("\r");
+
+ if (ST->RuntimeServices->GetVariable(L"/props/kernel_path", kEfiGlobalNamespaceVarGUID, nullptr,
+ &kernel_path_sz, kernel_path) != kEfiOk) {
+ /// access attributes (in order)
+ /// EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS
+ UInt32 attr = 0x00000001 | 0x00000002 | 0x00000004;
+
+ ST->RuntimeServices->SetVariable(L"/props/kernel_path", kEfiGlobalNamespaceVarGUID, &attr,
+ &kernel_path_sz, kernel_path);
+ }
} else {
writer.Write("BootZ: Version: ").Write(ver).Write("\r");
}
diff --git a/dev/boot/src/docs/KERN_VER.md b/dev/boot/src/docs/KERN_VER.md
index cabdb1d2..0659431b 100644
--- a/dev/boot/src/docs/KERN_VER.md
+++ b/dev/boot/src/docs/KERN_VER.md
@@ -1,6 +1,18 @@
-# The `/props/kern_ver` NVRAM variable
+# `/props/kern_ver` โ€” NVRAM EFI Variable
The `/props/kern_ver` variable is used to track NeKernel's current version in a BCD format.
-- Use it to track the current's NeKernel version, in order to adapt your drivers to it.
-- It is also useful to keep track of it, for other purposes (bug tracking, development of new features) \ No newline at end of file
+## ๐Ÿ›  Reason
+
+- It is also used for:
+ - Bug tracking and system patching.
+ - Version and compatibility checking.
+
+## ๐Ÿงช Usage
+
+N/A
+
+## ยฉ License
+
+ Copyright (C) 2025,
+ Amlal El Mahrouss โ€“ All rights reserved. \ No newline at end of file
diff --git a/dev/boot/src/docs/MKFS_HEFS.md b/dev/boot/src/docs/MKFS_HEFS.md
new file mode 100644
index 00000000..c9aa0628
--- /dev/null
+++ b/dev/boot/src/docs/MKFS_HEFS.md
@@ -0,0 +1,106 @@
+# `mkfs.hefs` โ€“ HeFS Filesystem Formatter
+
+`mkfs.hefs` is a command-line utility used to format a block device or disk image with the **High-throughput Extended File System (HeFS)** used by NeKernel. This tool initializes a HeFS volume by writing a boot node and configuring directory and inode index regions, block ranges, and volume metadata.
+
+---
+
+## ๐Ÿ›  Features
+
+- Writes a valid `BootNode` to the specified output device or file.
+- Sets disk size, sector size, and volume label.
+- Supports user-defined ranges for:
+ - Index Node Directory (IND)
+ - Inodes (IN)
+ - Data blocks
+- UTF-8 encoded volume label support.
+- Fully compatible with NeKernel's VFS subsystem.
+
+---
+
+## ๐Ÿงช Usage
+
+ mkfs.hefs -L <label> -s <sector_size> \
+ -b <ind_start> -e <ind_end> \
+ -bs <block_start> -be <block_end> \
+ -is <in_start> -ie <in_end> \
+ -S <disk_size> -o <output_device>
+
+---
+
+## ๐Ÿงพ Arguments
+
+| Option | Description |
+|---------------|-------------------------------------------------------------------------|
+| `-L` | Volume label (UTF-8, internally stored as UTF-16) |
+| `-s` | Sector size (e.g., 512) |
+| `-b` `-e` | Start and end addresses for the **Index Node Directory (IND)** region |
+| `-bs` `-be` | Start and end addresses for the **Block** data region |
+| `-is` `-ie` | Start and end addresses for the **Inode** region |
+| `-S` | Disk size in **gigabytes** |
+| `-o` | Path to the output device or image file |
+
+> All address-based inputs (`-b`, `-e`, etc.) must be specified in **hexadecimal** format.
+
+---
+
+## ๐Ÿงท Notes
+
+- Default sector size is `512` bytes.
+- Default volume name is `"HeFS_VOLUME"`, defined as `kHeFSDefaultVolumeName`.
+- The tool writes a `BootNode` at the beginning of the index node range.
+- A CRC-safe magic signature is embedded for boot and integrity validation.
+- After writing the metadata, the tool flushes and closes the file stream.
+
+---
+
+## ๐Ÿ’ป Example
+
+ mkfs.hefs -L "MyHeFS" -s 512 \
+ -b 0x1000 -e 0x8000 \
+ -bs 0x8000 -be 0x800000 \
+ -is 0x800000 -ie 0xA00000 \
+ -S 128 -o hefs.img
+
+This will create a 128 GiB formatted HeFS image named `hefs.img` with specified region boundaries.
+
+---
+
+## ๐Ÿ“ BootNode Structure
+
+The `BootNode` stores key filesystem metadata:
+
+ struct BootNode {
+ char magic[8];
+ char16_t volumeName[64];
+ uint16_t version;
+ uint16_t diskKind;
+ uint16_t encoding;
+ uint64_t diskSize;
+ uint32_t sectorSize;
+ uint64_t startIND, endIND;
+ uint64_t startIN, endIN;
+ uint64_t startBlock, endBlock;
+ uint64_t indCount;
+ uint16_t diskStatus;
+ };
+
+---
+
+## โš ๏ธ Error Handling
+
+- Prints usage and exits on invalid/missing arguments.
+- Exits with error if the output device cannot be opened or written to.
+- Checks for zero sector size or disk size to prevent invalid formatting.
+
+---
+
+## ๐Ÿ“š Source Location
+
+Part of the [HeFS Tooling module](https://github.com/nekernel-org/nekernel) and used during system setup or disk preparation for NeKernel.
+
+---
+
+## ยฉ License
+
+ Copyright (C) 2025,
+ Amlal El Mahrouss โ€“ All rights reserved. \ No newline at end of file