uint32_t fb_width;
uint32_t fb_height;
uint8_t fb_bpp;
+ uint8_t fb_type; /* 0=indexed, 1=direct RGB (linear), 2=EGA text */
};
#endif
* 0xC0400000 LAPIC MMIO (1 page)
* 0xC8000000 .. Kernel stacks (guard + 8KB per thread)
* 0xD0000000 .. Kernel heap (10 MB)
+ * 0xDC000000 .. Initrd / generic phys mapping (up to 64 MB)
+ * 0xE0000000 .. Framebuffer mapping (up to 16 MB)
*/
/* IOAPIC (arch/x86/ioapic.c) */
/* LAPIC (arch/x86/lapic.c) */
#define KVA_LAPIC 0xC0400000U
+/* Initrd / generic physical range mapping (hal/x86/mm.c) */
+#define KVA_PHYS_MAP 0xDC000000U
+
+/* Framebuffer (drivers/vbe.c) — up to 16 MB for large resolutions */
+#define KVA_FRAMEBUFFER 0xE0000000U
+
#endif
bi.fb_width = 0;
bi.fb_height = 0;
bi.fb_bpp = 0;
+ bi.fb_type = 0;
if (mbi_phys) {
uint32_t total_size = *(volatile uint32_t*)mbi_phys;
tag = (struct multiboot_tag*)((uint8_t*)tag + ((tag->size + 7) & ~7))) {
if (tag->type == MULTIBOOT_TAG_TYPE_MODULE) {
const struct multiboot_tag_module* mod = (const struct multiboot_tag_module*)tag;
- bi.initrd_start = mod->mod_start;
- bi.initrd_end = mod->mod_end;
- break;
+ if (!bi.initrd_start) {
+ bi.initrd_start = mod->mod_start;
+ bi.initrd_end = mod->mod_end;
+ }
}
if (tag->type == MULTIBOOT_TAG_TYPE_CMDLINE) {
const struct multiboot_tag_string* s = (const struct multiboot_tag_string*)tag;
bi.fb_width = fb->framebuffer_width;
bi.fb_height = fb->framebuffer_height;
bi.fb_bpp = fb->framebuffer_bpp;
+ bi.fb_type = fb->framebuffer_type;
}
}
}
}
}
- kprintf("[ELF] starting /bin/init.elf\n");
+ kprintf("[ELF] starting %s\n", init_path);
kprintf("[ELF] user_range_ok(entry)=%c user_range_ok(stack)=%c\n",
user_range_ok((const void*)entry, 1) ? '1' : '0',
#endif
int arch_platform_setup(const struct boot_info* bi) {
- (void)bi;
#if defined(__i386__)
vmm_init();
- vga_init();
- vga_set_color(0x0A, 0x00);
- console_enable_vga(1);
- kprintf("[AdrOS] Kernel Initialized (VGA).\n");
+ /* Enable VGA text console only if we are NOT in linear framebuffer mode.
+ * When GRUB provides a linear framebuffer (fb_type==1), the VGA text
+ * buffer at 0xB8000 is inactive — serial console carries all output. */
+ if (!bi || bi->fb_type != 1) {
+ vga_init();
+ vga_set_color(0x0A, 0x00);
+ console_enable_vga(1);
+ kprintf("[AdrOS] Kernel Initialized (VGA text mode).\n");
+ } else {
+ kprintf("[AdrOS] Kernel Initialized (framebuffer %ux%ux%u, VGA text disabled).\n",
+ (unsigned)bi->fb_width, (unsigned)bi->fb_height, (unsigned)bi->fb_bpp);
+ }
syscall_init();
#endif
}
+static void ring3_test_thread(void) {
+ x86_usermode_test_start();
+ for (;;) hal_cpu_idle();
+}
+
void arch_platform_usermode_test_start(void) {
#if defined(__i386__)
- x86_usermode_test_start();
+ process_create_kernel(ring3_test_thread);
#endif
}
.long MB_ARCH
.long multiboot_header_end - multiboot_header_start
.long 0x100000000 - (MB_MAGIC + MB_ARCH + (multiboot_header_end - multiboot_header_start))
+
+ /* Framebuffer request tag (type 5, optional) */
+ .align 8
+fb_tag_start:
+ .word 5 /* type: framebuffer */
+ .word 1 /* flags: optional (boot even if unavailable) */
+ .long fb_tag_end - fb_tag_start
+ .long 1024 /* preferred width */
+ .long 768 /* preferred height */
+ .long 32 /* preferred depth (bpp) */
+fb_tag_end:
+
+ /* End tag */
+ .align 8
.word 0, 0
.long 8
multiboot_header_end:
#include "uaccess.h"
#include "console.h"
#include "utils.h"
+#include "kernel_va_map.h"
#include <stddef.h>
g_vbe.size = g_vbe.pitch * g_vbe.height;
uint32_t pages = (g_vbe.size + 0xFFF) >> 12;
- uintptr_t virt_base = 0xE0000000U;
+ uintptr_t virt_base = KVA_FRAMEBUFFER;
for (uint32_t i = 0; i < pages; i++) {
vmm_map_page((uint64_t)(g_vbe.phys_addr + i * 0x1000),
#include "hal/mm.h"
#include "vmm.h"
+#include "kernel_va_map.h"
#include <stddef.h>
if (phys_end < phys_start) phys_end = phys_start;
- const uintptr_t virt_base = 0xE0000000U;
+ const uintptr_t virt_base = KVA_PHYS_MAP;
uintptr_t phys_start_aligned = phys_start & ~(uintptr_t)0xFFF;
uintptr_t phys_end_aligned = (phys_end + 0xFFF) & ~(uintptr_t)0xFFF;
return;
}
- /* Token 0 is the kernel path — skip it.
- * Process remaining tokens. */
+ /* Token 0 may be the kernel path (e.g. "/boot/adros-x86.bin") —
+ * skip it only if it looks like a path. GRUB2 with Multiboot2
+ * does NOT always include the kernel path in the cmdline string;
+ * it may pass only the arguments (e.g. "ring3" or "init=/bin/sh"). */
+ int start_idx = 0;
+ if (ntokens > 0 && tokens[0][0] == '/') {
+ start_idx = 1;
+ }
+
int after_separator = 0;
- for (int i = 1; i < ntokens; i++) {
+ for (int i = start_idx; i < ntokens; i++) {
const char* tok = tokens[i];
/* Check for "--" separator */
/* Parse kernel command line (Linux-like triaging) */
cmdline_parse(bi ? bi->cmdline : NULL);
+ /* Apply console= parameter: serial, vga, or both (default) */
+ const char* con = cmdline_get("console");
+ if (con) {
+ if (strcmp(con, "serial") == 0 || strcmp(con, "ttyS0") == 0) {
+ console_enable_uart(1);
+ console_enable_vga(0);
+ kprintf("[CONSOLE] output: serial only\n");
+ } else if (strcmp(con, "vga") == 0 || strcmp(con, "tty0") == 0) {
+ console_enable_uart(0);
+ console_enable_vga(1);
+ kprintf("[CONSOLE] output: VGA only\n");
+ } else {
+ kprintf("[CONSOLE] unknown console=%s, using both\n", con);
+ }
+ }
+
if (bi && bi->initrd_start) {
uintptr_t initrd_virt = 0;
if (hal_mm_map_physical_range((uintptr_t)bi->initrd_start, (uintptr_t)bi->initrd_end,
#include "arch_signal.h"
#include "arch_syscall.h"
#include "arch_process.h"
+#include "rtc.h"
#include <stddef.h>
struct timespec tp;
if (clk_id == CLOCK_REALTIME) {
- extern uint32_t rtc_unix_timestamp(void);
tp.tv_sec = rtc_unix_timestamp();
tp.tv_nsec = 0;
} else {