mirror of
https://github.com/BoredDevNL/BoredOS.git
synced 2026-05-15 10:48:38 +00:00
core: update system boot logic for disk-based root and cmdline flags
This commit is contained in:
parent
0fbc3a5fc8
commit
6e1eb7768d
7 changed files with 181 additions and 35 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -31,3 +31,6 @@ limine
|
|||
/build/
|
||||
*.o
|
||||
disk.img
|
||||
disk.qcow2
|
||||
.gitignore
|
||||
disk.img
|
||||
|
|
|
|||
60
Makefile
60
Makefile
|
|
@ -202,8 +202,23 @@ $(BUILD_DIR)/initrd.tar: $(KERNEL_ELF)
|
|||
mkdir -p $(BUILD_DIR)/initrd/Library/images/icons/colloid
|
||||
mkdir -p $(BUILD_DIR)/initrd/Library/Fonts/Emoji
|
||||
mkdir -p $(BUILD_DIR)/initrd/Library/DOOM
|
||||
mkdir -p $(BUILD_DIR)/initrd/Library/conf
|
||||
mkdir -p $(BUILD_DIR)/initrd/Library/bsh
|
||||
mkdir -p $(BUILD_DIR)/initrd/Library/BWM/Wallpaper
|
||||
mkdir -p $(BUILD_DIR)/initrd/docs
|
||||
mkdir -p $(BUILD_DIR)/initrd/boot
|
||||
mkdir -p $(BUILD_DIR)/initrd/mnt
|
||||
mkdir -p $(BUILD_DIR)/initrd/dev
|
||||
mkdir -p $(BUILD_DIR)/initrd/root/Desktop
|
||||
mkdir -p $(BUILD_DIR)/initrd/root/Pictures
|
||||
mkdir -p $(BUILD_DIR)/initrd/root/Documents
|
||||
mkdir -p $(BUILD_DIR)/initrd/root/Downloads
|
||||
|
||||
@printf "$(YELLOW)[COPY]$(RESET) Limine binaries + kernel for installer..."
|
||||
@if [ -f limine/BOOTX64.EFI ]; then cp limine/BOOTX64.EFI $(BUILD_DIR)/initrd/boot/; fi
|
||||
@if [ -f limine/BOOTIA32.EFI ]; then cp limine/BOOTIA32.EFI $(BUILD_DIR)/initrd/boot/; fi
|
||||
@if [ -f limine/limine-bios.sys ]; then cp limine/limine-bios.sys $(BUILD_DIR)/initrd/boot/; fi
|
||||
@cp $(KERNEL_ELF) $(BUILD_DIR)/initrd/boot/boredos.elf
|
||||
|
||||
@printf "$(YELLOW)[COPY]$(RESET) Userland binaries..."
|
||||
@for f in $(SRC_DIR)/userland/bin/*.elf; do \
|
||||
|
|
@ -331,30 +346,63 @@ clean:
|
|||
$(MAKE) -C $(SRC_DIR)/userland clean
|
||||
@printf "$(GREEN)[OK]$(RESET) Clean complete."
|
||||
|
||||
run-windows: $(ISO_IMAGE)
|
||||
disk.qcow2:
|
||||
$(call PRINT_STEP,CREATING 10GB EXPANDABLE DISK IMAGE)
|
||||
qemu-img create -f qcow2 disk.qcow2 10G
|
||||
|
||||
run-windows: $(ISO_IMAGE) disk.qcow2
|
||||
$(call PRINT_STEP,RUNNING BOREDOS IN QEMU ON WINDOWS)
|
||||
qemu-system-x86_64 -m 4G -serial stdio -cdrom $< -boot d \
|
||||
-smp 4 \
|
||||
-audiodev dsound,id=audio0 -machine pcspk-audiodev=audio0 \
|
||||
-vga std -global VGA.xres=1920 -global VGA.yres=1080 \
|
||||
-drive file=disk.img,format=raw,file.locking=off
|
||||
-drive file=disk.qcow2,format=qcow2,file.locking=off
|
||||
|
||||
run-mac: $(ISO_IMAGE)
|
||||
run-mac: $(ISO_IMAGE) disk.qcow2
|
||||
$(call PRINT_STEP,RUNNING BOREDOS IN QEMU ON MACOS)
|
||||
qemu-system-x86_64 -m 4G -serial stdio -cdrom $< -boot d \
|
||||
-smp 4 \
|
||||
-audiodev coreaudio,id=audio0 -machine pcspk-audiodev=audio0 \
|
||||
-vga std -global VGA.xres=1920 -global VGA.yres=1080 \
|
||||
-display cocoa,show-cursor=off \
|
||||
-drive file=disk.img,format=raw,file.locking=off \
|
||||
-device ahci,id=ahci -drive file=disk.qcow2,format=qcow2,if=none,id=disk0 -device ide-hd,bus=ahci.0,drive=disk0 \
|
||||
-cpu max
|
||||
|
||||
run-linux: $(ISO_IMAGE)
|
||||
OVMF_CODE := /opt/homebrew/share/qemu/edk2-x86_64-code.fd
|
||||
OVMF_VARS_TMPL := /opt/homebrew/share/qemu/edk2-i386-vars.fd
|
||||
OVMF_VARS := edk2-vars.fd
|
||||
|
||||
ifeq ($(shell test -f $(OVMF_CODE) && echo 1),)
|
||||
OVMF_CODE := /usr/local/share/qemu/edk2-x86_64-code.fd
|
||||
OVMF_VARS_TMPL := /usr/local/share/qemu/edk2-i386-vars.fd
|
||||
endif
|
||||
|
||||
$(OVMF_VARS):
|
||||
@if [ -f $(OVMF_VARS_TMPL) ]; then \
|
||||
printf "$(YELLOW)[UEFI]$(RESET) Creating local NVRAM vars..."; \
|
||||
cp $(OVMF_VARS_TMPL) $(OVMF_VARS); \
|
||||
fi
|
||||
|
||||
run-hd: disk.qcow2 $(OVMF_VARS)
|
||||
$(call PRINT_STEP,BOOTING BOREDOS FROM HARD DRIVE)
|
||||
qemu-system-x86_64 -m 4G -serial stdio -boot c \
|
||||
-smp 4 \
|
||||
-audiodev coreaudio,id=audio0 -machine pcspk-audiodev=audio0 \
|
||||
-vga std -global VGA.xres=1920 -global VGA.yres=1080 \
|
||||
-display cocoa,show-cursor=off \
|
||||
-drive if=pflash,format=raw,readonly=on,file=$(OVMF_CODE) \
|
||||
-drive if=pflash,format=raw,file=$(OVMF_VARS) \
|
||||
-device ahci,id=ahci \
|
||||
-drive file=disk.qcow2,format=qcow2,if=none,id=disk0 -device ide-hd,bus=ahci.0,drive=disk0 \
|
||||
-drive file=disk.img,format=raw,if=none,id=disk1 -device ide-hd,bus=ahci.1,drive=disk1 \
|
||||
-cpu max
|
||||
|
||||
run-linux: $(ISO_IMAGE) disk.qcow2
|
||||
$(call PRINT_STEP,RUNNING BOREDOS IN QEMU ON LINUX)
|
||||
qemu-system-x86_64 -m 4G -serial stdio -cdrom $< -boot d \
|
||||
-smp 4 \
|
||||
-audiodev pa,id=audio0 -machine pcspk-audiodev=audio0 \
|
||||
-vga std -global VGA.xres=1920 -global VGA.yres=1080 \
|
||||
-display gtk,show-cursor=off \
|
||||
-drive file=disk.img,format=raw,file.locking=off \
|
||||
-device ahci,id=ahci -drive file=disk.qcow2,format=qcow2,if=none,id=disk0 -device ide-hd,bus=ahci.0,drive=disk0 \
|
||||
-cpu max
|
||||
|
|
|
|||
112
src/core/main.c
112
src/core/main.c
|
|
@ -235,6 +235,77 @@ static void fat32_mkdir_recursive(const char *path) {
|
|||
}
|
||||
}
|
||||
|
||||
static bool cmdline_has_flag(const char *cmdline, const char *flag) {
|
||||
if (!cmdline || !flag || !flag[0]) return false;
|
||||
int flag_len = (int)k_strlen(flag);
|
||||
const char *p = cmdline;
|
||||
while (*p) {
|
||||
while (*p == ' ') p++;
|
||||
if (!*p) break;
|
||||
const char *start = p;
|
||||
while (*p && *p != ' ') p++;
|
||||
int len = (int)(p - start);
|
||||
if (len == flag_len && k_strncmp(start, flag, (size_t)flag_len) == 0) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool cmdline_read_value(const char *cmdline, const char *key, char *out, int out_len) {
|
||||
if (!cmdline || !key || !out || out_len <= 1) return false;
|
||||
int key_len = (int)k_strlen(key);
|
||||
const char *p = cmdline;
|
||||
while (*p) {
|
||||
while (*p == ' ') p++;
|
||||
if (!*p) break;
|
||||
if (k_strncmp(p, key, (size_t)key_len) == 0) {
|
||||
const char *val = p + key_len;
|
||||
int i = 0;
|
||||
while (*val && *val != ' ' && i < out_len - 1) {
|
||||
out[i++] = *val++;
|
||||
}
|
||||
out[i] = '\0';
|
||||
return i > 0;
|
||||
}
|
||||
while (*p && *p != ' ') p++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void boot_parse_cmdline(const char *cmdline, uint32_t media_type) {
|
||||
g_bootfs_state.boot_flags = 0;
|
||||
g_bootfs_state.root_device[0] = '\0';
|
||||
|
||||
char root_arg[32];
|
||||
if (cmdline_read_value(cmdline, "root=", root_arg, (int)sizeof(root_arg))) {
|
||||
const char *dev = root_arg;
|
||||
if (dev[0] == '/' && dev[1] == 'd' && dev[2] == 'e' && dev[3] == 'v' && dev[4] == '/') {
|
||||
dev += 5;
|
||||
}
|
||||
int i = 0;
|
||||
while (dev[i] && i < (int)sizeof(g_bootfs_state.root_device) - 1) {
|
||||
g_bootfs_state.root_device[i] = dev[i];
|
||||
i++;
|
||||
}
|
||||
g_bootfs_state.root_device[i] = '\0';
|
||||
if (i > 0) g_bootfs_state.boot_flags |= BOOT_FLAG_ROOT_SET;
|
||||
}
|
||||
|
||||
bool force_live = cmdline_has_flag(cmdline, "--live");
|
||||
bool force_disk = cmdline_has_flag(cmdline, "--disk");
|
||||
|
||||
if (force_live) {
|
||||
g_bootfs_state.boot_flags |= BOOT_FLAG_LIVE | BOOT_FLAG_FORCED;
|
||||
} else if (force_disk) {
|
||||
g_bootfs_state.boot_flags |= BOOT_FLAG_DISK | BOOT_FLAG_FORCED;
|
||||
} else if (g_bootfs_state.boot_flags & BOOT_FLAG_ROOT_SET) {
|
||||
g_bootfs_state.boot_flags |= BOOT_FLAG_DISK;
|
||||
} else if (media_type == LIMINE_MEDIA_TYPE_OPTICAL || media_type == LIMINE_MEDIA_TYPE_TFTP) {
|
||||
g_bootfs_state.boot_flags |= BOOT_FLAG_LIVE;
|
||||
} else {
|
||||
g_bootfs_state.boot_flags |= BOOT_FLAG_DISK;
|
||||
}
|
||||
}
|
||||
|
||||
static bool usage_policy_prompt(void) {
|
||||
kconsole_set_active(true);
|
||||
serial_write("BoredOS - Please read the Usage Policy provided with this software before continuing.\n");
|
||||
|
|
@ -351,21 +422,6 @@ void kmain(void) {
|
|||
|
||||
fat32_init();
|
||||
log_ok("FAT32 ready");
|
||||
fat32_mkdir("/bin");
|
||||
fat32_mkdir("/Library");
|
||||
fat32_mkdir("/Library/images");
|
||||
fat32_mkdir("/Library/images/Wallpapers");
|
||||
fat32_mkdir("/Library/images/gif");
|
||||
fat32_mkdir("/Library/Fonts");
|
||||
fat32_mkdir("/Library/DOOM");
|
||||
fat32_mkdir("/Library/conf");
|
||||
fat32_mkdir("/Library/bsh");
|
||||
fat32_mkdir("/docs");
|
||||
fat32_mkdir("/root");
|
||||
fat32_mkdir("/root/Desktop");
|
||||
fat32_mkdir("/root/Pictures");
|
||||
fat32_mkdir("/root/Documents");
|
||||
fat32_mkdir("/root/Downloads");
|
||||
|
||||
sysfs_init_subsystems();
|
||||
vfs_mount("/sys", "sysfs", "sysfs", sysfs_get_ops(), NULL);
|
||||
|
|
@ -388,6 +444,14 @@ void kmain(void) {
|
|||
serial_write_hex(g_bootfs_state.kernel_size);
|
||||
serial_write(" bytes\n");
|
||||
}
|
||||
|
||||
if (kernel_file_request.response != NULL && kernel_file_request.response->kernel_file != NULL) {
|
||||
const char *cmdline = kernel_file_request.response->kernel_file->cmdline;
|
||||
uint32_t media_type = kernel_file_request.response->kernel_file->media_type;
|
||||
boot_parse_cmdline(cmdline, media_type);
|
||||
} else {
|
||||
boot_parse_cmdline(NULL, LIMINE_MEDIA_TYPE_GENERIC);
|
||||
}
|
||||
|
||||
extern uint32_t wm_get_ticks(void);
|
||||
g_bootfs_state.boot_time_ms = wm_get_ticks();
|
||||
|
|
@ -415,6 +479,7 @@ void kmain(void) {
|
|||
if (path_len >= 5 && path[path_len-4] == '.' && path[path_len-3] == 't' &&
|
||||
path[path_len-2] == 'a' && path[path_len-1] == 'r') {
|
||||
g_bootfs_state.initrd_size = mod->size;
|
||||
g_bootfs_state.initrd_ptr = mod->address;
|
||||
serial_write("[INIT] -> Initrd detected\n");
|
||||
}
|
||||
}
|
||||
|
|
@ -488,7 +553,15 @@ void kmain(void) {
|
|||
smp_init(NULL);
|
||||
}
|
||||
|
||||
if (!usage_policy_prompt()) {
|
||||
bool bypass_tos = false;
|
||||
if (kernel_file_request.response != NULL && kernel_file_request.response->kernel_file != NULL) {
|
||||
const char *cmdline = kernel_file_request.response->kernel_file->cmdline;
|
||||
if (cmdline != NULL && k_strstr(cmdline, "--accept-tos") != NULL) {
|
||||
bypass_tos = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bypass_tos && !usage_policy_prompt()) {
|
||||
log_fail("Usage policy not accepted, halting");
|
||||
hcf();
|
||||
}
|
||||
|
|
@ -500,10 +573,5 @@ void kmain(void) {
|
|||
extern void bootfs_refresh_from_disk(void);
|
||||
bootfs_refresh_from_disk();
|
||||
|
||||
while (1) {
|
||||
wm_process_input();
|
||||
wm_process_deferred_thumbs();
|
||||
wallpaper_process_pending();
|
||||
asm("hlt");
|
||||
}
|
||||
wm_run_loop();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ void get_os_info(os_info_t *info) {
|
|||
for (size_t i = 0; i < sizeof(os_info_t); i++) p[i] = 0;
|
||||
|
||||
const char *os_name = "BoredOS";
|
||||
const char *os_version = "26.5.1-stable";
|
||||
const char *os_version = "26.5.1-dev";
|
||||
const char *os_codename = "Genesis";
|
||||
const char *kernel_name = "Boredkernel";
|
||||
const char *kernel_version = "4.2.1-stable";
|
||||
const char *kernel_version = "4.2.1-dev";
|
||||
const char *build_date = __DATE__;
|
||||
const char *build_time = __TIME__;
|
||||
const char *build_arch = "x86_64";
|
||||
|
|
|
|||
|
|
@ -155,3 +155,29 @@ void paging_destroy_user_pml4_phys(uint64_t pml4_phys) {
|
|||
extern void kfree(void* ptr);
|
||||
kfree((void*)pml4);
|
||||
}
|
||||
|
||||
uint64_t paging_virt2phys(uint64_t pml4_phys, uint64_t virtual_addr) {
|
||||
if (!pml4_phys) return 0;
|
||||
|
||||
if (virtual_addr >= 0xFFFF800000000000ULL) {
|
||||
return v2p(virtual_addr);
|
||||
}
|
||||
|
||||
page_table_t* pml4 = (page_table_t*)p2v(pml4_phys);
|
||||
uint64_t pml4_index = (virtual_addr >> 39) & 0x1FF;
|
||||
if (!(pml4->entries[pml4_index] & PT_PRESENT)) return 0;
|
||||
|
||||
page_table_t* pdpt = (page_table_t*)p2v(pml4->entries[pml4_index] & PT_ADDR_MASK);
|
||||
uint64_t pdpt_index = (virtual_addr >> 30) & 0x1FF;
|
||||
if (!(pdpt->entries[pdpt_index] & PT_PRESENT)) return 0;
|
||||
|
||||
page_table_t* pd = (page_table_t*)p2v(pdpt->entries[pdpt_index] & PT_ADDR_MASK);
|
||||
uint64_t pd_index = (virtual_addr >> 21) & 0x1FF;
|
||||
if (!(pd->entries[pd_index] & PT_PRESENT)) return 0;
|
||||
|
||||
page_table_t* pt = (page_table_t*)p2v(pd->entries[pd_index] & PT_ADDR_MASK);
|
||||
uint64_t pt_index = (virtual_addr >> 12) & 0x1FF;
|
||||
if (!(pt->entries[pt_index] & PT_PRESENT)) return 0;
|
||||
|
||||
return (pt->entries[pt_index] & PT_ADDR_MASK) | (virtual_addr & 0xFFF);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,5 +38,6 @@ void paging_switch_directory(uint64_t pml4_phys);
|
|||
void paging_destroy_user_pml4_phys(uint64_t pml4_phys);
|
||||
|
||||
void paging_init(void);
|
||||
uint64_t paging_virt2phys(uint64_t pml4_phys, uint64_t virtual_addr);
|
||||
|
||||
#endif // PAGING_H
|
||||
|
|
|
|||
|
|
@ -161,13 +161,13 @@ process_t* process_create(void (*entry_point)(void), bool is_user) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// 2. Allocate aligned stack
|
||||
void* user_stack = kmalloc_aligned(4096, 4096);
|
||||
void* user_stack = kmalloc_aligned(131072, 4096);
|
||||
void* kernel_stack = kmalloc_aligned(32768, 32768); // Needed for when user interrupts to Ring 0
|
||||
|
||||
if (is_user) {
|
||||
// Map user stack to 0x800000
|
||||
paging_map_page(new_proc->pml4_phys, 0x800000, v2p((uint64_t)user_stack), PT_PRESENT | PT_RW | PT_USER);
|
||||
for (int i = 0; i < 32; i++) {
|
||||
paging_map_page(new_proc->pml4_phys, 0x800000 + i*4096, v2p((uint64_t)user_stack + i*4096), PT_PRESENT | PT_RW | PT_USER);
|
||||
}
|
||||
|
||||
// Allocate code page aligned and copy code
|
||||
void* code = kmalloc_aligned(4096, 4096);
|
||||
|
|
@ -180,7 +180,7 @@ process_t* process_create(void (*entry_point)(void), bool is_user) {
|
|||
uint64_t* stack_ptr = (uint64_t*)((uint64_t)kernel_stack + 32768);
|
||||
|
||||
*(--stack_ptr) = 0x1B; // SS (User Data)
|
||||
*(--stack_ptr) = 0x800000 + 4096; // RSP
|
||||
*(--stack_ptr) = 0x800000 + 131072; // RSP
|
||||
*(--stack_ptr) = 0x202; // RFLAGS (IF=1)
|
||||
*(--stack_ptr) = 0x23; // CS (User Code)
|
||||
*(--stack_ptr) = 0x400000; // RIP
|
||||
|
|
|
|||
Loading…
Reference in a new issue