From 609698e032f4d110004908d4eefcc77c43553258 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Mon, 12 May 2025 17:19:50 +0200 Subject: feat: sched, tooling: improving and laying foundations for the future milestones and objectives, such as: driver loading (ifs.sys, ddk.sys, user.sys), and better tooling for application development. Signed-off-by: Amlal El Mahrouss --- tooling/fsck.hefs.cc | 2 -- tooling/mk_app.py | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++ tooling/mk_fwrk.py | 31 +++++++++++--------- 3 files changed, 97 insertions(+), 16 deletions(-) create mode 100755 tooling/mk_app.py (limited to 'tooling') diff --git a/tooling/fsck.hefs.cc b/tooling/fsck.hefs.cc index 96cd36b6..ce586b13 100644 --- a/tooling/fsck.hefs.cc +++ b/tooling/fsck.hefs.cc @@ -15,7 +15,5 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - (void) argv; - return EXIT_SUCCESS; } \ No newline at end of file diff --git a/tooling/mk_app.py b/tooling/mk_app.py new file mode 100755 index 00000000..ef2b64c9 --- /dev/null +++ b/tooling/mk_app.py @@ -0,0 +1,80 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- + +import os +import json +import sys + +def create_directory_structure(base_path, project_name): + # Define the directory structure + structure = { + project_name: { + "dist": { + ".keep": None + }, + "src": { + ".keep": None, + "CommandLine.cc": None, + }, + "vendor": { + ".keep": None + }, + ".keep": None, + f"{project_name}.json": {} + } + } + + def create_structure(path, structure): + for name, content in structure.items(): + current_path = os.path.join(path, name) + # Create directories or files based on the content type + if isinstance(content, dict) and current_path.endswith(".json") == False: + os.makedirs(current_path, exist_ok=True) + create_structure(current_path, content) + elif content is None: + # Create an empty file + with open(current_path, 'w') as f: + pass + + # Create the base directory + os.makedirs(base_path, exist_ok=True) + create_structure(base_path, structure) + + # Create the JSON file + proj_json_path = os.path.join(base_path, project_name, f"{project_name}.json") + + manifest = { + "compiler_path": "clang++", + "compiler_std": "c++20", + "headers_path": ["./", "../../../dev/kernel", "../../../public/frameworks/", "../../../dev/", "./"], + "sources_path": [ + + ], + "output_name": f"./dist/{project_name}", + "cpp_macros": [ + "kSampleFWVersion=0x0100", + "kSampleFWVersionHighest=0x0100", + "kSampleFWVersionLowest=0x0100", + "__NE_SDK__" + ] + } + + with open(proj_json_path, 'w') as json_file: + json.dump(manifest, json_file, indent=4) + + proj_cpp_path = os.path.join(base_path, project_name, f"src/CommandLine.cc") + + cpp_file = "#include \n\nSInt32 _NeMain(SInt32 argc, Char* argv[]) {\n\treturn EXIT_FAILURE;\n}" + + with open(proj_cpp_path, 'w') as cpp_file_io: + cpp_file_io.write(cpp_file) + +if __name__ == "__main__": + if len(sys.argv) != 2: + print("Usage: mk_app.py ") + sys.exit(os.EX_CONFIG) + + base_path = os.getcwd() # Use the current working directory as the base path + create_directory_structure(base_path, sys.argv[1]) + + print("NeKernel Application created successfully.") diff --git a/tooling/mk_fwrk.py b/tooling/mk_fwrk.py index 9bc132e6..89857347 100755 --- a/tooling/mk_fwrk.py +++ b/tooling/mk_fwrk.py @@ -5,7 +5,10 @@ import os import json import sys -def create_directory_structure(base_path, project_name): +""" + Create directory structure for the framework. +""" +def create_directory_structure(base_path_fwrk, project_file_name, project_name): # Define the directory structure structure = { project_name: { @@ -20,12 +23,12 @@ def create_directory_structure(base_path, project_name): ".keep": None }, ".keep": None, - f"{project_name}.json": {} + f"{project_file_name}.json": {} } } - def create_structure(path, structure): - for name, content in structure.items(): + def create_structure(path, structure_in): + for name, content in structure_in.items(): current_path = os.path.join(path, name) # Create directories or files based on the content type if isinstance(content, dict) and current_path.endswith(".json") == False: @@ -37,18 +40,18 @@ def create_directory_structure(base_path, project_name): pass # Create the base directory - os.makedirs(base_path, exist_ok=True) - create_structure(base_path, structure) + os.makedirs(base_path_fwrk, exist_ok=True) + create_structure(base_path_fwrk, structure) # Create the JSON file - proj_json_path = os.path.join(base_path, project_name, f"{project_name}.json") + proj_json_path = os.path.join(base_path_fwrk, project_name, f"{project_file_name}.json") manifest = { "compiler_path": "clang++", "compiler_std": "c++20", "headers_path": ["./", "../../../dev/kernel", "../../../public/frameworks/", "../../../dev/", "./"], "sources_path": [ - + ], "output_name": f"./dist/{project_name}", "cpp_macros": [ @@ -58,13 +61,13 @@ def create_directory_structure(base_path, project_name): "__NE_SDK__" ] } - + with open(proj_json_path, 'w') as json_file: json.dump(manifest, json_file, indent=4) - proj_cpp_path = os.path.join(base_path, project_name, f"src/CommandLine.cc") + proj_cpp_path = os.path.join(base_path_fwrk, project_name, f"src/CommandLine.cc") - cpp_file = "#include \n\nSInt32 _NeMain(SInt32 argc, Char* argv[]) {\n\treturn EXIT_FAILURE;\n}" + cpp_file = "#include \n\nSInt32 _DylibAttach(SInt32 argc, Char* argv[]) {\n\treturn EXIT_FAILURE;\n}" with open(proj_cpp_path, 'w') as cpp_file_io: cpp_file_io.write(cpp_file) @@ -75,6 +78,6 @@ if __name__ == "__main__": sys.exit(os.EX_CONFIG) base_path = os.getcwd() # Use the current working directory as the base path - create_directory_structure(base_path, sys.argv[1]) - - print("NeKernel framework created successfully.") + create_directory_structure(base_path, sys.argv[1], sys.argv[1] + '.fwrk') + + print("NeKernel Framework created successfully.") -- cgit v1.2.3 From 9fcff991059ff5cdbdf71848039e7b56ccd5bc49 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Wed, 14 May 2025 09:53:11 +0200 Subject: feat(kernel): add ddk.sys to the build flow, finished the mk_fwrk CLI. Signed-off-by: Amlal El Mahrouss --- dev/boot/amd64-desktop.make | 2 ++ dev/ddk/src/ddk_rt_cxx.cc | 8 ++++---- dev/user/Opts.h | 15 --------------- dev/user/SciCalls.h | 15 +++++++++++++++ dev/user/src/SystemCalls.cc | 12 ++++++------ public/frameworks/CoreFoundation.fwrk/xml/app.xml | 2 +- public/frameworks/DiskImage.fwrk/xml/app.xml | 7 ++++--- public/frameworks/KernelTest.fwrk/xml/app.xml | 5 +++-- setup_x64.sh | 2 ++ tooling/mk_app.py | 2 +- tooling/mk_fwrk.py | 17 +++++++++++++---- 11 files changed, 51 insertions(+), 36 deletions(-) delete mode 100644 dev/user/Opts.h create mode 100644 dev/user/SciCalls.h (limited to 'tooling') diff --git a/dev/boot/amd64-desktop.make b/dev/boot/amd64-desktop.make index c660df87..b5e49cb0 100644 --- a/dev/boot/amd64-desktop.make +++ b/dev/boot/amd64-desktop.make @@ -76,6 +76,7 @@ KERNEL=krnl.efi SYSCHK=chk.efi BOOTNET=net.efi SCIKIT=user.sys +DDK=ddk.sys .PHONY: invalid-recipe invalid-recipe: @@ -93,6 +94,7 @@ all: compile-amd64 $(COPY) ./modules/BootNet/$(BOOTNET) src/root/$(BOOTNET) $(COPY) ../user/$(SCIKIT) src/root/$(SCIKIT) $(COPY) src/$(BOOTLOADER) src/root/$(BOOTLOADER) + $(COPY) ../ddk/$(DDK) src/root/$(DDK) .PHONY: disk disk: diff --git a/dev/ddk/src/ddk_rt_cxx.cc b/dev/ddk/src/ddk_rt_cxx.cc index 7daf0fcc..3d57e2b9 100644 --- a/dev/ddk/src/ddk_rt_cxx.cc +++ b/dev/ddk/src/ddk_rt_cxx.cc @@ -9,17 +9,17 @@ #include void* operator new(size_t sz) { - return kalloc(sz); + return ::kalloc(sz); } void operator delete(void* ptr) { - kfree(ptr); + ::kfree(ptr); } void* operator new[](size_t sz) { - return kalloc(sz); + return ::kalloc(sz); } void operator delete[](void* ptr) { - kfree(ptr); + ::kfree(ptr); } diff --git a/dev/user/Opts.h b/dev/user/Opts.h deleted file mode 100644 index 4b3b63c1..00000000 --- a/dev/user/Opts.h +++ /dev/null @@ -1,15 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include - -IMPORT_C VoidPtr sci_syscall_arg_1(SizeT id); -IMPORT_C VoidPtr sci_syscall_arg_2(SizeT id, VoidPtr arg1); -IMPORT_C VoidPtr sci_syscall_arg_3(SizeT id, VoidPtr arg1, VoidPtr arg3); -IMPORT_C VoidPtr sci_syscall_arg_4(SizeT id, VoidPtr arg1, VoidPtr arg3, VoidPtr arg4); diff --git a/dev/user/SciCalls.h b/dev/user/SciCalls.h new file mode 100644 index 00000000..4b3b63c1 --- /dev/null +++ b/dev/user/SciCalls.h @@ -0,0 +1,15 @@ +/* ------------------------------------------- + + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include + +IMPORT_C VoidPtr sci_syscall_arg_1(SizeT id); +IMPORT_C VoidPtr sci_syscall_arg_2(SizeT id, VoidPtr arg1); +IMPORT_C VoidPtr sci_syscall_arg_3(SizeT id, VoidPtr arg1, VoidPtr arg3); +IMPORT_C VoidPtr sci_syscall_arg_4(SizeT id, VoidPtr arg1, VoidPtr arg3, VoidPtr arg4); diff --git a/dev/user/src/SystemCalls.cc b/dev/user/src/SystemCalls.cc index f8b6d597..874f607d 100644 --- a/dev/user/src/SystemCalls.cc +++ b/dev/user/src/SystemCalls.cc @@ -4,7 +4,7 @@ ------------------------------------------- */ -#include +#include #include /// @file SystemCalls.cc @@ -63,15 +63,15 @@ IMPORT_C Void IoCloseFile(_Input Ref desc) { } IMPORT_C UInt64 IoSeekFile(_Input Ref desc, _Input UInt64 off) { - auto ret = (UInt64*) sci_syscall_arg_3(3, reinterpret_cast(desc), - reinterpret_cast(&off)); + auto ret = (volatile UInt64*) sci_syscall_arg_3(3, reinterpret_cast(desc), + reinterpret_cast(&off)); MUST_PASS((*ret) != ~0UL); return *ret; } IMPORT_C UInt64 IoTellFile(_Input Ref desc) { - auto ret = (UInt64*) sci_syscall_arg_2(4, reinterpret_cast(desc)); + auto ret = (volatile UInt64*) sci_syscall_arg_2(4, reinterpret_cast(desc)); return *ret; } @@ -80,8 +80,8 @@ IMPORT_C SInt32 PrintOut(_Input IORef desc, const char* fmt, ...) { va_start(args, fmt); - auto ret = (UInt64*) sci_syscall_arg_4(5, reinterpret_cast(desc), - reinterpret_cast(const_cast(fmt)), args); + auto ret = (volatile UInt64*) sci_syscall_arg_4( + 5, reinterpret_cast(desc), reinterpret_cast(const_cast(fmt)), args); va_end(args); diff --git a/public/frameworks/CoreFoundation.fwrk/xml/app.xml b/public/frameworks/CoreFoundation.fwrk/xml/app.xml index 3a2beac4..fe112a09 100644 --- a/public/frameworks/CoreFoundation.fwrk/xml/app.xml +++ b/public/frameworks/CoreFoundation.fwrk/xml/app.xml @@ -1,3 +1,3 @@ - + diff --git a/public/frameworks/DiskImage.fwrk/xml/app.xml b/public/frameworks/DiskImage.fwrk/xml/app.xml index 29d6670f..f498d4ab 100644 --- a/public/frameworks/DiskImage.fwrk/xml/app.xml +++ b/public/frameworks/DiskImage.fwrk/xml/app.xml @@ -1,3 +1,4 @@ - - - + + + + \ No newline at end of file diff --git a/public/frameworks/KernelTest.fwrk/xml/app.xml b/public/frameworks/KernelTest.fwrk/xml/app.xml index f0c48862..e3ff9424 100644 --- a/public/frameworks/KernelTest.fwrk/xml/app.xml +++ b/public/frameworks/KernelTest.fwrk/xml/app.xml @@ -1,3 +1,4 @@ - - + + + \ No newline at end of file diff --git a/setup_x64.sh b/setup_x64.sh index 6afc1633..5eeaafde 100755 --- a/setup_x64.sh +++ b/setup_x64.sh @@ -9,6 +9,8 @@ cd src make sci_asm_io_x64 cd .. btb user.json +cd ../ddk +btb ddk.json cd ../boot make -f amd64-desktop.make efi make -f amd64-desktop.make epm-img diff --git a/tooling/mk_app.py b/tooling/mk_app.py index ef2b64c9..9418cf05 100755 --- a/tooling/mk_app.py +++ b/tooling/mk_app.py @@ -77,4 +77,4 @@ if __name__ == "__main__": base_path = os.getcwd() # Use the current working directory as the base path create_directory_structure(base_path, sys.argv[1]) - print("NeKernel Application created successfully.") + print("Info: Application created successfully.") diff --git a/tooling/mk_fwrk.py b/tooling/mk_fwrk.py index 89857347..3c73e88e 100755 --- a/tooling/mk_fwrk.py +++ b/tooling/mk_fwrk.py @@ -12,14 +12,17 @@ def create_directory_structure(base_path_fwrk, project_file_name, project_name): # Define the directory structure structure = { project_name: { + "headers": { + ".keep": None + }, "dist": { ".keep": None }, "src": { ".keep": None, - "CommandLine.cc": None, + "DylibMain.cc": None, }, - "vendor": { + "xml": { ".keep": None }, ".keep": None, @@ -65,13 +68,19 @@ def create_directory_structure(base_path_fwrk, project_file_name, project_name): with open(proj_json_path, 'w') as json_file: json.dump(manifest, json_file, indent=4) - proj_cpp_path = os.path.join(base_path_fwrk, project_name, f"src/CommandLine.cc") + proj_cpp_path = os.path.join(base_path_fwrk, project_name, f"src/DylibMain.cc") cpp_file = "#include \n\nSInt32 _DylibAttach(SInt32 argc, Char* argv[]) {\n\treturn EXIT_FAILURE;\n}" with open(proj_cpp_path, 'w') as cpp_file_io: cpp_file_io.write(cpp_file) + xml_blob = f"\n" + proj_xml_path = os.path.join(base_path_fwrk, project_name, f"xml/app.xml") + + with open(proj_xml_path, 'w') as cpp_file_io: + cpp_file_io.write(xml_blob) + if __name__ == "__main__": if len(sys.argv) != 2: print("Usage: mk_fwrk.py ") @@ -80,4 +89,4 @@ if __name__ == "__main__": base_path = os.getcwd() # Use the current working directory as the base path create_directory_structure(base_path, sys.argv[1], sys.argv[1] + '.fwrk') - print("NeKernel Framework created successfully.") + print("Info: Framework created successfully.") -- cgit v1.2.3 From c589f92ed0f6e462a976c64d533c1d8a21b2a3ba Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Fri, 16 May 2025 13:35:50 +0200 Subject: feat(kernel): User doesn't store the password directly anymore, it is hashed under a 64-bit FNV algorithm. why? - Better security, so that we're sure that no one else knows about the password. also: - Rename super to MGMT (Management), as it manages a NeKernel machine. - Added a copy of cxxdrv in the nekernel source tree. - Working on the custom manual parser for NeKernel. (PoC) Signed-off-by: Amlal El Mahrouss --- dev/kernel/CompilerKit/Version.h | 8 ++-- dev/kernel/KernelKit/User.h | 10 ++-- dev/kernel/src/FS/NeFS+FileSystemParser.cc | 7 ++- dev/kernel/src/User.cc | 77 +++++++----------------------- public/manuals/nekernel/mgmt.util.man | 20 ++++++++ public/manuals/troff/cxxdrv.7 | 34 +++++++++++++ tooling/manual.py | 9 ++++ 7 files changed, 93 insertions(+), 72 deletions(-) create mode 100644 public/manuals/nekernel/mgmt.util.man create mode 100644 public/manuals/troff/cxxdrv.7 create mode 100644 tooling/manual.py (limited to 'tooling') diff --git a/dev/kernel/CompilerKit/Version.h b/dev/kernel/CompilerKit/Version.h index 93378863..4250531a 100644 --- a/dev/kernel/CompilerKit/Version.h +++ b/dev/kernel/CompilerKit/Version.h @@ -2,8 +2,8 @@ #pragma once -#define BOOTLOADER_VERSION "v0.0.1" -#define KERNEL_VERSION "v0.0.1" +#define BOOTLOADER_VERSION "v0.0.2-bootz" +#define KERNEL_VERSION "v0.0.2-krnl" -#define BOOTLOADER_VERSION_BCD 0x0001 -#define KERNEL_VERSION_BCD 0x0001 +#define BOOTLOADER_VERSION_BCD (0x0002) +#define KERNEL_VERSION_BCD (0x0002) diff --git a/dev/kernel/KernelKit/User.h b/dev/kernel/KernelKit/User.h index 250b1dfc..2a12e41e 100644 --- a/dev/kernel/KernelKit/User.h +++ b/dev/kernel/KernelKit/User.h @@ -22,11 +22,11 @@ ///! We got the Super, Standard (%s format) and Guest user, ///! all are used to make authorization operations on the OS. -#define kSuperUser "OS AUTHORITY/SUPER/%s" +#define kSuperUser "OS AUTHORITY/MGMT/%s" #define kGuestUser "OS AUTHORITY/GUEST/%s" #define kStdUser "OS AUTHORITY/STD/%s" -#define kUsersDir "/user/" +#define kUsersDir "/users/" #define kMaxUserNameLen (256U) #define kMaxUserTokenLen (256U) @@ -45,7 +45,7 @@ enum class UserRingKind { typedef Char* UserPublicKey; typedef Char UserPublicKeyType; -/// @brief User class. +/// @brief System User class. class User final { public: User() = delete; @@ -80,12 +80,12 @@ class User final { /// @brief Checks if a password matches the **password**. /// @param password the password to check. - Bool Matches(const UserPublicKey password) noexcept; + Bool Login(const UserPublicKey password) noexcept; private: UserRingKind mUserRing{UserRingKind::kRingStdUser}; Char mUserName[kMaxUserNameLen] = {0}; - Char mUserKey[kMaxUserTokenLen] = {0}; + UInt64 mUserFNV{0UL}; }; } // namespace Kernel diff --git a/dev/kernel/src/FS/NeFS+FileSystemParser.cc b/dev/kernel/src/FS/NeFS+FileSystemParser.cc index dae69a21..3622e711 100644 --- a/dev/kernel/src/FS/NeFS+FileSystemParser.cc +++ b/dev/kernel/src/FS/NeFS+FileSystemParser.cc @@ -878,7 +878,7 @@ namespace Kernel::NeFS { /// @brief Construct NeFS drives. /***********************************************************************************/ Boolean fs_init_nefs(Void) noexcept { - kout << "Creating main disk...\r"; + kout << "Creating HeFS disk...\r"; kMountpoint.A() = io_construct_main_drive(); @@ -886,9 +886,8 @@ Boolean fs_init_nefs(Void) noexcept { ke_panic(RUNTIME_CHECK_FILESYSTEM, "Main disk cannot be mounted."); NeFileSystemParser parser; - parser.Format(&kMountpoint.A(), 0, kNeFSVolumeName); - - return YES; + + return parser.Format(&kMountpoint.A(), 0, kNeFSVolumeName); } } // namespace Kernel::NeFS diff --git a/dev/kernel/src/User.cc b/dev/kernel/src/User.cc index 3e6aeeba..c1a5ca94 100644 --- a/dev/kernel/src/User.cc +++ b/dev/kernel/src/User.cc @@ -29,20 +29,23 @@ namespace Detail { /// \param password password to hash. /// \return the hashed password //////////////////////////////////////////////////////////// - Int32 user_standard_token_generator(Char* password, const Char* in_password, User* user, - SizeT length) { + STATIC UInt64 user_fnv_generator(const Char* password, User* user) { if (!password || !user) return 1; if (*password == 0) return 1; - kout << "user_standard_token_generator: Hashing user password...\r"; + kout << "user_fnv_generator: Hashing user password...\r"; - for (SizeT i_pass = 0UL; i_pass < length; ++i_pass) { - Char cur_chr = in_password[i_pass]; + const UInt64 FNV_OFFSET_BASIS = 0xcbf29ce484222325ULL; + const UInt64 FNV_PRIME = 0x100000001b3ULL; - password[i_pass] = cur_chr | (user->IsStdUser() ? kStdUserType : kSuperUserType); + UInt64 hash = FNV_OFFSET_BASIS; + + while (*password) { + hash ^= (Utf8Char) (*password++); + hash *= FNV_PRIME; } - kout << "user_standard_token_generator: Hashed user password.\r"; + kout << "user_fnv_generator: Hashed user password.\r"; return 0; } @@ -68,70 +71,26 @@ User::User(const UserRingKind& ring_kind, const Char* user_name) : mUserRing(rin //////////////////////////////////////////////////////////// User::~User() = default; -Bool User::Save(const UserPublicKey password_to_fill) noexcept { - if (!password_to_fill || *password_to_fill == 0) return No; - - SizeT len = rt_string_len(password_to_fill); - - UserPublicKey password = new UserPublicKeyType[len]; - - MUST_PASS(password); - - rt_set_memory(password, 0, len); - - // fill data first, generate hash. - // return false on error. - - rt_copy_memory((VoidPtr) password_to_fill, password, len); - - if (!Detail::user_standard_token_generator(password, password_to_fill, this, len)) { - delete[] password; - password = nullptr; - - return No; - } - - // then store password. - - rt_copy_memory(password, this->mUserKey, rt_string_len(password_to_fill)); +Bool User::Save(const UserPublicKey password) noexcept { + if (!password || *password == 0) return No; - delete[] password; - password = nullptr; + this->mUserFNV = Detail::user_fnv_generator(password, this); kout << "User::Save: Saved password successfully...\r"; return Yes; } -Bool User::Matches(const UserPublicKey password_to_fill) noexcept { - if (!password_to_fill || *password_to_fill) return No; - - SizeT len = rt_string_len(password_to_fill); - - Char* password = new Char[len]; - MUST_PASS(password); - - // fill data first, generate hash. - // return false on error. - - rt_copy_memory((VoidPtr) password_to_fill, password, len); - - if (!Detail::user_standard_token_generator(password, password_to_fill, this, len)) { - delete[] password; - password = nullptr; - - return No; - } - - kout << "User::Matches: Validating hashed passwords...\r"; +Bool User::Login(const UserPublicKey password) noexcept { + if (!password || !*password) return No; // now check if the password matches. - if (rt_string_cmp(password, this->mUserKey, rt_string_len(this->mUserKey)) == 0) { - kout << "User::Matches: Password matches.\r"; + if (this->mUserFNV == Detail::user_fnv_generator(password, this)) { + kout << "User::Login: Password matches.\r"; return Yes; } - kout << "User::Matches: Password doesn't match.\r"; + kout << "User::Login: Password doesn't match.\r"; return No; } diff --git a/public/manuals/nekernel/mgmt.util.man b/public/manuals/nekernel/mgmt.util.man new file mode 100644 index 00000000..929da2d6 --- /dev/null +++ b/public/manuals/nekernel/mgmt.util.man @@ -0,0 +1,20 @@ +Title: mgmt - Management utility command. +Command: mgmt + +Body: + +The management command serves as the main scheduling and management utility of System One. + +Usages include but not limited to: + +- Run certain scripts at X time. +- Verify a device/filesystem integrity. +- Manage and automate other NeKernel machines. + +Example: + +mgmt -s -t 2:30PM -d Wed -m Apr -y 2026 -s pgp-update.script + +Release: + +System One NeKernel diff --git a/public/manuals/troff/cxxdrv.7 b/public/manuals/troff/cxxdrv.7 new file mode 100644 index 00000000..20e28fd4 --- /dev/null +++ b/public/manuals/troff/cxxdrv.7 @@ -0,0 +1,34 @@ +.TH LD64 1 "LibCompiler" "January 2025" "NeKernel Manual" +.SH NAME +.B cxxdrv +\- AE 64-bit C++ compiler for NeKernel + +.SH SYNOPSIS +.B cxxdrv %OPTIONS% %INPUT_FILES% + +.SH DESCRIPTION +.B cxxdrv +is the dedicated compiler used by NeKernel, it compiles to the AE object format. + +.SH OPTIONS +.TP +.B -output +Specify the output file. + +.SH USAGE EXAMPLES +.TP +.B Generate object file from the main.cpp unit. +.B cxxdrv main.cpp + +.SH EXIT STATUS +.TP +0 Successful compilation. +.TP +1 Error encountered during compilation of the C++ unit(s). + +.SH SEE ALSO +.BR cxxdrv (7), asm (7) + +.SH AUTHOR +Amlal El Mahrouss + diff --git a/tooling/manual.py b/tooling/manual.py new file mode 100644 index 00000000..8298559b --- /dev/null +++ b/tooling/manual.py @@ -0,0 +1,9 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- + +import sys, os + +if __name__ == "__main__": + if len(sys.argv) != 2: + print("Usage: manual.py ") + sys.exit(os.EX_CONFIG) -- cgit v1.2.3 From c85a99c2afdd4c9dfa9d8f0f212e4625b6adade7 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Wed, 21 May 2025 03:45:08 +0200 Subject: feat(kernel): source code improvements. Signed-off-by: Amlal El Mahrouss --- compile_flags.txt | 1 - dev/boot/modules/SysChk/SysChk.cc | 1 + dev/boot/src/BootTextWriter.cc | 16 +++- dev/kernel/HALKit/AMD64/HalAPStartup.s | 12 +++ dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc | 67 ++++++++------- .../HALKit/AMD64/HalApplicationProcessorGNU.s | 8 -- .../AMD64/HalApplicationProcessorStartup.asm | 75 ----------------- dev/kernel/HALKit/AMD64/Paging.h | 4 + dev/kernel/HALKit/AMD64/Processor.h | 8 +- dev/kernel/HALKit/AMD64/make_ap_blob.sh | 3 - dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc | 97 ++++++++++------------ dev/kernel/HALKit/ARM64/HalCommonAPI.s | 9 ++ dev/kernel/HALKit/ARM64/HalFlushTLB.S | 9 -- dev/kernel/HALKit/ARM64/HalInterruptAPI.s | 3 + dev/kernel/HALKit/ARM64/HalTimerARM64.cc | 1 + dev/kernel/HALKit/ARM64/Paging.h | 4 + dev/kernel/HALKit/ARM64/Processor.h | 28 +++---- dev/kernel/KernelKit/KernelTaskScheduler.h | 5 +- setup_arm64.sh | 5 -- setup_arm64_project.sh | 5 ++ setup_x64.sh | 18 ---- setup_x64_project.sh | 16 ++++ tooling/mk_img.py | 10 +-- 23 files changed, 170 insertions(+), 235 deletions(-) create mode 100644 dev/kernel/HALKit/AMD64/HalAPStartup.s delete mode 100644 dev/kernel/HALKit/AMD64/HalApplicationProcessorGNU.s delete mode 100644 dev/kernel/HALKit/AMD64/HalApplicationProcessorStartup.asm delete mode 100755 dev/kernel/HALKit/AMD64/make_ap_blob.sh create mode 100644 dev/kernel/HALKit/ARM64/HalCommonAPI.s delete mode 100644 dev/kernel/HALKit/ARM64/HalFlushTLB.S create mode 100644 dev/kernel/HALKit/ARM64/HalInterruptAPI.s delete mode 100755 setup_arm64.sh create mode 100755 setup_arm64_project.sh delete mode 100755 setup_x64.sh create mode 100755 setup_x64_project.sh (limited to 'tooling') diff --git a/compile_flags.txt b/compile_flags.txt index b37b28ae..e9a887a3 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -21,7 +21,6 @@ -D__NE_ED__ -xc++ -D__AHCI__ --D__aarch64__ -DNE_USE_MBCI_FLASH -D__ATA_DMA__ -Wall diff --git a/dev/boot/modules/SysChk/SysChk.cc b/dev/boot/modules/SysChk/SysChk.cc index 4f71ee31..1601148e 100644 --- a/dev/boot/modules/SysChk/SysChk.cc +++ b/dev/boot/modules/SysChk/SysChk.cc @@ -34,6 +34,7 @@ EXTERN_C Int32 SysChkModuleMain(Kernel::HEL::BootInfoHeader* handover) { #elif defined(__AHCI__) Boot::BDiskFormatFactory partition_factory; #endif + if (partition_factory.IsPartitionValid()) return kEfiOk; return partition_factory.Format(kMachineModel); diff --git a/dev/boot/src/BootTextWriter.cc b/dev/boot/src/BootTextWriter.cc index 5e826c6d..6ffb7de6 100644 --- a/dev/boot/src/BootTextWriter.cc +++ b/dev/boot/src/BootTextWriter.cc @@ -24,6 +24,8 @@ @brief puts wrapper over EFI ConOut. */ Boot::BootTextWriter& Boot::BootTextWriter::Write(const CharacterTypeUTF16* str) { + NE_UNUSED(str); + #ifdef __DEBUG__ if (!str || *str == 0) return *this; @@ -50,6 +52,8 @@ Boot::BootTextWriter& Boot::BootTextWriter::Write(const CharacterTypeUTF16* str) /// @brief UTF-8 equivalent of Write (UTF-16). /// @param str the input string. Boot::BootTextWriter& Boot::BootTextWriter::Write(const Char* str) { + NE_UNUSED(str); + #ifdef __DEBUG__ if (!str || *str == 0) return *this; @@ -74,6 +78,8 @@ Boot::BootTextWriter& Boot::BootTextWriter::Write(const Char* str) { } Boot::BootTextWriter& Boot::BootTextWriter::Write(const UChar* str) { + NE_UNUSED(str); + #ifdef __DEBUG__ if (!str || *str == 0) return *this; @@ -101,6 +107,8 @@ Boot::BootTextWriter& Boot::BootTextWriter::Write(const UChar* str) { @brief putc wrapper over EFI ConOut. */ Boot::BootTextWriter& Boot::BootTextWriter::WriteCharacter(CharacterTypeUTF16 c) { + NE_UNUSED(c); + #ifdef __DEBUG__ EfiCharType str[2]; @@ -113,6 +121,8 @@ Boot::BootTextWriter& Boot::BootTextWriter::WriteCharacter(CharacterTypeUTF16 c) } Boot::BootTextWriter& Boot::BootTextWriter::Write(const UInt64& x) { + NE_UNUSED(x); + #ifdef __DEBUG__ this->_Write(x); this->Write("h"); @@ -122,6 +132,8 @@ Boot::BootTextWriter& Boot::BootTextWriter::Write(const UInt64& x) { } Boot::BootTextWriter& Boot::BootTextWriter::_Write(const UInt64& x) { + NE_UNUSED(x); + #ifdef __DEBUG__ UInt64 y = (x > 0 ? x : -x) / 16; UInt64 h = (x > 0 ? x : -x) % 16; @@ -136,9 +148,9 @@ Boot::BootTextWriter& Boot::BootTextWriter::_Write(const UInt64& x) { if (y == ~0UL) y = -y; - const char cNumbers[] = "0123456789ABCDEF"; + const char kNumberList[] = "0123456789ABCDEF"; - this->WriteCharacter(cNumbers[h]); + this->WriteCharacter(kNumberList[h]); #endif // ifdef __DEBUG__ return *this; diff --git a/dev/kernel/HALKit/AMD64/HalAPStartup.s b/dev/kernel/HALKit/AMD64/HalAPStartup.s new file mode 100644 index 00000000..ec17bf7b --- /dev/null +++ b/dev/kernel/HALKit/AMD64/HalAPStartup.s @@ -0,0 +1,12 @@ +.data + +.global hal_ap_blob_start +.global hal_ap_blob_length + +hal_ap_blob_start: + cli + hlt + jmp hal_ap_blob_start + +hal_ap_blob_length: + .long 4 diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc index 46ad8fd6..e4ad1024 100644 --- a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc @@ -4,21 +4,8 @@ ------------------------------------------- */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "NewKit/Defines.h" - #define APIC_MAG "APIC" -#define AP_BLOB_SIZE 126 - #define APIC_ICR_LOW 0x300 #define APIC_ICR_HIGH 0x310 #define APIC_SIPI_VEC 0x00500 @@ -35,6 +22,16 @@ #define APIC_BASE_MSR_BSP 0x100 #define APIC_BASE_MSR_ENABLE 0x800 +#include +#include +#include +#include +#include +#include +#include +#include +#include + /// @note: _hal_switch_context is internal /////////////////////////////////////////////////////////////////////////////////////// @@ -44,8 +41,6 @@ /////////////////////////////////////////////////////////////////////////////////////// namespace Kernel::HAL { -EXTERN_C Void sched_jump_to_task(HAL::StackFramePtr stack_frame); - struct HAL_APIC_MADT; struct HAL_HARDWARE_THREAD; @@ -54,6 +49,8 @@ struct HAL_HARDWARE_THREAD final { ProcessID mThreadID{0}; }; +EXTERN_C Void sched_jump_to_task(HAL::StackFramePtr stack_frame); + STATIC HAL_APIC_MADT* kMADTBlock = nullptr; STATIC Bool kSMPAware = false; STATIC Int64 kSMPCount = 0; @@ -64,6 +61,8 @@ STATIC Int32 kSMPInterrupt = 0; STATIC UInt64 kAPICLocales[kMaxAPInsideSched] = {0}; STATIC VoidPtr kRawMADT = nullptr; +STATIC HAL_HARDWARE_THREAD kHWThread[kSchedProcessLimitPerTeam] = {{}}; + /// @brief Multiple APIC Descriptor Table. struct HAL_APIC_MADT final SDT_OBJECT { UInt32 Address; // Madt address @@ -97,7 +96,10 @@ Void hal_send_ipi_msg(UInt32 target, UInt32 apic_id, UInt8 vector) { } } -STATIC HAL_HARDWARE_THREAD kHWThread[kSchedProcessLimitPerTeam] = {{}}; +/***********************************************************************************/ +/// @brief Get current stack frame for a thread. +/// @param thrdid The thread ID. +/***********************************************************************************/ EXTERN_C HAL::StackFramePtr mp_get_current_context(Int64 thrdid) { const auto process_index = thrdid % kSchedProcessLimitPerTeam; @@ -105,16 +107,28 @@ EXTERN_C HAL::StackFramePtr mp_get_current_context(Int64 thrdid) { return kHWThread[process_index].mFramePtr; } +/***********************************************************************************/ +/// @brief Register current stack frame for a thread. +/// @param stack_frame The current stack frame. +/// @param thrdid The thread ID. +/***********************************************************************************/ + EXTERN_C BOOL mp_register_process(HAL::StackFramePtr stack_frame, ProcessID thrdid) { if (thrdid > kSMPCount) return NO; - if (mp_is_smp()) { - kHWThread[thrdid].mFramePtr = stack_frame; - kHWThread[thrdid].mThreadID = thrdid; + if (!mp_is_smp()) { + if (stack_frame) { + kHWThread[thrdid].mFramePtr = stack_frame; + kHWThread[thrdid].mThreadID = thrdid; + HardwareThreadScheduler::The()[thrdid].Leak()->Busy(NO); - HardwareThreadScheduler::The()[thrdid].Leak()->Busy(NO); + sched_jump_to_task(stack_frame); - sched_jump_to_task(stack_frame); + return YES; + } + } else { + kHWThread[thrdid].mFramePtr = stack_frame; + kHWThread[thrdid].mThreadID = thrdid; return YES; } @@ -130,20 +144,11 @@ Bool mp_is_smp(Void) noexcept { return kSMPAware; } -/***********************************************************************************/ -/// @brief Assembly symbol to bootstrap AP. -/***********************************************************************************/ -EXTERN_C Char* hal_ap_blob_start; - -/***********************************************************************************/ -/// @brief Assembly symbol to bootstrap AP. -/***********************************************************************************/ -EXTERN_C Char* hal_ap_blob_end; - /***********************************************************************************/ /// @brief Fetch and enable SMP scheduler. /// @param vendor_ptr SMP containing structure. /***********************************************************************************/ + Void mp_init_cores(VoidPtr vendor_ptr) noexcept { if (!vendor_ptr) return; diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessorGNU.s b/dev/kernel/HALKit/AMD64/HalApplicationProcessorGNU.s deleted file mode 100644 index a8ad3b76..00000000 --- a/dev/kernel/HALKit/AMD64/HalApplicationProcessorGNU.s +++ /dev/null @@ -1,8 +0,0 @@ -.data - -.global hal_ap_blob_start /* Export the start symbol */ -.global hal_ap_blob_end /* Export the end symbol */ - -hal_ap_blob_start: - .incbin "HALKit/AMD64/HalApplicationProcessorStartup.bin" -hal_ap_blob_end: diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessorStartup.asm b/dev/kernel/HALKit/AMD64/HalApplicationProcessorStartup.asm deleted file mode 100644 index 2adc8fed..00000000 --- a/dev/kernel/HALKit/AMD64/HalApplicationProcessorStartup.asm +++ /dev/null @@ -1,75 +0,0 @@ -;; /* -;; * ======================================================== -;; * -;; * NeKernel -;; * Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. -;; * -;; * 25/03/25: FIX: Fix warning regarding resb being used inside a non-bss area (using no-op instead). -;; * -;; * ======================================================== -;; */ - -[bits 16] -[org 0x7c00] - -hal_ap_start: - mov ax, 0x0 - mov ss, ax - mov esp, 0x7000 - - cli - mov eax, cr0 - or eax, 1 - mov cr0, eax - jmp .hal_ap_start_flush -.hal_ap_start_flush: - mov ax, 0x10 - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - - mov eax, cr4 - or eax, 1 << 5 - mov cr4, eax - - mov eax, cr3 - mov cr3, eax - - mov ecx, 0xC0000080 - rdmsr - or eax, 1 - wrmsr - - mov eax, cr0 - or eax, (1 << 31) - mov cr0, eax - - jmp 0x08:hal_ap_64bit_entry -hal_ap_end: - -hal_ap_length: - dq hal_ap_end - hal_ap_start - -[bits 64] - -hal_ap_64bit_entry: - mov ax, 0x23 - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - - mov rsp, rbx - - push 0x33 - lea rax, [hal_ap_64bit_entry_loop] - push rax - o64 pushf - - o64 iret - -hal_ap_64bit_entry_loop: - jmp $ diff --git a/dev/kernel/HALKit/AMD64/Paging.h b/dev/kernel/HALKit/AMD64/Paging.h index 061bae45..b73b8604 100644 --- a/dev/kernel/HALKit/AMD64/Paging.h +++ b/dev/kernel/HALKit/AMD64/Paging.h @@ -6,6 +6,8 @@ #pragma once +#ifdef __NE_AMD64__ + /** --------------------------------------------------- * THIS FILE CONTAINS CODE FOR X86_64 PAGING. @@ -85,3 +87,5 @@ struct PDE { ATTRIBUTE(aligned(kib_cast(4))) PTE fPTE[512]; }; } // namespace Kernel + +#endif // __NE_AMD64__ \ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/Processor.h b/dev/kernel/HALKit/AMD64/Processor.h index 8fb69c0c..c574f8d5 100644 --- a/dev/kernel/HALKit/AMD64/Processor.h +++ b/dev/kernel/HALKit/AMD64/Processor.h @@ -13,6 +13,8 @@ #pragma once +#ifdef __NE_AMD64__ + #include #include #include @@ -73,7 +75,7 @@ enum { kMMFlagsNX = 1 << 4, kMMFlagsPCD = 1 << 5, kMMFlagsPwt = 1 << 6, - kMMFlagsCount = 4, + kMMFlagsCount = 6, }; struct PACKED Register64 final { @@ -283,4 +285,6 @@ EXTERN_C ATTRIBUTE(naked) Kernel::Void hal_load_gdt(Kernel::HAL::Register64 ptr) inline Kernel::VoidPtr kKernelBitMpStart = nullptr; inline Kernel::UIntPtr kKernelBitMpSize = 0UL; -inline Kernel::VoidPtr kKernelCR3 = nullptr; \ No newline at end of file +inline Kernel::VoidPtr kKernelCR3 = nullptr; + +#endif // __NE_AMD64__ */ \ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/make_ap_blob.sh b/dev/kernel/HALKit/AMD64/make_ap_blob.sh deleted file mode 100755 index 3f079187..00000000 --- a/dev/kernel/HALKit/AMD64/make_ap_blob.sh +++ /dev/null @@ -1,3 +0,0 @@ -# !/bin/sh - -nasm -f bin HalApplicationProcessorStartup.asm -o HalApplicationProcessorStartup.bin \ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc b/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc index d37a3e54..5be41e4e 100644 --- a/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc @@ -4,6 +4,23 @@ ------------------------------------------- */ +#define GICD_BASE 0x08000000 +#define GICC_BASE 0x08010000 + +#define GICD_CTLR 0x000 +#define GICD_ISENABLER 0x100 +#define GICD_ICENABLER 0x180 +#define GICD_ISPENDR 0x200 +#define GICD_ICPENDR 0x280 +#define GICD_IPRIORITYR 0x400 +#define GICD_ITARGETSR 0x800 +#define GICD_ICFGR 0xC00 + +#define GICC_CTLR 0x000 +#define GICC_PMR 0x004 +#define GICC_IAR 0x00C +#define GICC_EOIR 0x010 + #include #include #include @@ -11,28 +28,11 @@ #include #include -#define GICD_BASE 0x08000000 // Distributor base address -#define GICC_BASE 0x08010000 // CPU interface base address - -#define GICD_CTLR 0x000 // Distributor Control Register -#define GICD_ISENABLER 0x100 // Interrupt Set-Enable Registers -#define GICD_ICENABLER 0x180 // Interrupt Clear-Enable Registers -#define GICD_ISPENDR 0x200 // Interrupt Set-Pending Registers -#define GICD_ICPENDR 0x280 // Interrupt Clear-Pending Registers -#define GICD_IPRIORITYR 0x400 // Interrupt Priority Registers -#define GICD_ITARGETSR 0x800 // Interrupt Processor Targets Registers -#define GICD_ICFGR 0xC00 // Interrupt Configuration Registers - -#define GICC_CTLR 0x000 // CPU Interface Control Register -#define GICC_PMR 0x004 // Interrupt Priority Mask Register -#define GICC_IAR 0x00C // Interrupt Acknowledge Register -#define GICC_EOIR 0x010 // End of Interrupt Register - // ================================================================= // namespace Kernel { struct HAL_HARDWARE_THREAD final { - HAL::StackFramePtr mFrame; + HAL::StackFramePtr mFramePtr; ProcessID mThreadID{0}; }; @@ -41,49 +41,37 @@ STATIC HAL_HARDWARE_THREAD kHWThread[kMaxAPInsideSched] = {{nullptr}}; namespace Detail { STATIC BOOL kGICEnabled = NO; - STATIC void mp_hang_fn(void) { - while (YES) - ; - - dbg_break_point(); - } - - Void mp_setup_gic_el0(Void) { - // enable distributor. + /***********************************************************************************/ + /// @brief Enables the GIC with EL0 configuration. + /// @internal + /***********************************************************************************/ + STATIC Void mp_setup_gic_el0(Void) { ke_dma_write(GICD_BASE, GICD_CTLR, YES); UInt32 gicc_ctlr = ke_dma_read(GICC_BASE, GICC_CTLR); - const auto kEnableSignalInt = YES; + const UInt8 kEnableSignalInt = 0x1; - gicc_ctlr |= kEnableSignalInt; // Enable signaling of interrupts - gicc_ctlr |= (kEnableSignalInt << 1); // Allow Group 1 interrupts in EL0 + gicc_ctlr |= kEnableSignalInt; + gicc_ctlr |= (kEnableSignalInt << 0x1); ke_dma_write(GICC_BASE, GICC_CTLR, gicc_ctlr); - // Set priority mask (accept all priorities) ke_dma_write(GICC_BASE, GICC_PMR, 0xFF); UInt32 icfgr = ke_dma_read(GICD_BASE, GICD_ICFGR + (0x20 / 0x10) * 4); - icfgr |= (0x2 << ((32 % 16) * 2)); // Edge-triggered - ke_dma_write(GICD_BASE, GICD_ICFGR + (0x20 / 0x10) * 4, icfgr); + icfgr |= (0x2 << ((32 % 16) * 2)); - // Target interrupt 32 to CPU 1 + ke_dma_write(GICD_BASE, GICD_ICFGR + (0x20 / 0x10) * 4, icfgr); ke_dma_write(GICD_BASE, GICD_ITARGETSR + (0x20 / 0x04) * 4, 0x2 << ((32 % 4) * 8)); - - // Set interrupt 32 priority to lowest (0xFF) ke_dma_write(GICD_BASE, GICD_IPRIORITYR + (0x20 / 0x04) * 4, 0xFF << ((32 % 4) * 8)); - - // Enable interrupt 32 for AP. ke_dma_write(GICD_BASE, GICD_ISENABLER + 4, 0x01); } - BOOL mp_handle_gic_interrupt_el0(Void) { - // Read the interrupt ID + EXTERN_C BOOL mp_handle_gic_interrupt_el0(Void) { UInt32 interrupt_id = ke_dma_read(GICC_BASE, GICC_IAR); - // Check if it's a valid interrupt (not spurious) if ((interrupt_id & 0x3FF) < 1020) { auto interrupt = interrupt_id & 0x3FF; @@ -106,15 +94,25 @@ namespace Detail { return YES; } - // spurious interrupt return NO; } } // namespace Detail +/***********************************************************************************/ +/// @brief Get current stack frame for a thread. +/// @param thrdid The thread ID. +/***********************************************************************************/ + EXTERN_C HAL::StackFramePtr mp_get_current_context(ProcessID thrdid) { - return kHWThread[thrdid].mFrame; + return kHWThread[thrdid].mFramePtr; } +/***********************************************************************************/ +/// @brief Register current stack frame for a thread. +/// @param stack_frame The current stack frame. +/// @param thrdid The thread ID. +/***********************************************************************************/ + EXTERN_C Bool mp_register_process(HAL::StackFramePtr stack_frame, ProcessID thrdid) { MUST_PASS(Detail::kGICEnabled); @@ -123,25 +121,20 @@ EXTERN_C Bool mp_register_process(HAL::StackFramePtr stack_frame, ProcessID thrd const auto process_index = thrdid; - kHWThread[process_index].mFrame = stack_frame; + kHWThread[process_index].mFramePtr = stack_frame; kHWThread[process_index].mThreadID = thrdid; - STATIC HardwareTimer timer{rtl_milliseconds(1000)}; - timer.Wait(); - - HardwareThreadScheduler::The()[thrdid].Leak()->Busy(NO); - return YES; } -/// @internal +/***********************************************************************************/ /// @brief Initialize the Global Interrupt Controller. +/// @internal +/***********************************************************************************/ Void mp_init_cores(Void) noexcept { if (!Detail::kGICEnabled) { Detail::kGICEnabled = YES; Detail::mp_setup_gic_el0(); } - - return Detail::kGICEnabled; } } // namespace Kernel \ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/HalCommonAPI.s b/dev/kernel/HALKit/ARM64/HalCommonAPI.s new file mode 100644 index 00000000..e76b6e3f --- /dev/null +++ b/dev/kernel/HALKit/ARM64/HalCommonAPI.s @@ -0,0 +1,9 @@ +/* (c) 2024-2025 Amlal El Mahrouss */ + +.text + +.global hal_flush_tlb + +hal_flush_tlb: + tlbi + ret diff --git a/dev/kernel/HALKit/ARM64/HalFlushTLB.S b/dev/kernel/HALKit/ARM64/HalFlushTLB.S deleted file mode 100644 index e76b6e3f..00000000 --- a/dev/kernel/HALKit/ARM64/HalFlushTLB.S +++ /dev/null @@ -1,9 +0,0 @@ -/* (c) 2024-2025 Amlal El Mahrouss */ - -.text - -.global hal_flush_tlb - -hal_flush_tlb: - tlbi - ret diff --git a/dev/kernel/HALKit/ARM64/HalInterruptAPI.s b/dev/kernel/HALKit/ARM64/HalInterruptAPI.s new file mode 100644 index 00000000..cafebb7d --- /dev/null +++ b/dev/kernel/HALKit/ARM64/HalInterruptAPI.s @@ -0,0 +1,3 @@ +/* (c) 2024-2025 Amlal El Mahrouss */ + +.text diff --git a/dev/kernel/HALKit/ARM64/HalTimerARM64.cc b/dev/kernel/HALKit/ARM64/HalTimerARM64.cc index 32f64aec..2a595f11 100644 --- a/dev/kernel/HALKit/ARM64/HalTimerARM64.cc +++ b/dev/kernel/HALKit/ARM64/HalTimerARM64.cc @@ -12,3 +12,4 @@ ------------------------------------------- */ #include +#include \ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/Paging.h b/dev/kernel/HALKit/ARM64/Paging.h index 2eb02bc1..88eedcd8 100644 --- a/dev/kernel/HALKit/ARM64/Paging.h +++ b/dev/kernel/HALKit/ARM64/Paging.h @@ -12,6 +12,8 @@ ------------------------------------------------------- */ +#ifdef __NE_ARM64__ + #include #ifndef kPageMax @@ -101,3 +103,5 @@ typedef HAL::PDE_4KB PDE; } // namespace Kernel EXTERN_C void hal_flush_tlb(); + +#endif // __NE_ARM64__ \ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/Processor.h b/dev/kernel/HALKit/ARM64/Processor.h index 9f16d8f5..f52b854f 100644 --- a/dev/kernel/HALKit/ARM64/Processor.h +++ b/dev/kernel/HALKit/ARM64/Processor.h @@ -6,12 +6,14 @@ #pragma once +#ifdef __NE_ARM64__ + #include #include #include #include -#define kCPUBackendName "ARMv8" +#define kCPUBackendName "aarch64" namespace Kernel::HAL { struct PACKED Register64 final { @@ -21,11 +23,11 @@ struct PACKED Register64 final { /// @brief Memory Manager mapping flags. enum { - kMMFlagsPresent = 1 << 0, - kMMFlagsWr = 1 << 1, - kMMFlagsUser = 1 << 2, - kMMFlagsNX = 1 << 3, - kMMFlagsPCD = 1 << 4, + kMMFlagsInvalid = 1 << 0, + kMMFlagsPresent = 1 << 1, + kMMFlagsWr = 1 << 2, + kMMFlagsUser = 1 << 3, + kMMFlagsNX = 1 << 4, kMMFlagsCount = 4, }; @@ -62,16 +64,6 @@ inline Void rt_halt() noexcept { } } -template -inline void hal_dma_write(UIntPtr address, DataKind value) { - *reinterpret_cast(address) = value; -} - -template -inline DataKind hal_dma_read(UIntPtr address) { - return *reinterpret_cast(address); -} - inline Void hal_wfi(Void) { asm volatile("wfi"); } @@ -80,6 +72,8 @@ inline Void hal_wfi(Void) { inline Kernel::VoidPtr kKernelBitMpStart = nullptr; inline Kernel::UIntPtr kKernelBitMpSize = 0UL; -inline Kernel::VoidPtr kKernelPhysicalStart = nullptr; +inline Kernel::VoidPtr kKernelPDE = nullptr; #include + +#endif // __NE_ARM64__ \ No newline at end of file diff --git a/dev/kernel/KernelKit/KernelTaskScheduler.h b/dev/kernel/KernelKit/KernelTaskScheduler.h index 942cd8b4..f4ff4125 100644 --- a/dev/kernel/KernelKit/KernelTaskScheduler.h +++ b/dev/kernel/KernelKit/KernelTaskScheduler.h @@ -15,9 +15,8 @@ #include namespace Kernel { -struct KERNEL_TASK; - -struct KERNEL_TASK final { +class KERNEL_TASK final { +public: Char Name[kSchedNameLen] = {"KERNEL_TASK"}; ProcessSubsystem SubSystem{ProcessSubsystem::kProcessSubsystemDriver}; HAL::StackFramePtr StackFrame{nullptr}; diff --git a/setup_arm64.sh b/setup_arm64.sh deleted file mode 100755 index ffc642d4..00000000 --- a/setup_arm64.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -cd dev/boot -make -f arm64-desktop.make efi -make -f arm64-desktop.make epm-img \ No newline at end of file diff --git a/setup_arm64_project.sh b/setup_arm64_project.sh new file mode 100755 index 00000000..ffc642d4 --- /dev/null +++ b/setup_arm64_project.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +cd dev/boot +make -f arm64-desktop.make efi +make -f arm64-desktop.make epm-img \ No newline at end of file diff --git a/setup_x64.sh b/setup_x64.sh deleted file mode 100755 index 5eeaafde..00000000 --- a/setup_x64.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -# LOG HISTORY: -# 03/25/25: Add 'disk' build step. -# 04/05/25: Improve and fix script. - -cd dev/user -cd src -make sci_asm_io_x64 -cd .. -btb user.json -cd ../ddk -btb ddk.json -cd ../boot -make -f amd64-desktop.make efi -make -f amd64-desktop.make epm-img -cd ../../dev/kernel/HALKit/AMD64 -./make_ap_blob.sh diff --git a/setup_x64_project.sh b/setup_x64_project.sh new file mode 100755 index 00000000..a6115ba7 --- /dev/null +++ b/setup_x64_project.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +# LOG HISTORY: +# 03/25/25: Add 'disk' build step. +# 04/05/25: Improve and fix script. + +cd dev/user +cd src +make sci_asm_io_x64 +cd .. +btb user.json +cd ../ddk +btb ddk.json +cd ../boot +make -f amd64-desktop.make efi +make -f amd64-desktop.make epm-img diff --git a/tooling/mk_img.py b/tooling/mk_img.py index 8227a217..539353fc 100755 --- a/tooling/mk_img.py +++ b/tooling/mk_img.py @@ -24,14 +24,6 @@ def copy_to_fat(image_path, source_dir): command = ["mcopy", "-spm", "-i", image_path] + files_to_copy + ["::"] subprocess.run(command, check=True) - - print(f"Info: Successfully copied contents of '{source_dir}' into '{image_path}'") - except FileNotFoundError: - print("Error: mcopy is not installed. Please install mtools.") - sys.exit(1) - except subprocess.CalledProcessError as e: - print(f"Error: mcopy failed with error code {e.returncode}.") - sys.exit(1) except Exception as e: print(f"Error: failed: {e}") sys.exit(1) @@ -46,4 +38,4 @@ if __name__ == "__main__": copy_to_fat(image_path, source_dir) - print("NeKernel image created successfully.") + print("Info: image created successfully.") -- cgit v1.2.3 From 54a0f4c49d9bfb955174c87dae2f442d7f5a8b25 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Fri, 23 May 2025 11:12:31 +0200 Subject: 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 --- dev/boot/src/HEL/AMD64/BootATA+Next.cc | 270 --------------------- dev/boot/src/HEL/AMD64/BootATA.cc | 256 ------------------- dev/boot/src/HEL/AMD64/BootATAcc | 266 ++++++++++++++++++++ dev/boot/src/HEL/AMD64/BootEFI.cc | 20 +- dev/boot/src/docs/KERN_VER.md | 18 +- dev/boot/src/docs/MKFS_HEFS.md | 106 ++++++++ dev/kernel/HALKit/AMD64/HalACPIFactoryInterface.cc | 2 +- dev/kernel/HALKit/AMD64/HalAPStartup.s | 12 - dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc | 2 - .../HALKit/AMD64/HalApplicationProcessorStartup.s | 14 ++ dev/kernel/HALKit/AMD64/HalCommonAPI.asm | 3 - .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 66 +---- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 1 + dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc | 26 +- dev/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc | 2 +- .../HALKit/ARM64/HalApplicationProcessorStartup.s | 12 + dev/kernel/HALKit/ARM64/HalKernelMain.cc | 2 +- dev/kernel/KernelKit/FileMgr.h | 11 +- dev/kernel/KernelKit/HardwareThreadScheduler.h | 1 - dev/kernel/KernelKit/HeapMgr.h | 58 +++++ dev/kernel/KernelKit/HeapMgr.inl | 35 +++ dev/kernel/KernelKit/MemoryMgr.h | 78 ------ dev/kernel/KernelKit/Zxd.h | 37 +++ dev/kernel/NeKit/Function.h | 1 - dev/kernel/NeKit/New.h | 2 +- dev/kernel/NeKit/Ref.h | 2 +- dev/kernel/src/ACPIFactoryInterface.cc | 2 +- dev/kernel/src/BitMapMgr.cc | 10 +- dev/kernel/src/FS/Ext2+FileMgr.cc | 2 +- dev/kernel/src/FS/HeFS+FileMgr.cc | 2 +- dev/kernel/src/FS/NeFS+FileMgr.cc | 2 +- dev/kernel/src/HardwareThreadScheduler.cc | 13 +- dev/kernel/src/HeapMgr.cc | 260 ++++++++++++++++++++ dev/kernel/src/KPC.cc | 2 +- dev/kernel/src/MemoryMgr.cc | 260 -------------------- dev/kernel/src/New+Delete.cc | 2 +- dev/kernel/src/PEFCodeMgr.cc | 2 +- dev/kernel/src/User.cc | 2 +- dev/kernel/src/UserProcessScheduler.cc | 22 +- docs/drawio/ZXD_DESIGN.drawio | 62 ++--- tooling/mkfs.hefs.cc | 4 +- 41 files changed, 918 insertions(+), 1032 deletions(-) delete mode 100644 dev/boot/src/HEL/AMD64/BootATA+Next.cc delete mode 100644 dev/boot/src/HEL/AMD64/BootATA.cc create mode 100644 dev/boot/src/HEL/AMD64/BootATAcc create mode 100644 dev/boot/src/docs/MKFS_HEFS.md delete mode 100644 dev/kernel/HALKit/AMD64/HalAPStartup.s create mode 100644 dev/kernel/HALKit/AMD64/HalApplicationProcessorStartup.s create mode 100644 dev/kernel/HALKit/ARM64/HalApplicationProcessorStartup.s create mode 100644 dev/kernel/KernelKit/HeapMgr.h create mode 100644 dev/kernel/KernelKit/HeapMgr.inl delete mode 100644 dev/kernel/KernelKit/MemoryMgr.h create mode 100644 dev/kernel/KernelKit/Zxd.h create mode 100644 dev/kernel/src/HeapMgr.cc delete mode 100644 dev/kernel/src/MemoryMgr.cc (limited to 'tooling') diff --git a/dev/boot/src/HEL/AMD64/BootATA+Next.cc b/dev/boot/src/HEL/AMD64/BootATA+Next.cc deleted file mode 100644 index 547d4f99..00000000 --- a/dev/boot/src/HEL/AMD64/BootATA+Next.cc +++ /dev/null @@ -1,270 +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 - * - */ - -#if 0 - -#include -#include -#include - -#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; - - boot_ata_select(IO); - - rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); - - /// fetch serial info - /// model, speed, number of sectors... - - while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)); - - for (SizeT indexData = 0ul; indexData < kATADataLen; ++indexData) { - kATAData[indexData] = rt_in16(IO + ATA_REG_DATA); - } - - OutBus = (Bus == ATA_PRIMARY_IO) ? BootDeviceATA::kPrimary : BootDeviceATA::kSecondary; - - OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; - - return true; -} - -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); - - while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)); - - for (SizeT IndexOff = 0; IndexOff < Size; IndexOff += 2) { - boot_ata_wait_io(IO); - - auto in = rt_in16(IO + ATA_REG_DATA); - - Buf[IndexOff] = in & 0xFF; - Buf[IndexOff + 1] = (in >> 8) & 0xFF; - 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); - - while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)); - - for (SizeT IndexOff = 0; IndexOff < Size; IndexOff += 2) { - boot_ata_wait_io(IO); - - UInt8 low = (UInt8) Buf[IndexOff]; - UInt8 high = (IndexOff + 1 < Size) ? (UInt8) Buf[IndexOff + 1] : 0; - UInt16 packed = (high << 8) | low; - - rt_out16(IO + ATA_REG_DATA, packed); - - 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; -} - -#endif \ No newline at end of file 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 -#include -#include - -#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/BootATAcc b/dev/boot/src/HEL/AMD64/BootATAcc new file mode 100644 index 00000000..4fd6dc16 --- /dev/null +++ b/dev/boot/src/HEL/AMD64/BootATAcc @@ -0,0 +1,266 @@ +/* ------------------------------------------- + + 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 +#include +#include + +#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; + + boot_ata_select(IO); + + rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); + + /// fetch serial info + /// model, speed, number of sectors... + + while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)); + + for (SizeT indexData = 0ul; indexData < kATADataLen; ++indexData) { + kATAData[indexData] = rt_in16(IO + ATA_REG_DATA); + } + + OutBus = (Bus == ATA_PRIMARY_IO) ? BootDeviceATA::kPrimary : BootDeviceATA::kSecondary; + + OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; + + return true; +} + +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); + + while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)); + + for (SizeT IndexOff = 0; IndexOff < Size; IndexOff += 2) { + boot_ata_wait_io(IO); + + auto in = rt_in16(IO + ATA_REG_DATA); + + Buf[IndexOff] = in & 0xFF; + Buf[IndexOff + 1] = (in >> 8) & 0xFF; + 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); + + while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)); + + for (SizeT IndexOff = 0; IndexOff < Size; IndexOff += 2) { + boot_ata_wait_io(IO); + + UInt8 low = (UInt8) Buf[IndexOff]; + UInt8 high = (IndexOff + 1 < Size) ? (UInt8) Buf[IndexOff + 1] : 0; + UInt16 packed = (high << 8) | low; + + rt_out16(IO + ATA_REG_DATA, packed); + + 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/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