/ kernel / core / kernel.c
kernel.c
  1  #include "kernel.h"
  2  #include "gdt.h"
  3  #include "idt.h"
  4  #include "memory.h"
  5  #include "io_uring.h"
  6  #include "string.h"
  7  #include "fs.h"
  8  #include "initrd.h"
  9  #include "process.h"
 10  #include "elf.h"
 11  #include "paging.h"
 12  #include "vfs.h"
 13  #include "keyboard.h"
 14  #include "console.h"
 15  
 16  // Multiboot information structure
 17  struct multiboot_info {
 18      uint32_t flags;
 19      uint32_t mem_lower;
 20      uint32_t mem_upper;
 21      uint32_t boot_device;
 22      uint32_t cmdline;
 23      uint32_t mods_count;
 24      uint32_t mods_addr;
 25      // ...
 26  } __attribute__((packed));
 27  
 28  // Helper function to create VGA entry
 29  static inline uint16_t vga_entry(unsigned char uc, uint8_t color) {
 30      return (uint16_t) uc | (uint16_t) color << 8;
 31  }
 32  
 33  // Initialize terminal - now delegates to console
 34  void terminal_init(void) {
 35      // Clear screen with initial color
 36      uint8_t color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK);
 37      uint16_t* terminal_buffer = (uint16_t*) VGA_ADDRESS;
 38      
 39      for (size_t y = 0; y < VGA_HEIGHT; y++) {
 40          for (size_t x = 0; x < VGA_WIDTH; x++) {
 41              const size_t index = y * VGA_WIDTH + x;
 42              terminal_buffer[index] = vga_entry(' ', color);
 43          }
 44      }
 45  }
 46  
 47  // Put character to terminal - now delegates to console
 48  void terminal_putchar(char c) {
 49      if (system_console) {
 50          console_putchar(c);
 51      }
 52  }
 53  
 54  // Write data to terminal - now delegates to console
 55  void terminal_write(const char* data, size_t size) {
 56      if (system_console) {
 57          console_write(data, size);
 58      }
 59  }
 60  
 61  // Write string to terminal - now delegates to console
 62  void terminal_writestring(const char* data) {
 63      if (system_console) {
 64          console_write(data, strlen(data));
 65      }
 66  }
 67  
 68  // Clear terminal - now delegates to console
 69  void terminal_clear(void) {
 70      if (system_console) {
 71          console_clear();
 72      }
 73  }
 74  
 75  // Set terminal color - now delegates to console
 76  void terminal_setcolor(uint8_t color) {
 77      if (system_console) {
 78          uint8_t fg = color & 0x0F;
 79          uint8_t bg = (color >> 4) & 0x0F;
 80          console_set_color(fg, bg);
 81      }
 82  }
 83  
 84  // Get current terminal cursor position - now delegates to console
 85  void terminal_get_cursor(size_t* row, size_t* column) {
 86      if (system_console) {
 87          uint32_t x, y;
 88          console_get_cursor(&x, &y);
 89          if (row) *row = y;
 90          if (column) *column = x;
 91      } else {
 92          if (row) *row = 0;
 93          if (column) *column = 0;
 94      }
 95  }
 96  
 97  // Kernel panic - halt the system
 98  void kernel_panic(const char* message) {
 99      __asm__ volatile("cli"); // Disable interrupts
100      
101      terminal_setcolor(vga_entry_color(VGA_COLOR_WHITE, VGA_COLOR_RED));
102      terminal_writestring("\n\nKERNEL PANIC: ");
103      terminal_writestring(message);
104      terminal_writestring("\nSystem halted.\n");
105      
106      // Halt the CPU
107      while (1) {
108          __asm__ volatile("hlt");
109      }
110  }
111  
112  // External functions
113  extern void test_io_uring(void);
114  
115  // Timer tick counter
116  volatile uint32_t timer_ticks = 0;
117  
118  // Actual timer handler
119  static void timer_tick(void) {
120      timer_ticks++;
121      
122      // TODO sometime fix ts
123      // Simple round-robin scheduling every 10 ticks  
124      // if (timer_ticks % 10 == 0 && current_process) {
125      //     process_yield();
126      // }
127  }
128  
129  // Timer interrupt handler (matches interrupt_handler_t)
130  void timer_handler(void) {
131      timer_tick();
132      
133      // Send End Of Interrupt to PIC
134      outb(0x20, 0x20);
135  }
136  
137  // Kernel main entry point
138  void kernel_main(uint32_t magic, uint32_t addr) {
139      // Multiboot information structure
140      struct multiboot_info* mbi = (struct multiboot_info*)addr;
141      
142      // Initialize terminal FIRST
143      terminal_init();
144      terminal_writestring("Terminal initialized\n");
145      
146      // Initialize console early for unified VGA management
147      console_early_init();
148      terminal_writestring("Console early init OK\n");
149      
150      // Check multiboot magic
151      if (magic != 0x2BADB002) {
152          terminal_writestring("Bad magic number!\n");
153          while (1) { hlt(); }
154      }
155      
156      terminal_writestring("Multiboot OK\n");
157      
158      // Initialize GDT
159      terminal_writestring("Init GDT...\n");
160      gdt_init();
161      terminal_writestring("GDT OK\n");
162      
163      // Initialize IDT
164      terminal_writestring("Init IDT...\n");
165      idt_init();
166      terminal_writestring("IDT OK\n");
167      
168      // Initialize memory FIRST
169      terminal_writestring("Init memory...\n");
170  
171      uint32_t total_mem_bytes;
172      if (mbi->flags & 0x1) {
173          // mem_upper is in KB, represents memory above 1MB
174          total_mem_bytes = (mbi->mem_upper + 1024) * 1024;
175      } else {
176          total_mem_bytes = 128 * 1024 * 1024; // Fallback default 128MB
177      }
178  
179      memory_init(total_mem_bytes);
180      terminal_writestring("Memory detected: ");
181      char mbuf[12];
182      itoa(total_mem_bytes / (1024 * 1024), mbuf, 10);
183      terminal_writestring(mbuf);
184      terminal_writestring(" MB\n");
185      
186      // Initialize paging
187      terminal_writestring("Init paging...\n");
188      paging_init();
189      terminal_writestring("Paging OK\n");
190      
191      // Initialize VFS
192      terminal_writestring("Init VFS...\n");
193      vfs_init();
194      terminal_writestring("VFS OK\n");
195      
196      // Initialize PIC FIRST - remap IRQs to interrupts 32-47
197      // Send initialization command to both PICs
198      outb(0x20, 0x11);  // Master PIC command
199      outb(0xA0, 0x11);  // Slave PIC command
200      
201      // Set IRQ base addresses
202      outb(0x21, 0x20);  // Master PIC: IRQs 0-7 -> interrupts 32-39
203      outb(0xA1, 0x28);  // Slave PIC: IRQs 8-15 -> interrupts 40-47
204      
205      // Configure PIC cascade
206      outb(0x21, 0x04);  // Master PIC: slave on IRQ2
207      outb(0xA1, 0x02);  // Slave PIC: cascade identity
208      
209      // Set 8086 mode
210      outb(0x21, 0x01);  // Master PIC
211      outb(0xA1, 0x01);  // Slave PIC
212      
213      // Unmask all IRQs initially
214      outb(0x21, 0x00);  // Master PIC mask
215      outb(0xA1, 0x00);  // Slave PIC mask
216      
217      terminal_writestring("PIC initialized\n");
218      
219      // Initialize keyboard AFTER PIC
220      terminal_writestring("Init keyboard...\n");
221      keyboard_init();
222      terminal_writestring("Keyboard OK\n");
223      
224      // Initialize console
225      terminal_writestring("Init console...\n");
226      console_late_init();
227      terminal_writestring("Console OK\n");
228      
229      // Initialize timer (IRQ0)
230      register_interrupt_handler(32, timer_handler);  // IRQ0 is interrupt 32
231      
232      // Set up PIT for ~100Hz
233      uint32_t divisor = 1193180 / 100;  // 100Hz
234      outb(0x43, 0x36);  // Command byte
235      outb(0x40, divisor & 0xFF);  // Low byte
236      outb(0x40, divisor >> 8);   // High byte
237      terminal_writestring("Timer initialized at 100Hz\n");
238      
239      // Enable interrupts!
240      __asm__ volatile("sti");
241      terminal_writestring("Interrupts enabled\n");
242      
243      // If we get here, basic initialization worked
244      terminal_writestring("\nBasic init complete!\n");
245      
246      // Initialize io_uring subsystem
247      terminal_writestring("Init io_uring...\n");
248      io_uring_init();
249      terminal_writestring("io_uring OK\n");
250      
251      // Initialize filesystem
252      terminal_writestring("Init filesystem...\n");
253      fs_init();
254      terminal_writestring("Filesystem OK\n");
255      
256      // Load initrd
257      if (mbi->mods_count > 0) {
258          terminal_writestring("Loading initrd...\n");
259          uint32_t* mod_start = (uint32_t*)mbi->mods_addr;
260          uint32_t initrd_location = *mod_start;
261          uint32_t initrd_end = *(mod_start + 1);
262          
263          terminal_writestring("Initrd at 0x");
264          char buf[9];
265          itoa(initrd_location, buf, 16);
266          terminal_writestring(buf);
267          terminal_writestring(", size: ");
268          itoa(initrd_end - initrd_location, buf, 10);
269          terminal_writestring(buf);
270          terminal_writestring(" bytes\n");
271          
272          // Initialize initrd filesystem
273          fs_root = initrd_init(initrd_location);
274      } else {
275          terminal_writestring("No initrd found!\n");
276      }
277      
278      // Initialize process management
279      terminal_writestring("Init processes...\n");
280      process_init();
281      terminal_writestring("Processes OK\n");
282      
283      terminal_writestring("\nAll systems initialized!\n");
284      terminal_writestring("io_uring kernel ready.\n\n");
285      
286      // List files in initrd
287      if (fs_root) {
288          terminal_writestring("Files in initrd:\n");
289          int i = 0;
290          struct dirent* node = 0;
291          while ((node = fs_readdir(fs_root, i)) != 0) {
292              terminal_writestring("  - ");
293              terminal_writestring(node->name);
294              terminal_writestring("\n");
295              i++;
296          }
297          terminal_writestring("\n");
298      }
299      
300      // Try to run hello_uring
301      terminal_writestring("Attempting to execute hello_uring...\n");
302      int result = process_exec("hello_uring");
303      if (result < 0) {
304          terminal_writestring("Failed to execute hello_uring\n");
305      }
306      
307      terminal_writestring("\nKernel execution complete.\n");
308      
309      // Main kernel loop
310      while (1) {
311          hlt();
312      }
313  }