<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ícaro</title>
    <description>The latest articles on DEV Community by Ícaro (@icarotelesdasilva).</description>
    <link>https://dev.to/icarotelesdasilva</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4123778%2F9278b1fc-d113-45a7-907e-42ab725ea57e.jpeg</url>
      <title>DEV Community: Ícaro</title>
      <link>https://dev.to/icarotelesdasilva</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/icarotelesdasilva"/>
    <language>en</language>
    <item>
      <title>Bare-metal hardware freeze in NexisK development</title>
      <dc:creator>Ícaro</dc:creator>
      <pubDate>Thu, 17 Sep 2026 17:52:22 +0000</pubDate>
      <link>https://dev.to/icarotelesdasilva/bare-metal-hardware-freeze-in-nexisk-development-2gce</link>
      <guid>https://dev.to/icarotelesdasilva/bare-metal-hardware-freeze-in-nexisk-development-2gce</guid>
      <description>&lt;p&gt;Hello everyone,&lt;br&gt;
Could anyone assist me with an issue I have been encountering recently?&lt;/p&gt;

&lt;p&gt;I am a low-level software developer working on NexisK (project repository: &lt;a href="https://github.com/icarotelesdasilva/NexisK" rel="noopener noreferrer"&gt;https://github.com/icarotelesdasilva/NexisK&lt;/a&gt;). &lt;/p&gt;

&lt;p&gt;I am facing a specific issue in unreleased kernel commits that I have not been able to resolve:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The custom bootloader loads normally.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The bootloader menu displays correctly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Upon pressing Enter, the system successfully transitions to 32-bit protected mode and enters VGA text mode.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Immediately afterward, the system freezes completely, with the VGA text cursor blinking indefinitely.&lt;br&gt;
Steps already taken:&lt;br&gt;
Removed the GDT post-bootloader phase.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Stripped out most critical kernel routines and services, among other diagnostic attempts, but the issue persists.&lt;/p&gt;

&lt;p&gt;I have attached a video demonstrating the behavior.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/..." class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/..." alt="Uploading image" width="800" height="400"&gt;&lt;/a&gt; If anyone is willing to help investigate, I can share the uncommitted codebase branch reproducing this bug.&lt;/p&gt;

&lt;p&gt;Thank you in advance for any insights.&lt;/p&gt;

</description>
      <category>help</category>
      <category>osdev</category>
      <category>c</category>
      <category>assembly</category>
    </item>
    <item>
      <title>What do you think of this kernel compilation method?</title>
      <dc:creator>Ícaro</dc:creator>
      <pubDate>Tue, 15 Sep 2026 21:18:55 +0000</pubDate>
      <link>https://dev.to/icarotelesdasilva/what-do-you-think-of-this-kernel-compilation-method-1fmj</link>
      <guid>https://dev.to/icarotelesdasilva/what-do-you-think-of-this-kernel-compilation-method-1fmj</guid>
      <description>&lt;p&gt;I’ve been exploring a new way to develop my programming language and evolve it gradually alongside my kernel project.&lt;/p&gt;

&lt;p&gt;While working on NexisK and NexisLoader, I started thinking about the build process itself. Running make all is practical, but it is also generic. It works, but it does not really reflect the kind of system I want to build.&lt;/p&gt;

&lt;p&gt;That led me to a different idea: what if I created a compiler within my open-source kernel that could read a user-created build.nexis file, parse its own build syntax, and then invoke the actual Makefile?&lt;/p&gt;

&lt;p&gt;The idea is still in its early stages. I would need to define the syntax, design the parser, and determine how the compiler would interact with the build system. There are also several technical questions to solve, especially regarding how the kernel would handle file access, process execution, and communication with the build tools.&lt;/p&gt;

&lt;p&gt;However, that is part of what makes the project interesting to me.&lt;/p&gt;

&lt;p&gt;I do not want to create another language simply by adding a different syntax to existing instructions. I want to understand how the different components work together, from parsing source code to executing commands and managing the build process.&lt;/p&gt;

&lt;p&gt;The build.nexis file could eventually become a way to describe how a project should be built, while the compiler would interpret that description and coordinate the necessary steps.&lt;/p&gt;

&lt;p&gt;This is not about replacing Make because it is bad. Make already solves a real problem. My goal is to experiment with a different approach and use the project as an opportunity to deepen my understanding of compiler development, language design, and operating systems.&lt;/p&gt;

&lt;p&gt;I am still defining what this language should become, but I think connecting it to my kernel could make the development process more interesting and give it a more specific purpose.&lt;/p&gt;

&lt;p&gt;What do you think about this approach?&lt;/p&gt;

</description>
      <category>osdev</category>
      <category>kernel</category>
      <category>langchain</category>
      <category>learning</category>
    </item>
    <item>
      <title>The Hell Documentation</title>
      <dc:creator>Ícaro</dc:creator>
      <pubDate>Tue, 15 Sep 2026 00:19:57 +0000</pubDate>
      <link>https://dev.to/icarotelesdasilva/the-hell-documentation-4k28</link>
      <guid>https://dev.to/icarotelesdasilva/the-hell-documentation-4k28</guid>
      <description>&lt;p&gt;Anyone who has worked with OS development, especially beginners like me, has probably encountered problems with documentation. I am not writing this as a complaint or an attack on documentation. I simply want to share some of the frustrations I have experienced while developing my kernel.&lt;/p&gt;

&lt;p&gt;When Documentation Does Not Tell You What to Do&lt;/p&gt;

&lt;p&gt;I have faced many frustrating situations that had nothing to do with triple faults or similar problems. The real difficulty was figuring out how to implement something using documentation alone, without relying on AI.&lt;/p&gt;

&lt;p&gt;That does not mean documentation is useless. Quite the opposite. It is extremely valuable and provides a great deal of help. The problem is that when you do not know what to do, documentation often does not explain the implementation directly.&lt;/p&gt;

&lt;p&gt;For example, consider the OSDev Wiki documentation about the PIC:&lt;/p&gt;

&lt;p&gt;Each chip (master and slave) has a command port and a data port, as shown in the table below. When no command is issued, the data port allows access to the interrupt mask register of the 8259 PIC.&lt;/p&gt;

&lt;p&gt;Chip    Purpose I/O Port&lt;br&gt;
Master PIC  Command 0x0020&lt;br&gt;
Master PIC  Data    0x0021&lt;br&gt;
Slave PIC   Command 0x00A0&lt;br&gt;
Slave PIC   Data    0x00A1&lt;/p&gt;

&lt;p&gt;The documentation also explains that PIC vector offsets must be divisible by 8, that changing them requires reinitializing the PIC, and that the previous configuration must be restored when returning to real mode.&lt;/p&gt;

&lt;p&gt;All of that information is useful. However, it does not directly explain what I should actually do to configure the PIC in my kernel.&lt;/p&gt;

&lt;p&gt;And before someone says, “It does explain it. You just did not read it properly or skipped the fundamentals.”&lt;/p&gt;

&lt;p&gt;No. I read the documentation before going to AI.&lt;/p&gt;

&lt;p&gt;Learning Through Implementation&lt;/p&gt;

&lt;p&gt;I use AI to teach me and provide instructions when I get stuck. I then implement the concepts myself based on what I learn.&lt;/p&gt;

&lt;p&gt;For example, after studying the PIC documentation, I learned how to remap the interrupt vectors and initialize the master and slave PICs.&lt;/p&gt;

&lt;p&gt;Here is the actual PIC remapping code from my kernel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;outb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0x20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x11&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;outb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xA0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x11&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;outb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0x21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;offset1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;outb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xA1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;offset2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;outb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0x21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x04&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;outb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xA1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x02&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;outb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0x21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x01&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;outb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xA1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x01&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;outb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0x21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;outb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xA1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The point is not that I cannot read documentation. The point is that understanding a technical description and knowing how to turn it into working code are two different skills.&lt;/p&gt;

&lt;p&gt;Documentation can tell you what a register does, which ports exist, and what values mean. But when you are still learning, the gap between that information and a working implementation can be enormous.&lt;/p&gt;

&lt;p&gt;What I Am Trying to Say&lt;/p&gt;

&lt;p&gt;I am not asking for documentation to explain every line of code. That would be unrealistic.&lt;/p&gt;

&lt;p&gt;What I am saying is that beginners often need more than a description of the hardware. They need to understand the sequence of operations, why those operations are necessary, and how the different pieces fit together.&lt;/p&gt;

&lt;p&gt;That is where I have found AI useful. Not as a replacement for documentation, but as a way to understand what the documentation is trying to tell me.&lt;/p&gt;

&lt;p&gt;I still have a lot to learn about OS development, and I am sure I will encounter many more situations like this.&lt;/p&gt;

&lt;p&gt;That is all I wanted to share. If anyone has advice on how to study documentation more effectively, especially when working on low-level systems, I would be glad to hear it.&lt;/p&gt;

</description>
      <category>osdev</category>
      <category>documentation</category>
      <category>x86</category>
      <category>frustation</category>
    </item>
    <item>
      <title>The use of AI in 2026 what do you think?</title>
      <dc:creator>Ícaro</dc:creator>
      <pubDate>Mon, 14 Sep 2026 20:37:29 +0000</pubDate>
      <link>https://dev.to/icarotelesdasilva/the-use-of-ai-in-2026-what-do-you-think-15aa</link>
      <guid>https://dev.to/icarotelesdasilva/the-use-of-ai-in-2026-what-do-you-think-15aa</guid>
      <description>&lt;p&gt;Hi, my name is Ícaro Teles; I’m a 14-year-old Brazilian teenager (as of 2026). I started out in the tech world six years ago, and I’ve noticed that nowadays, 90% of programmers don't read articles or seek to learn anymore—they just practice what's known as "vibecoding." In my opinion, AI &lt;em&gt;should&lt;/em&gt; be used, but for learning purposes—not just for copy-pasting. What do you think about that?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>discuss</category>
      <category>learning</category>
      <category>programming</category>
    </item>
    <item>
      <title>Building NexisK: A Technical Deep Dive into My i386 Kernel</title>
      <dc:creator>Ícaro</dc:creator>
      <pubDate>Mon, 14 Sep 2026 02:41:12 +0000</pubDate>
      <link>https://dev.to/icarotelesdasilva/building-nexisk-a-technical-deep-dive-into-my-i386-kernel-47ai</link>
      <guid>https://dev.to/icarotelesdasilva/building-nexisk-a-technical-deep-dive-into-my-i386-kernel-47ai</guid>
      <description>&lt;p&gt;Building NexisK: Inside My i386 Kernel, Custom Bootloader and Memory Management&lt;/p&gt;

&lt;p&gt;Building an operating system kernel from scratch is not primarily about displaying text on a screen. It is about establishing a controlled execution environment on hardware that initially knows nothing about my kernel.&lt;/p&gt;

&lt;p&gt;Before my code can manage memory, receive interrupts, execute processes or provide system calls, it must first solve a more fundamental problem: how to take control of the machine reliably.&lt;/p&gt;

&lt;p&gt;That is the problem I am working on with NexisK, an experimental 32-bit x86 kernel built from scratch using C and NASM assembly.&lt;/p&gt;

&lt;p&gt;The project currently targets the i386 architecture, uses a custom BIOS bootloader, enters protected mode, discovers physical memory through BIOS E820, initializes interrupt infrastructure and contains the early foundations of physical memory management, system calls and process execution.&lt;/p&gt;

&lt;p&gt;This article explains the architecture, the decisions behind it, the current implementation and the engineering lessons I have learned while building it.&lt;/p&gt;

&lt;p&gt;The goal is not to present NexisK as a finished operating system. It is to show what exists, what works, what remains incomplete and why each subsystem matters.&lt;/p&gt;

&lt;p&gt;Introduction&lt;/p&gt;

&lt;p&gt;My current release is NexisK v0.8.9.&lt;/p&gt;

&lt;p&gt;The project is organized around a simple principle: implement the mechanisms that an operating system depends on instead of hiding them behind an existing operating-system framework.&lt;/p&gt;

&lt;p&gt;NexisK currently includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A custom two-stage BIOS bootloader.&lt;/li&gt;
&lt;li&gt;32-bit i386 protected-mode execution.&lt;/li&gt;
&lt;li&gt;Global Descriptor Table initialization.&lt;/li&gt;
&lt;li&gt;Interrupt Descriptor Table infrastructure.&lt;/li&gt;
&lt;li&gt;CPU exception handling.&lt;/li&gt;
&lt;li&gt;Programmable Interrupt Controller configuration.&lt;/li&gt;
&lt;li&gt;Programmable Interval Timer support.&lt;/li&gt;
&lt;li&gt;Keyboard and PS/2 mouse interrupt handling.&lt;/li&gt;
&lt;li&gt;VGA text output.&lt;/li&gt;
&lt;li&gt;Serial debugging output.&lt;/li&gt;
&lt;li&gt;Basic system-call infrastructure.&lt;/li&gt;
&lt;li&gt;BIOS E820 physical memory discovery.&lt;/li&gt;
&lt;li&gt;An initial Physical Memory Manager.&lt;/li&gt;
&lt;li&gt;Initial process and context-switching infrastructure.&lt;/li&gt;
&lt;li&gt;A preliminary userspace directory structure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The kernel is written primarily in C, with NASM assembly used where direct control over processor state and machine instructions is required.&lt;/p&gt;

&lt;p&gt;The repository contains 33 commits at the time of writing, and the current release tracks the development milestone v0.8.9.&lt;/p&gt;

&lt;p&gt;Source code:&lt;/p&gt;

&lt;p&gt;GitHub: NexisK&lt;/p&gt;

&lt;p&gt;Why I Built a Kernel from Scratch&lt;/p&gt;

&lt;p&gt;There are many ways to build software for a computer. Most application development starts with an operating system that already provides memory management, process isolation, drivers, filesystems and hardware abstractions.&lt;/p&gt;

&lt;p&gt;Kernel development starts before those services exist.&lt;/p&gt;

&lt;p&gt;I wanted to understand the boundary between software and hardware directly.&lt;/p&gt;

&lt;p&gt;What happens when the processor begins executing my boot code?&lt;/p&gt;

&lt;p&gt;How does the CPU move from firmware execution into protected mode?&lt;/p&gt;

&lt;p&gt;How does a kernel discover which physical memory is available?&lt;/p&gt;

&lt;p&gt;How does an interrupt reach the correct handler?&lt;/p&gt;

&lt;p&gt;How does a system call cross from a process into kernel code?&lt;/p&gt;

&lt;p&gt;These questions are connected. A failure in one layer can prevent every layer above it from working.&lt;/p&gt;

&lt;p&gt;For example, a broken GDT can prevent protected-mode execution. An incorrect IDT can cause exceptions to jump to invalid addresses. A faulty memory manager can overwrite kernel structures. A bad context switch can corrupt the execution state of a process.&lt;/p&gt;

&lt;p&gt;The architecture must therefore be developed from the bottom upward.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             APPLICATIONS
                  │
                  ▼
              USERSPACE
                  │
                  ▼
             SYSTEM CALLS
                  │
                  ▼
             PROCESS MODEL
                  │
                  ▼
            VIRTUAL MEMORY
                  │
                  ▼
           PHYSICAL MEMORY
                  │
                  ▼
                CPU
                  │
                  ▼
              HARDWARE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is the reason I chose to build the kernel instead of starting with a higher-level operating-system framework.&lt;/p&gt;

&lt;p&gt;Architecture&lt;/p&gt;

&lt;p&gt;NexisK is a 32-bit x86 kernel. Its current execution environment is i386 protected mode.&lt;/p&gt;

&lt;p&gt;The architecture is divided into several subsystems:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                     NexisK
                       │
      ┌────────────────┼────────────────┐
      │                │                │
      ▼                ▼                ▼
    CPU            Interrupts         Drivers
      │                │                │
      └────────────────┼────────────────┘
                       │
                       ▼
               Memory Discovery
                       │
                       ▼
              Physical Memory
                 Management
                       │
                       ▼
                Virtual Memory
                       │
                       ▼
                  Processes
                       │
                       ▼
                System Calls
                       │
                       ▼
                   Userspace
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is the intended dependency direction, not a claim that every layer is complete.&lt;/p&gt;

&lt;p&gt;The current kernel has an initial physical memory manager, while virtual memory and process management remain under development.&lt;/p&gt;

&lt;p&gt;Technical Configuration&lt;/p&gt;

&lt;p&gt;Component   Implementation&lt;br&gt;
Architecture    i386 / x86-32&lt;br&gt;
CPU mode    Protected mode&lt;br&gt;
Kernel language C&lt;br&gt;
Assembly    NASM&lt;br&gt;
Bootloader  Custom BIOS bootloader&lt;br&gt;
Boot structure  Stage 1 + Stage 2&lt;br&gt;
Memory discovery    BIOS E820&lt;br&gt;
Interrupt controller    PIC&lt;br&gt;
Timer   PIT&lt;br&gt;
Display VGA text mode&lt;br&gt;
Debugging   Serial output&lt;br&gt;
System calls    int 0x80&lt;br&gt;
Emulator    QEMU&lt;br&gt;
Build system    GNU Make&lt;br&gt;
License GPL-2.0-only&lt;/p&gt;

&lt;p&gt;The kernel is not currently a complete operating-system distribution. It does not provide a complete filesystem ecosystem, production-ready userspace or a Linux-like environment.&lt;/p&gt;

&lt;p&gt;That distinction matters because the engineering requirements of a kernel and a complete operating system are different.&lt;/p&gt;

&lt;p&gt;The Bootloader&lt;/p&gt;

&lt;p&gt;The bootloader is the first major component of NexisK.&lt;/p&gt;

&lt;p&gt;Instead of relying on GRUB or Limine, I maintain a separate custom BIOS bootloader responsible for preparing the machine and loading the kernel.&lt;/p&gt;

&lt;p&gt;The boot process is divided into two stages.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                     BIOS
                       │
                       ▼
                   Stage 1
                       │
                       ▼
                   Stage 2
                       │
        ┌──────────────┼──────────────┐
        │              │              │
        ▼              ▼              ▼
    Initialize      Boot Menu       E820
    Environment      Selection      Detection
        │              │              │
        └──────────────┼──────────────┘
                       │
                       ▼
                 Kernel Loading
                       │
                       ▼
                    NexisK
                       │
                       ▼
                      kmain
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Stage 1 is the initial boot sector. Its job is to begin execution and load Stage 2.&lt;/p&gt;

&lt;p&gt;Stage 2 handles the more substantial boot work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Boot initialization.&lt;/li&gt;
&lt;li&gt;Kernel selection.&lt;/li&gt;
&lt;li&gt;Memory map detection.&lt;/li&gt;
&lt;li&gt;Kernel loading.&lt;/li&gt;
&lt;li&gt;Transfer of control to the kernel.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The bootloader also generates the bootable disk image and ISO used by the project.&lt;/p&gt;

&lt;p&gt;The current disk-image layout is based on a 1.44 MB floppy-style image, which is then packaged as an El Torito bootable ISO.&lt;/p&gt;

&lt;p&gt;build/&lt;br&gt;
├── stage1.bin&lt;br&gt;
├── stage2.bin&lt;br&gt;
├── disk.img&lt;br&gt;
├── iso/&lt;br&gt;
│   └── boot.img&lt;br&gt;
└── NexisK.iso&lt;/p&gt;

&lt;p&gt;Why Separate the Bootloader from the Kernel?&lt;/p&gt;

&lt;p&gt;The bootloader and kernel solve different problems.&lt;/p&gt;

&lt;p&gt;The bootloader must understand the firmware environment, load the kernel and provide the information required for kernel initialization.&lt;/p&gt;

&lt;p&gt;The kernel must establish its own runtime environment and manage the machine after control is transferred.&lt;/p&gt;

&lt;p&gt;Keeping these components separate makes their responsibilities clearer.&lt;/p&gt;

&lt;p&gt;It also makes the bootloader reusable. A boot manager should eventually be able to load more than one kernel, expose hardware information and provide a stable interface between firmware and operating-system code.&lt;/p&gt;

&lt;p&gt;That is one of the reasons I maintain the bootloader as a separate project.&lt;/p&gt;

&lt;p&gt;CPU Initialization and Protected Mode&lt;/p&gt;

&lt;p&gt;NexisK targets the i386 architecture and executes in 32-bit protected mode.&lt;/p&gt;

&lt;p&gt;Protected mode changes the environment in which the kernel executes. Segment descriptors, privilege levels and interrupt handling become central parts of the system.&lt;/p&gt;

&lt;p&gt;The Global Descriptor Table provides the segment descriptors used by the CPU.&lt;/p&gt;

&lt;p&gt;The current kernel contains GDT initialization and the basic protected-mode execution environment.&lt;/p&gt;

&lt;p&gt;The general transition is:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;              Real Mode
                  │
                  ▼
          Load GDT Descriptor
                  │
                  ▼
          Enable Protected Mode
                  │
                  ▼
            Far Jump
                  │
                  ▼
          32-bit Kernel Code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The GDT is not an optional decoration. The processor needs valid segment configuration to execute protected-mode code correctly.&lt;/p&gt;

&lt;p&gt;This is one of the first places where a kernel stops behaving like an ordinary C program.&lt;/p&gt;

&lt;p&gt;The compiler can generate C instructions, but it cannot independently establish the processor environment in which those instructions are valid.&lt;/p&gt;

&lt;p&gt;That work belongs to the low-level initialization code.&lt;/p&gt;

&lt;p&gt;What I Learned&lt;/p&gt;

&lt;p&gt;A kernel cannot treat CPU initialization as a single function that is called and forgotten.&lt;/p&gt;

&lt;p&gt;The processor state, descriptor tables and execution mode determine whether the rest of the kernel can run.&lt;/p&gt;

&lt;p&gt;A useful debugging strategy is to verify each transition independently:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Confirm that the bootloader executes.&lt;/li&gt;
&lt;li&gt;Confirm that Stage 2 executes.&lt;/li&gt;
&lt;li&gt;Confirm that the kernel is loaded at the expected address.&lt;/li&gt;
&lt;li&gt;Confirm that protected mode is entered.&lt;/li&gt;
&lt;li&gt;Confirm that the kernel reaches kmain.&lt;/li&gt;
&lt;li&gt;Only then begin debugging higher-level initialization.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This reduces the number of possible causes when the machine stops responding.&lt;/p&gt;

&lt;p&gt;Interrupt Architecture&lt;/p&gt;

&lt;p&gt;Interrupts are the mechanism through which the processor reacts to events that are not part of the current sequential instruction flow.&lt;/p&gt;

&lt;p&gt;NexisK contains infrastructure for CPU exceptions and hardware interrupts.&lt;/p&gt;

&lt;p&gt;The main components are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Interrupt Descriptor Table.&lt;/li&gt;
&lt;li&gt;CPU exception handlers.&lt;/li&gt;
&lt;li&gt;Programmable Interrupt Controller.&lt;/li&gt;
&lt;li&gt;Programmable Interval Timer.&lt;/li&gt;
&lt;li&gt;Keyboard interrupt handler.&lt;/li&gt;
&lt;li&gt;PS/2 mouse interrupt handler.&lt;/li&gt;
&lt;li&gt;System-call interrupt vector.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The IDT associates interrupt vectors with handler entry points.&lt;/p&gt;

&lt;p&gt;The PIC is responsible for managing hardware interrupt requests.&lt;/p&gt;

&lt;p&gt;The PIT provides timer events.&lt;/p&gt;

&lt;p&gt;Together, these components establish the foundation required for scheduling, input handling and process management.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                CPU Exception
                      │
                      ▼
                   IDT Entry
                      │
                      ▼
                Exception Handler
                      │
                      ▼
                Kernel Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;For hardware interrupts:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             Hardware Device
                    │
                    ▼
                   IRQ
                    │
                    ▼
                   PIC
                    │
                    ▼
                Interrupt Vector
                    │
                    ▼
                   IDT
                    │
                    ▼
                IRQ Handler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Interrupt Vector Configuration&lt;/p&gt;

&lt;p&gt;The kernel uses the standard PIC remapping layout:&lt;/p&gt;

&lt;p&gt;Master PIC IRQs: 0x20 - 0x27&lt;br&gt;
Slave PIC IRQs:  0x28 - 0x2F&lt;/p&gt;

&lt;p&gt;This separates hardware interrupt vectors from the processor exception vectors.&lt;/p&gt;

&lt;p&gt;The distinction is important because exceptions and hardware IRQs have different origins and different handling requirements.&lt;/p&gt;

&lt;p&gt;The kernel also provides serial output, which is particularly useful when debugging interrupt delivery in QEMU.&lt;/p&gt;

&lt;p&gt;VGA output is useful for seeing what is happening on the screen. Serial output is useful for recording execution progress, memory-map entries and diagnostic information without relying exclusively on the display.&lt;/p&gt;

&lt;p&gt;Memory Discovery with BIOS E820&lt;/p&gt;

&lt;p&gt;Physical memory management cannot begin until the kernel knows which physical addresses are available.&lt;/p&gt;

&lt;p&gt;NexisK uses the BIOS INT 15h, E820h interface to discover the physical memory map.&lt;/p&gt;

&lt;p&gt;The bootloader collects the memory regions and exposes the resulting map to the kernel.&lt;/p&gt;

&lt;p&gt;The kernel then processes the entries and identifies usable regions.&lt;/p&gt;

&lt;p&gt;A representative memory map reported by NexisK contains the following entries:&lt;/p&gt;

&lt;p&gt;Base: 0x0000000000000000&lt;br&gt;
Size: 0x000000000009FC00&lt;br&gt;
Type: 0x00000001&lt;br&gt;
Base: 0x000000000009FC00&lt;br&gt;
Size: 0x0000000000000400&lt;br&gt;
Type: 0x00000002&lt;br&gt;
Base: 0x00000000000F0000&lt;br&gt;
Size: 0x0000000000010000&lt;br&gt;
Type: 0x00000002&lt;br&gt;
Base: 0x0000000000100000&lt;br&gt;
Size: 0x0000000007EE0000&lt;br&gt;
Type: 0x00000001&lt;br&gt;
Base: 0x0000000007FE0000&lt;br&gt;
Size: 0x0000000000020000&lt;br&gt;
Type: 0x00000002&lt;br&gt;
Base: 0x00000000FFFC0000&lt;br&gt;
Size: 0x0000000000040000&lt;br&gt;
Type: 0x00000002&lt;/p&gt;

&lt;p&gt;The two usable regions in this example are:&lt;/p&gt;

&lt;p&gt;Region 1:&lt;br&gt;
Base = 0x00000000&lt;br&gt;
Size = 0x0009FC00&lt;br&gt;
Region 2:&lt;br&gt;
Base = 0x00100000&lt;br&gt;
Size = 0x07EE0000&lt;/p&gt;

&lt;p&gt;The second region begins at the 1 MiB boundary, which is a common location for usable extended memory in BIOS-based systems.&lt;/p&gt;

&lt;p&gt;The E820 memory map is important because physical memory is not necessarily one continuous block.&lt;/p&gt;

&lt;p&gt;Firmware-reserved areas, hardware memory regions and other non-usable ranges must not be treated as allocatable RAM.&lt;/p&gt;

&lt;p&gt;A physical memory manager that simply assumes every address below the detected RAM limit is free will eventually overwrite something important.&lt;/p&gt;

&lt;p&gt;Physical Memory Manager&lt;/p&gt;

&lt;p&gt;The Physical Memory Manager is one of the most important subsystems currently being developed in NexisK.&lt;/p&gt;

&lt;p&gt;Its responsibility is to track physical pages and provide the foundation for future virtual memory management.&lt;/p&gt;

&lt;p&gt;The current implementation consumes the E820 map and identifies usable physical memory regions.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             BIOS E820
                 │
                 ▼
          Memory Map Entries
                 │
                 ▼
              pmm_init()
                 │
                 ▼
          Filter Type 1 Regions
                 │
                 ▼
           Calculate Pages
                 │
                 ▼
         Calculate Page Addresses
                 │
                 ▼
          Calculate Bitmap Index
                 │
                 ▼
         Mark Usable Pages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The PMM processes usable regions in increments of 4 KiB.&lt;/p&gt;

&lt;p&gt;That page size is important because it is the standard x86 page granularity used by the paging architecture.&lt;/p&gt;

&lt;p&gt;The current bitmap representation uses one byte per physical page.&lt;/p&gt;

&lt;p&gt;Bitmap Entry:&lt;br&gt;
0 = Free&lt;br&gt;
1 = Reserved / Occupied&lt;/p&gt;

&lt;p&gt;Each bitmap entry corresponds to one 4 KiB physical page.&lt;/p&gt;

&lt;p&gt;This is an initial representation, not the final memory-management design.&lt;/p&gt;

&lt;p&gt;Bitmap Overhead&lt;/p&gt;

&lt;p&gt;A byte-per-page bitmap is simple to understand, but it consumes more metadata than a packed bit bitmap.&lt;/p&gt;

&lt;p&gt;For example, managing 1 GiB of physical memory with 4 KiB pages requires:&lt;/p&gt;

&lt;p&gt;1 GiB / 4 KiB = 262,144 pages&lt;/p&gt;

&lt;p&gt;With one byte per page:&lt;/p&gt;

&lt;p&gt;262,144 bytes = 256 KiB&lt;/p&gt;

&lt;p&gt;With one bit per page:&lt;/p&gt;

&lt;p&gt;262,144 bits = 32 KiB&lt;/p&gt;

&lt;p&gt;The byte-per-page representation therefore uses eight times more metadata than a one-bit-per-page representation.&lt;/p&gt;

&lt;p&gt;I chose the simpler representation for the initial implementation because it makes page-state inspection and debugging straightforward.&lt;/p&gt;

&lt;p&gt;Memory efficiency matters, but correctness matters first.&lt;/p&gt;

&lt;p&gt;The current PMM still requires additional work for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complete bitmap initialization.&lt;/li&gt;
&lt;li&gt;Kernel memory reservation.&lt;/li&gt;
&lt;li&gt;Bootloader memory reservation.&lt;/li&gt;
&lt;li&gt;Bitmap memory reservation.&lt;/li&gt;
&lt;li&gt;Physical page allocation.&lt;/li&gt;
&lt;li&gt;Physical page freeing.&lt;/li&gt;
&lt;li&gt;More precise handling of memory-map boundaries.&lt;/li&gt;
&lt;li&gt;Integration with the Virtual Memory Manager.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lessons from Physical Memory Management&lt;/p&gt;

&lt;p&gt;The biggest lesson is that discovering memory and managing memory are different problems.&lt;/p&gt;

&lt;p&gt;E820 tells the kernel which regions exist and which regions are usable.&lt;/p&gt;

&lt;p&gt;The PMM must then maintain the state of individual physical pages.&lt;/p&gt;

&lt;p&gt;That means it must know which pages are free, which are reserved and which are currently allocated.&lt;/p&gt;

&lt;p&gt;The PMM cannot safely allocate memory until its own metadata is protected.&lt;/p&gt;

&lt;p&gt;This creates a dependency:&lt;/p&gt;

&lt;p&gt;Memory Discovery&lt;br&gt;
      │&lt;br&gt;
      ▼&lt;br&gt;
PMM Metadata&lt;br&gt;
      │&lt;br&gt;
      ▼&lt;br&gt;
Reserve Kernel and Boot Memory&lt;br&gt;
      │&lt;br&gt;
      ▼&lt;br&gt;
Physical Page Allocation&lt;br&gt;
      │&lt;br&gt;
      ▼&lt;br&gt;
Virtual Memory&lt;/p&gt;

&lt;p&gt;The metadata used to manage memory is itself stored in memory. The kernel must therefore reserve and protect its own bookkeeping structures.&lt;/p&gt;

&lt;p&gt;This is one of the first places where operating-system development becomes a problem of managing the resources used to manage resources.&lt;/p&gt;

&lt;p&gt;Virtual Memory and Paging&lt;/p&gt;

&lt;p&gt;The Virtual Memory Manager is planned to be built on top of the physical memory manager.&lt;/p&gt;

&lt;p&gt;The current VMM is not considered complete.&lt;/p&gt;

&lt;p&gt;The intended functionality includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Paging.&lt;/li&gt;
&lt;li&gt;Virtual address mapping.&lt;/li&gt;
&lt;li&gt;Page fault handling.&lt;/li&gt;
&lt;li&gt;Dynamic page mapping.&lt;/li&gt;
&lt;li&gt;Kernel/user memory permissions.&lt;/li&gt;
&lt;li&gt;Per-process address spaces.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The relationship between physical and virtual memory is fundamental.&lt;/p&gt;

&lt;p&gt;The PMM tracks physical pages.&lt;/p&gt;

&lt;p&gt;The VMM controls how virtual addresses map to those physical pages.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             Virtual Address
                    │
                    ▼
                Page Tables
                    │
                    ▼
             Physical Address
                    │
                    ▼
              Physical Memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Without a working physical memory allocator, the VMM cannot reliably create new mappings.&lt;/p&gt;

&lt;p&gt;Without a working VMM, process isolation and independent address spaces are difficult to implement correctly.&lt;/p&gt;

&lt;p&gt;This is why I am treating memory management as a staged subsystem instead of trying to implement every feature at once.&lt;/p&gt;

&lt;p&gt;Process Infrastructure&lt;/p&gt;

&lt;p&gt;NexisK contains initial process-related infrastructure and context-switching groundwork.&lt;/p&gt;

&lt;p&gt;This is not yet a complete multitasking system.&lt;/p&gt;

&lt;p&gt;The intended process subsystem includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Process creation.&lt;/li&gt;
&lt;li&gt;Process destruction.&lt;/li&gt;
&lt;li&gt;PID management.&lt;/li&gt;
&lt;li&gt;Process address spaces.&lt;/li&gt;
&lt;li&gt;Context switching.&lt;/li&gt;
&lt;li&gt;Scheduler.&lt;/li&gt;
&lt;li&gt;Preemptive multitasking.&lt;/li&gt;
&lt;li&gt;Process isolation.&lt;/li&gt;
&lt;li&gt;Userspace execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A process is more than a function call.&lt;/p&gt;

&lt;p&gt;A process requires an execution context, a stack, an address space and a mechanism for switching between execution contexts.&lt;/p&gt;

&lt;p&gt;A simplified process transition looks like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;          Current Process
                │
                ▼
          Save CPU Context
                │
                ▼
         Select Next Process
                │
                ▼
          Restore CPU Context
                │
                ▼
           Next Process
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The context-switching infrastructure is only one part of the complete process model.&lt;/p&gt;

&lt;p&gt;A scheduler must decide when a process runs. The memory subsystem must provide the required address-space behavior. The interrupt subsystem must provide a mechanism for preemption or other scheduling events.&lt;/p&gt;

&lt;p&gt;This is another example of why kernel subsystems cannot be developed as completely isolated features.&lt;/p&gt;

&lt;p&gt;They have interfaces, but their correctness depends on the behavior of the other components.&lt;/p&gt;

&lt;p&gt;System Calls&lt;/p&gt;

&lt;p&gt;NexisK contains a basic system-call mechanism using the int 0x80 instruction.&lt;/p&gt;

&lt;p&gt;The syscall number is passed through the EAX register.&lt;/p&gt;

&lt;p&gt;The current interface is intentionally minimal and is primarily used to validate the system-call path.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;              Execution Context
                     │
                     ▼
                  int 0x80
                     │
                     ▼
                  IDT[0x80]
                     │
                     ▼
               Syscall Handler
                     │
                     ▼
                Kernel Syscall
                     │
                     ▼
                    iret
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The system-call mechanism establishes the basic path from an execution context into kernel code.&lt;/p&gt;

&lt;p&gt;The interface will need to evolve alongside process management, privilege levels and userspace support.&lt;/p&gt;

&lt;p&gt;A production-quality syscall ABI requires much more than a single interrupt vector.&lt;/p&gt;

&lt;p&gt;It needs defined calling conventions, argument validation, return values, error handling and a stable interface between user programs and the kernel.&lt;/p&gt;

&lt;p&gt;The current implementation is the beginning of that path, not a complete syscall subsystem.&lt;/p&gt;

&lt;p&gt;Kernel I/O and Drivers&lt;/p&gt;

&lt;p&gt;The kernel currently provides basic low-level I/O through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VGA text output.&lt;/li&gt;
&lt;li&gt;Serial output.&lt;/li&gt;
&lt;li&gt;Keyboard input.&lt;/li&gt;
&lt;li&gt;PS/2 mouse input.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These drivers are small, but they are essential for making the kernel observable.&lt;/p&gt;

&lt;p&gt;A kernel without reliable output is difficult to debug.&lt;/p&gt;

&lt;p&gt;A kernel without input cannot meaningfully interact with a user.&lt;/p&gt;

&lt;p&gt;The VGA driver provides visible text output in the traditional text-mode environment.&lt;/p&gt;

&lt;p&gt;The serial driver provides diagnostic output that can be captured externally.&lt;/p&gt;

&lt;p&gt;The keyboard and mouse handlers provide the first layer of device interaction.&lt;/p&gt;

&lt;p&gt;The current hardware support is deliberately limited. Storage drivers, filesystem support and additional device drivers remain future work.&lt;/p&gt;

&lt;p&gt;Real Hardware Testing&lt;/p&gt;

&lt;p&gt;QEMU is extremely useful for kernel development, but it is not a replacement for physical hardware.&lt;/p&gt;

&lt;p&gt;An emulator provides a controlled environment. It allows me to reproduce boot behavior, inspect execution and collect diagnostic information.&lt;/p&gt;

&lt;p&gt;NexisK uses QEMU as its primary emulation environment and also includes real hardware boot validation in its development process.&lt;/p&gt;

&lt;p&gt;The build system provides:&lt;/p&gt;

&lt;p&gt;make&lt;/p&gt;

&lt;p&gt;to build the kernel and bootable image.&lt;/p&gt;

&lt;p&gt;To run the kernel in QEMU:&lt;/p&gt;

&lt;p&gt;make run&lt;/p&gt;

&lt;p&gt;For deeper QEMU diagnostics:&lt;/p&gt;

&lt;p&gt;make dev&lt;/p&gt;

&lt;p&gt;The debug configuration writes additional information to:&lt;/p&gt;

&lt;p&gt;build/qemu.log&lt;/p&gt;

&lt;p&gt;This is useful for investigating:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU resets.&lt;/li&gt;
&lt;li&gt;Interrupt behavior.&lt;/li&gt;
&lt;li&gt;Guest errors.&lt;/li&gt;
&lt;li&gt;Unimplemented instructions.&lt;/li&gt;
&lt;li&gt;MMU activity.&lt;/li&gt;
&lt;li&gt;Protected-mode execution.&lt;/li&gt;
&lt;li&gt;Kernel execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why Hardware Testing Matters&lt;/p&gt;

&lt;p&gt;A kernel can behave correctly in an emulator and still fail on a physical machine.&lt;/p&gt;

&lt;p&gt;Firmware implementations differ.&lt;/p&gt;

&lt;p&gt;Hardware initialization differs.&lt;/p&gt;

&lt;p&gt;Memory maps differ.&lt;/p&gt;

&lt;p&gt;Devices differ.&lt;/p&gt;

&lt;p&gt;The boot path may encounter assumptions that were never exposed in the emulator.&lt;/p&gt;

&lt;p&gt;For NexisK, this matters particularly because the bootloader interacts directly with BIOS services and hardware.&lt;/p&gt;

&lt;p&gt;Real hardware testing is therefore not merely a demonstration that the kernel boots. It is a way to discover assumptions about the machine that are not visible in a controlled emulated environment.&lt;/p&gt;

&lt;p&gt;The current project documentation records real hardware boot validation, but it does not provide a complete compatibility matrix across different machines.&lt;/p&gt;

&lt;p&gt;I do not consider the current bootloader universally compatible with all x86 hardware.&lt;/p&gt;

&lt;p&gt;Performance&lt;/p&gt;

&lt;p&gt;NexisK is currently a kernel-development project, not a performance benchmark suite.&lt;/p&gt;

&lt;p&gt;The repository does not currently provide measured syscall latency, interrupt latency, context-switch timing, memory-allocation throughput or boot-time benchmarks.&lt;/p&gt;

&lt;p&gt;I will not invent those numbers.&lt;/p&gt;

&lt;p&gt;The current measurable implementation details are architectural:&lt;/p&gt;

&lt;p&gt;Metric  Current Value&lt;br&gt;
Target architecture i386&lt;br&gt;
CPU mode    32-bit protected mode&lt;br&gt;
Page size   4 KiB&lt;br&gt;
PMM bitmap entry size   1 byte&lt;br&gt;
Boot stages 2&lt;br&gt;
Syscall vector  0x80&lt;br&gt;
Master PIC vector range 0x20–0x27&lt;br&gt;
Slave PIC vector range  0x28–0x2F&lt;br&gt;
Current release v0.8.9&lt;br&gt;
Repository commits  33&lt;/p&gt;

&lt;p&gt;These values describe the implementation. They are not performance results.&lt;/p&gt;

&lt;p&gt;A meaningful performance evaluation will require a defined workload and a stable implementation.&lt;/p&gt;

&lt;p&gt;For example, a future PMM benchmark could measure the time required to allocate and free a fixed number of physical pages.&lt;/p&gt;

&lt;p&gt;A syscall benchmark could measure the cost of entering the kernel through int 0x80 and returning through iret.&lt;/p&gt;

&lt;p&gt;A context-switch benchmark could measure the time required to save and restore process state.&lt;/p&gt;

&lt;p&gt;Those measurements would become meaningful only after the relevant subsystems are complete enough to benchmark.&lt;/p&gt;

&lt;p&gt;Development Lessons Learned&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Bootloader Complexity Is Not the Same as Kernel Complexity&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A kernel can have a working C entry point and still be unable to boot reliably.&lt;/p&gt;

&lt;p&gt;The bootloader must establish the environment in which the kernel executes.&lt;/p&gt;

&lt;p&gt;That includes loading the kernel correctly, preserving required information and transferring control at the correct processor state.&lt;/p&gt;

&lt;p&gt;The bootloader deserves its own design and testing.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Memory Management Must Be Developed Incrementally&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The PMM cannot be treated as a single feature.&lt;/p&gt;

&lt;p&gt;Memory discovery, page tracking, reservation, allocation and freeing are separate responsibilities.&lt;/p&gt;

&lt;p&gt;Trying to implement all of them simultaneously makes debugging much harder.&lt;/p&gt;

&lt;p&gt;The current byte-per-page bitmap is intentionally simple. It allows the initial implementation to focus on page-state tracking before optimizing metadata representation.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Hardware Abstraction Must Not Hide the Hardware Too Early&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The current kernel uses explicit architecture-specific code.&lt;/p&gt;

&lt;p&gt;That is appropriate for an i386 kernel because the processor’s descriptor tables, interrupt vectors and I/O mechanisms are directly relevant to the implementation.&lt;/p&gt;

&lt;p&gt;A large abstraction layer introduced too early can hide the exact state that needs to be debugged.&lt;/p&gt;

&lt;p&gt;I prefer to establish correct low-level mechanisms first and abstract them only when the interfaces are understood.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A Directory Is Not an Implementation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;NexisK includes:&lt;/p&gt;

&lt;p&gt;userspace/&lt;br&gt;
├── init/&lt;br&gt;
└── shell/&lt;/p&gt;

&lt;p&gt;These directories establish the intended separation between kernel code and future userspace programs.&lt;/p&gt;

&lt;p&gt;They do not mean that Ring 3 execution, executable loading or a complete shell already exist.&lt;/p&gt;

&lt;p&gt;The same principle applies to process management and virtual memory.&lt;/p&gt;

&lt;p&gt;A subsystem should be described according to what it actually implements, not according to what its directory structure suggests.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;QEMU and Real Hardware Solve Different Problems&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;QEMU is valuable for repeatable testing and diagnostics.&lt;/p&gt;

&lt;p&gt;Physical hardware exposes firmware and compatibility assumptions.&lt;/p&gt;

&lt;p&gt;Neither environment completely replaces the other.&lt;/p&gt;

&lt;p&gt;A useful development process uses emulation for rapid iteration and hardware testing for validation against real machines.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Kernel Development Is Dependency Management&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The kernel architecture is a dependency graph.&lt;/p&gt;

&lt;p&gt;The bootloader provides the environment.&lt;/p&gt;

&lt;p&gt;The CPU subsystem establishes execution.&lt;/p&gt;

&lt;p&gt;The interrupt subsystem provides event handling.&lt;/p&gt;

&lt;p&gt;The memory subsystem provides allocation and address translation.&lt;/p&gt;

&lt;p&gt;The process subsystem depends on memory and interrupt behavior.&lt;/p&gt;

&lt;p&gt;System calls depend on the execution and privilege model.&lt;/p&gt;

&lt;p&gt;Userspace depends on all of them.&lt;/p&gt;

&lt;p&gt;Understanding these dependencies prevents implementing higher-level features on unstable foundations.&lt;/p&gt;

&lt;p&gt;Future Development&lt;/p&gt;

&lt;p&gt;The next stages of NexisK development are centered on completing the existing architectural foundations.&lt;/p&gt;

&lt;p&gt;Bootloader&lt;/p&gt;

&lt;p&gt;The bootloader needs more robust disk access, improved hardware compatibility and eventually UEFI support.&lt;/p&gt;

&lt;p&gt;The current design is based on the traditional BIOS environment.&lt;/p&gt;

&lt;p&gt;A future x86-64 transition will also require changes to the boot architecture.&lt;/p&gt;

&lt;p&gt;Memory Management&lt;/p&gt;

&lt;p&gt;The PMM needs complete bitmap initialization, proper reservation handling, physical page allocation and freeing.&lt;/p&gt;

&lt;p&gt;The VMM needs paging, page fault handling and dynamic mapping.&lt;/p&gt;

&lt;p&gt;These are prerequisites for a reliable process model.&lt;/p&gt;

&lt;p&gt;Privilege Levels&lt;/p&gt;

&lt;p&gt;The kernel currently has protected-mode infrastructure and initial work toward privilege-level support.&lt;/p&gt;

&lt;p&gt;Full Ring 3 execution and kernel/user separation remain under development.&lt;/p&gt;

&lt;p&gt;The final privilege model must provide a reliable boundary between kernel code and userspace code.&lt;/p&gt;

&lt;p&gt;Processes and Scheduling&lt;/p&gt;

&lt;p&gt;The process subsystem needs a complete lifecycle, address spaces, context switching and scheduling.&lt;/p&gt;

&lt;p&gt;Preemptive multitasking will require coordination between the timer, interrupt handling, process state and memory management.&lt;/p&gt;

&lt;p&gt;Userspace&lt;/p&gt;

&lt;p&gt;The initial userspace directory structure exists, but the actual execution environment remains to be implemented.&lt;/p&gt;

&lt;p&gt;Future work includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Executable loading.&lt;/li&gt;
&lt;li&gt;Initial init process.&lt;/li&gt;
&lt;li&gt;Userspace system-call API.&lt;/li&gt;
&lt;li&gt;Shell execution.&lt;/li&gt;
&lt;li&gt;User-space programs.&lt;/li&gt;
&lt;li&gt;Process isolation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Storage&lt;/p&gt;

&lt;p&gt;Storage support is not currently available as a complete kernel subsystem.&lt;/p&gt;

&lt;p&gt;Future work includes disk abstraction, disk drivers, LBA support, filesystem abstraction and file operations.&lt;/p&gt;

&lt;p&gt;Get Started&lt;/p&gt;

&lt;p&gt;NexisK is currently developed and tested primarily on Linux.&lt;/p&gt;

&lt;p&gt;The required tools are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GCC.&lt;/li&gt;
&lt;li&gt;NASM.&lt;/li&gt;
&lt;li&gt;GNU Make.&lt;/li&gt;
&lt;li&gt;GNU ld.&lt;/li&gt;
&lt;li&gt;QEMU.&lt;/li&gt;
&lt;li&gt;genisoimage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On Debian or Ubuntu:&lt;/p&gt;

&lt;p&gt;sudo apt update&lt;br&gt;
sudo apt install \&lt;br&gt;
    build-essential \&lt;br&gt;
    gcc \&lt;br&gt;
    nasm \&lt;br&gt;
    make \&lt;br&gt;
    binutils \&lt;br&gt;
    qemu-system-x86 \&lt;br&gt;
    genisoimage&lt;/p&gt;

&lt;p&gt;Clone the repository:&lt;/p&gt;

&lt;p&gt;git clone &lt;a href="https://github.com/icarotelesdasilva/NexisK.git" rel="noopener noreferrer"&gt;https://github.com/icarotelesdasilva/NexisK.git&lt;/a&gt;&lt;br&gt;
cd NexisK&lt;/p&gt;

&lt;p&gt;Build the kernel and bootable ISO:&lt;/p&gt;

&lt;p&gt;make&lt;/p&gt;

&lt;p&gt;The generated files are placed in:&lt;/p&gt;

&lt;p&gt;build/&lt;/p&gt;

&lt;p&gt;The main bootable image is:&lt;/p&gt;

&lt;p&gt;build/NexisK.iso&lt;/p&gt;

&lt;p&gt;Run the kernel with QEMU:&lt;/p&gt;

&lt;p&gt;make run&lt;/p&gt;

&lt;p&gt;For deeper debugging:&lt;/p&gt;

&lt;p&gt;make dev&lt;/p&gt;

&lt;p&gt;To remove generated build artifacts:&lt;/p&gt;

&lt;p&gt;make clean&lt;/p&gt;

&lt;p&gt;A clean build can then be produced with:&lt;/p&gt;

&lt;p&gt;make&lt;/p&gt;

&lt;p&gt;Conclusion&lt;/p&gt;

&lt;p&gt;NexisK is an ongoing effort to build a 32-bit x86 kernel from the lowest levels upward.&lt;/p&gt;

&lt;p&gt;The project currently has a custom BIOS bootloader, protected-mode execution, interrupt infrastructure, hardware input, serial debugging, BIOS E820 memory discovery and an initial physical memory manager.&lt;/p&gt;

&lt;p&gt;It also contains the early foundations of system calls, process management and userspace architecture.&lt;/p&gt;

&lt;p&gt;The most important part of the project is not the number of features. It is the relationship between them.&lt;/p&gt;

&lt;p&gt;The bootloader must load the kernel correctly.&lt;/p&gt;

&lt;p&gt;The CPU must execute in a valid environment.&lt;/p&gt;

&lt;p&gt;The interrupt subsystem must deliver events reliably.&lt;/p&gt;

&lt;p&gt;The memory manager must track physical pages without corrupting kernel state.&lt;/p&gt;

&lt;p&gt;The process subsystem must preserve execution contexts.&lt;/p&gt;

&lt;p&gt;The syscall interface must establish a controlled path into the kernel.&lt;/p&gt;

&lt;p&gt;Each layer depends on the previous one.&lt;/p&gt;

&lt;p&gt;That is what makes kernel development difficult, and that is also what makes it useful.&lt;/p&gt;

&lt;p&gt;I am building NexisK to understand these mechanisms directly, with the implementation exposed instead of hidden behind a finished operating system.&lt;/p&gt;

&lt;p&gt;The project is still evolving. Its current limitations are part of the engineering work, not something to conceal.&lt;/p&gt;

&lt;p&gt;If you are interested in operating-system development, x86 architecture, C, assembly programming or bare-metal systems programming, the source code is available.&lt;/p&gt;

&lt;p&gt;Explore the project, inspect the implementation and follow the development.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: NexisK&lt;/li&gt;
&lt;li&gt;GitHub profile: icarotelesdasilva&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are working on your own kernel, I would be interested in comparing implementation approaches, discussing memory management or examining how different kernels handle the hardware/software boundary.&lt;/p&gt;

&lt;p&gt;The source is open. The architecture is still being built.&lt;/p&gt;

&lt;p&gt;And the next layer is always waiting.&lt;/p&gt;

</description>
      <category>osdev</category>
      <category>kernel</category>
      <category>x86</category>
      <category>c</category>
    </item>
  </channel>
</rss>
