...
This commit is contained in:
2
.clangd
2
.clangd
@@ -1,2 +0,0 @@
|
|||||||
CompileFlags:
|
|
||||||
Add: [ -m32, -ffreestanding, -fno-stack-protector, -nostdlib, -nostdinc, -Wall, -Wextra, -std=c23 ]
|
|
||||||
8
makefile
8
makefile
@@ -8,7 +8,7 @@ LDFLAGS = -g
|
|||||||
ASFLAGS = -g -F dwarf
|
ASFLAGS = -g -F dwarf
|
||||||
|
|
||||||
# Do not modify
|
# Do not modify
|
||||||
CFLAGS += -m32 -ffreestanding -fno-stack-protector -nostdlib -nostdinc -Wall -Wextra -std=c23
|
CFLAGS += -m32 -ffreestanding -fno-stack-protector -nostdlib -nostdinc -Wall -Wextra -std=c23 -Isrc/shared
|
||||||
LDFLAGS +=
|
LDFLAGS +=
|
||||||
ASFLAGS += -f elf32
|
ASFLAGS += -f elf32
|
||||||
|
|
||||||
@@ -26,14 +26,14 @@ run: .build/nub-os.iso
|
|||||||
clean:
|
clean:
|
||||||
@rm -r .build 2>/dev/null || true
|
@rm -r .build 2>/dev/null || true
|
||||||
|
|
||||||
.build/nub-os.iso: .build/nub-os src/grub.cfg
|
.build/nub-os.iso: .build/nub-os src/boot/grub.cfg
|
||||||
mkdir -p .build/grub/boot/grub
|
mkdir -p .build/grub/boot/grub
|
||||||
cp src/grub.cfg .build/grub/boot/grub
|
cp src/boot/grub.cfg .build/grub/boot/grub
|
||||||
cp .build/nub-os .build/grub/boot/
|
cp .build/nub-os .build/grub/boot/
|
||||||
grub-mkrescue -o .build/nub-os.iso .build/grub/
|
grub-mkrescue -o .build/nub-os.iso .build/grub/
|
||||||
|
|
||||||
.build/nub-os: $(OBJS)
|
.build/nub-os: $(OBJS)
|
||||||
$(LD) $(LDFLAGS) -T src/linker.ld -o $@ $^
|
$(LD) $(LDFLAGS) -T linker/x86_64.ld -o $@ $^
|
||||||
|
|
||||||
.build/%.o: src/%.c
|
.build/%.o: src/%.c
|
||||||
@mkdir -p $(dir $@)
|
@mkdir -p $(dir $@)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
global _start
|
global _start
|
||||||
extern kmain
|
extern c_start
|
||||||
|
|
||||||
%define MAGIC 0xe85250d6
|
%define MAGIC 0xe85250d6
|
||||||
%define ARCH 0x0
|
%define ARCH 0x0
|
||||||
@@ -27,10 +27,12 @@ stack:
|
|||||||
.top:
|
.top:
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
bits 32
|
|
||||||
_start:
|
_start:
|
||||||
mov esp, stack.top
|
mov esp, stack.top
|
||||||
call kmain
|
push ebx
|
||||||
|
push eax
|
||||||
|
call c_start
|
||||||
|
add esp, 8
|
||||||
.halt:
|
.halt:
|
||||||
cli
|
cli
|
||||||
hlt
|
hlt
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "console.h"
|
#include "console.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#define ROWS 25
|
#define ROWS 25
|
||||||
#define COLUMNS 80
|
#define COLUMNS 80
|
||||||
@@ -96,3 +97,72 @@ void console_clear() {
|
|||||||
cursor_row = 0;
|
cursor_row = 0;
|
||||||
cursor_col = 0;
|
cursor_col = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Supported formats:
|
||||||
|
// - `d`: i32 (decimal)
|
||||||
|
// - `u`: u32 (decimal)
|
||||||
|
// - `x`: u32 (hex)
|
||||||
|
// - `c`: char (ascii)
|
||||||
|
// - `s`: char* (ascii string)
|
||||||
|
//
|
||||||
|
// ```c
|
||||||
|
// printf(
|
||||||
|
// "The answer is %d is located at offset %x in file %s",
|
||||||
|
// 42,
|
||||||
|
// 0x2000
|
||||||
|
// "hitchhiker.txt"
|
||||||
|
// );
|
||||||
|
// ```
|
||||||
|
void kprintf(const char *fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
|
||||||
|
bool should_format = false;
|
||||||
|
|
||||||
|
for (size_t i = 0; fmt[i] != '\0'; i++) {
|
||||||
|
if (should_format) {
|
||||||
|
should_format = false;
|
||||||
|
|
||||||
|
if (fmt[i] == '%') {
|
||||||
|
console_putchar('%', VGA_DEFAULT_COLOR);
|
||||||
|
} else if (fmt[i] == 's') {
|
||||||
|
const char *str = va_arg(args, const char *);
|
||||||
|
for (size_t j = 0; str[j] != '\0'; j++) {
|
||||||
|
console_putchar(str[j], VGA_DEFAULT_COLOR);
|
||||||
|
}
|
||||||
|
} else if (fmt[i] == 'c') {
|
||||||
|
char character = (char)va_arg(args, u32);
|
||||||
|
console_putchar(character, VGA_DEFAULT_COLOR);
|
||||||
|
} else if (fmt[i] == 'd') {
|
||||||
|
u32 val = va_arg(args, u32);
|
||||||
|
char buf[21];
|
||||||
|
itoa(val, buf);
|
||||||
|
for (size_t j = 0; buf[j] != '\0'; j++) {
|
||||||
|
console_putchar(buf[j], VGA_DEFAULT_COLOR);
|
||||||
|
}
|
||||||
|
} else if (fmt[i] == 'u') {
|
||||||
|
u32 val = va_arg(args, u32);
|
||||||
|
char buf[21];
|
||||||
|
uitoa(val, buf);
|
||||||
|
for (size_t j = 0; buf[j] != '\0'; j++) {
|
||||||
|
console_putchar(buf[j], VGA_DEFAULT_COLOR);
|
||||||
|
}
|
||||||
|
} else if (fmt[i] == 'x') {
|
||||||
|
u32 val = va_arg(args, u32);
|
||||||
|
char buf[17];
|
||||||
|
uitoa_hex(val, buf);
|
||||||
|
for (size_t j = 0; buf[j] != '\0'; j++) {
|
||||||
|
console_putchar(buf[j], VGA_DEFAULT_COLOR);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console_putchar(fmt[i], VGA_DEFAULT_COLOR);
|
||||||
|
}
|
||||||
|
} else if (fmt[i] == '%') {
|
||||||
|
should_format = true;
|
||||||
|
} else {
|
||||||
|
console_putchar(fmt[i], VGA_DEFAULT_COLOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "def.h"
|
#include <def.h>
|
||||||
|
|
||||||
#define VGA_BLACK 0
|
#define VGA_BLACK 0
|
||||||
#define VGA_BLUE 1
|
#define VGA_BLUE 1
|
||||||
@@ -25,3 +25,5 @@
|
|||||||
|
|
||||||
void console_putchar(char character, u8 color);
|
void console_putchar(char character, u8 color);
|
||||||
void console_clear();
|
void console_clear();
|
||||||
|
|
||||||
|
void kprintf(const char *fmt, ...);
|
||||||
154
src/boot/entry.c
Normal file
154
src/boot/entry.c
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
#include <def.h>
|
||||||
|
#include "console.h"
|
||||||
|
#include "multiboot2.h"
|
||||||
|
|
||||||
|
static inline void hlt() {
|
||||||
|
asm("hlt");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void cli() {
|
||||||
|
asm("cli");
|
||||||
|
}
|
||||||
|
|
||||||
|
void kpanic(const char *message) {
|
||||||
|
kprintf("panic: %s\n", message);
|
||||||
|
while (true) {
|
||||||
|
cli();
|
||||||
|
hlt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 align(u32 num, u32 alignment) {
|
||||||
|
return (num + alignment - 1) & ~(alignment - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void c_start(u32 magic, uptr multiboot_info) {
|
||||||
|
console_clear();
|
||||||
|
|
||||||
|
if (magic != MULTIBOOT_BOOTLOADER_MAGIC) {
|
||||||
|
kpanic("Magic is wrong");
|
||||||
|
}
|
||||||
|
|
||||||
|
uptr next = multiboot_info + 8;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
multiboot_tag *tag = (multiboot_tag*)next;
|
||||||
|
|
||||||
|
if (tag->type == MULTIBOOT_TAG_TYPE_END) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (tag->type) {
|
||||||
|
case MULTIBOOT_TAG_TYPE_CMDLINE: {
|
||||||
|
multiboot_tag_string *tag_cmdline = (multiboot_tag_string*)tag;
|
||||||
|
kprintf("cmdline: %s\n", tag_cmdline->string);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME: {
|
||||||
|
multiboot_tag_string *tag_bootloader = (multiboot_tag_string*)tag;
|
||||||
|
kprintf("bootloader: %s\n", tag_bootloader->string);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MULTIBOOT_TAG_TYPE_MODULE: {
|
||||||
|
multiboot_tag_module *tag_module = (multiboot_tag_module*)tag;
|
||||||
|
kprintf("MULTIBOOT_TAG_TYPE_MODULE\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO: {
|
||||||
|
multiboot_tag_basic_meminfo *tag_basic_meminfo = (multiboot_tag_basic_meminfo*)tag;
|
||||||
|
kprintf("MULTIBOOT_TAG_TYPE_BASIC_MEMINFO\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MULTIBOOT_TAG_TYPE_BOOTDEV: {
|
||||||
|
multiboot_tag_bootdev *tag_bootdev = (multiboot_tag_bootdev*)tag;
|
||||||
|
kprintf("MULTIBOOT_TAG_TYPE_BOOTDEV\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MULTIBOOT_TAG_TYPE_MMAP: {
|
||||||
|
multiboot_tag_mmap *tag_mmap = (multiboot_tag_mmap*)tag;
|
||||||
|
kprintf("MULTIBOOT_TAG_TYPE_MMAP\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MULTIBOOT_TAG_TYPE_VBE: {
|
||||||
|
multiboot_tag_vbe *tag_vbe = (multiboot_tag_vbe*)tag;
|
||||||
|
kprintf("MULTIBOOT_TAG_TYPE_VBE\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MULTIBOOT_TAG_TYPE_FRAMEBUFFER: {
|
||||||
|
multiboot_tag_framebuffer *tag_framebuffer = (multiboot_tag_framebuffer*)tag;
|
||||||
|
kprintf("MULTIBOOT_TAG_TYPE_FRAMEBUFFER\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MULTIBOOT_TAG_TYPE_ELF_SECTIONS: {
|
||||||
|
multiboot_tag_elf_sections *tag_elf_sections = (multiboot_tag_elf_sections*)tag;
|
||||||
|
kprintf("MULTIBOOT_TAG_TYPE_ELF_SECTIONS\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MULTIBOOT_TAG_TYPE_APM: {
|
||||||
|
multiboot_tag_apm *tag_apm = (multiboot_tag_apm*)tag;
|
||||||
|
kprintf("MULTIBOOT_TAG_TYPE_APM\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MULTIBOOT_TAG_TYPE_EFI32: {
|
||||||
|
multiboot_tag_efi32 *tag_efi32 = (multiboot_tag_efi32*)tag;
|
||||||
|
kprintf("MULTIBOOT_TAG_TYPE_EFI32\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MULTIBOOT_TAG_TYPE_EFI64: {
|
||||||
|
multiboot_tag_efi64 *tag_efi64 = (multiboot_tag_efi64*)tag;
|
||||||
|
kprintf("MULTIBOOT_TAG_TYPE_EFI64\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MULTIBOOT_TAG_TYPE_SMBIOS: {
|
||||||
|
multiboot_tag_smbios *tag_smbios = (multiboot_tag_smbios*)tag;
|
||||||
|
kprintf("MULTIBOOT_TAG_TYPE_SMBIOS\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MULTIBOOT_TAG_TYPE_ACPI_OLD: {
|
||||||
|
multiboot_tag_old_acpi *tag_old_acpi = (multiboot_tag_old_acpi*)tag;
|
||||||
|
kprintf("MULTIBOOT_TAG_TYPE_ACPI_OLD\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MULTIBOOT_TAG_TYPE_ACPI_NEW: {
|
||||||
|
multiboot_tag_new_acpi *tag_new_acpi = (multiboot_tag_new_acpi*)tag;
|
||||||
|
kprintf("MULTIBOOT_TAG_TYPE_ACPI_NEW\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MULTIBOOT_TAG_TYPE_NETWORK: {
|
||||||
|
multiboot_tag_network *tag_network = (multiboot_tag_network*)tag;
|
||||||
|
kprintf("MULTIBOOT_TAG_TYPE_NETWORK\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MULTIBOOT_TAG_TYPE_EFI_MMAP: {
|
||||||
|
multiboot_tag_efi_mmap *tag_efi_mmap = (multiboot_tag_efi_mmap*)tag;
|
||||||
|
kprintf("MULTIBOOT_TAG_TYPE_EFI_MMAP\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MULTIBOOT_TAG_TYPE_EFI_BS: {
|
||||||
|
// note(nub31): Just a flag, no data
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MULTIBOOT_TAG_TYPE_EFI32_IH: {
|
||||||
|
multiboot_tag_efi32_ih *tag_efi32_ih = (multiboot_tag_efi32_ih*)tag;
|
||||||
|
kprintf("MULTIBOOT_TAG_TYPE_EFI32_IH\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MULTIBOOT_TAG_TYPE_EFI64_IH: {
|
||||||
|
multiboot_tag_efi64_ih *tag_efi64_ih = (multiboot_tag_efi64_ih*)tag;
|
||||||
|
kprintf("MULTIBOOT_TAG_TYPE_EFI64_IH\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR: {
|
||||||
|
multiboot_tag_load_base_addr *tag_load_base_addr = (multiboot_tag_load_base_addr*)tag;
|
||||||
|
kprintf("MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
kpanic("Unhandled multiboot tag");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
next = align(next + tag->size, MULTIBOOT_TAG_ALIGN);
|
||||||
|
}
|
||||||
|
}
|
||||||
221
src/boot/multiboot2.h
Normal file
221
src/boot/multiboot2.h
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define MULTIBOOT_BOOTLOADER_MAGIC 0x36d76289
|
||||||
|
|
||||||
|
#define MULTIBOOT_TAG_ALIGN 8
|
||||||
|
|
||||||
|
#define MULTIBOOT_TAG_TYPE_END 0
|
||||||
|
#define MULTIBOOT_TAG_TYPE_CMDLINE 1
|
||||||
|
#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2
|
||||||
|
#define MULTIBOOT_TAG_TYPE_MODULE 3
|
||||||
|
#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4
|
||||||
|
#define MULTIBOOT_TAG_TYPE_BOOTDEV 5
|
||||||
|
#define MULTIBOOT_TAG_TYPE_MMAP 6
|
||||||
|
#define MULTIBOOT_TAG_TYPE_VBE 7
|
||||||
|
#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8
|
||||||
|
#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9
|
||||||
|
#define MULTIBOOT_TAG_TYPE_APM 10
|
||||||
|
#define MULTIBOOT_TAG_TYPE_EFI32 11
|
||||||
|
#define MULTIBOOT_TAG_TYPE_EFI64 12
|
||||||
|
#define MULTIBOOT_TAG_TYPE_SMBIOS 13
|
||||||
|
#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14
|
||||||
|
#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15
|
||||||
|
#define MULTIBOOT_TAG_TYPE_NETWORK 16
|
||||||
|
#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17
|
||||||
|
#define MULTIBOOT_TAG_TYPE_EFI_BS 18
|
||||||
|
#define MULTIBOOT_TAG_TYPE_EFI32_IH 19
|
||||||
|
#define MULTIBOOT_TAG_TYPE_EFI64_IH 20
|
||||||
|
#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u8 red;
|
||||||
|
u8 green;
|
||||||
|
u8 blue;
|
||||||
|
} multiboot_color;
|
||||||
|
|
||||||
|
#define MULTIBOOT_MEMORY_AVAILABLE 1
|
||||||
|
#define MULTIBOOT_MEMORY_RESERVED 2
|
||||||
|
#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3
|
||||||
|
#define MULTIBOOT_MEMORY_NVS 4
|
||||||
|
#define MULTIBOOT_MEMORY_BADRAM 5
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 type;
|
||||||
|
u32 size;
|
||||||
|
} multiboot_tag;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 type;
|
||||||
|
u32 size;
|
||||||
|
char string[0];
|
||||||
|
} multiboot_tag_string;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 type;
|
||||||
|
u32 size;
|
||||||
|
u32 mod_start;
|
||||||
|
u32 mod_end;
|
||||||
|
char cmdline[0];
|
||||||
|
} multiboot_tag_module;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 type;
|
||||||
|
u32 size;
|
||||||
|
u32 mem_lower;
|
||||||
|
u32 mem_upper;
|
||||||
|
} multiboot_tag_basic_meminfo;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 type;
|
||||||
|
u32 size;
|
||||||
|
u32 biosdev;
|
||||||
|
u32 slice;
|
||||||
|
u32 part;
|
||||||
|
} multiboot_tag_bootdev;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u64 addr;
|
||||||
|
u64 len;
|
||||||
|
u32 type;
|
||||||
|
u32 zero;
|
||||||
|
} multiboot_mmap_entry;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 type;
|
||||||
|
u32 size;
|
||||||
|
u32 entry_size;
|
||||||
|
u32 entry_version;
|
||||||
|
multiboot_mmap_entry entries[0];
|
||||||
|
} multiboot_tag_mmap;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 type;
|
||||||
|
u32 size;
|
||||||
|
|
||||||
|
u16 vbe_mode;
|
||||||
|
u16 vbe_interface_seg;
|
||||||
|
u16 vbe_interface_off;
|
||||||
|
u16 vbe_interface_len;
|
||||||
|
|
||||||
|
u8 vbe_control_info[512];
|
||||||
|
u8 vbe_mode_info[256];
|
||||||
|
} multiboot_tag_vbe;
|
||||||
|
|
||||||
|
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
|
||||||
|
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
|
||||||
|
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 type;
|
||||||
|
u32 size;
|
||||||
|
u64 framebuffer_addr;
|
||||||
|
u32 framebuffer_pitch;
|
||||||
|
u32 framebuffer_width;
|
||||||
|
u32 framebuffer_height;
|
||||||
|
u8 framebuffer_bpp;
|
||||||
|
u8 framebuffer_type;
|
||||||
|
u16 reserved;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
u16 framebuffer_palette_num_colors;
|
||||||
|
multiboot_color framebuffer_palette[0];
|
||||||
|
};
|
||||||
|
struct {
|
||||||
|
u8 framebuffer_red_field_position;
|
||||||
|
u8 framebuffer_red_mask_size;
|
||||||
|
u8 framebuffer_green_field_position;
|
||||||
|
u8 framebuffer_green_mask_size;
|
||||||
|
u8 framebuffer_blue_field_position;
|
||||||
|
u8 framebuffer_blue_mask_size;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} multiboot_tag_framebuffer;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 type;
|
||||||
|
u32 size;
|
||||||
|
u32 num;
|
||||||
|
u32 entsize;
|
||||||
|
u32 shndx;
|
||||||
|
char sections[0];
|
||||||
|
} multiboot_tag_elf_sections;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 type;
|
||||||
|
u32 size;
|
||||||
|
u16 version;
|
||||||
|
u16 cseg;
|
||||||
|
u32 offset;
|
||||||
|
u16 cseg_16;
|
||||||
|
u16 dseg;
|
||||||
|
u16 flags;
|
||||||
|
u16 cseg_len;
|
||||||
|
u16 cseg_16_len;
|
||||||
|
u16 dseg_len;
|
||||||
|
} multiboot_tag_apm;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 type;
|
||||||
|
u32 size;
|
||||||
|
u32 pointer;
|
||||||
|
} multiboot_tag_efi32;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 type;
|
||||||
|
u32 size;
|
||||||
|
u64 pointer;
|
||||||
|
} multiboot_tag_efi64;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 type;
|
||||||
|
u32 size;
|
||||||
|
u8 major;
|
||||||
|
u8 minor;
|
||||||
|
u8 reserved[6];
|
||||||
|
u8 tables[0];
|
||||||
|
} multiboot_tag_smbios;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 type;
|
||||||
|
u32 size;
|
||||||
|
u8 rsdp[0];
|
||||||
|
} multiboot_tag_old_acpi;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 type;
|
||||||
|
u32 size;
|
||||||
|
u8 rsdp[0];
|
||||||
|
} multiboot_tag_new_acpi;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 type;
|
||||||
|
u32 size;
|
||||||
|
u8 dhcpack[0];
|
||||||
|
} multiboot_tag_network;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 type;
|
||||||
|
u32 size;
|
||||||
|
u32 descr_size;
|
||||||
|
u32 descr_vers;
|
||||||
|
u8 efi_mmap[0];
|
||||||
|
} multiboot_tag_efi_mmap;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 type;
|
||||||
|
u32 size;
|
||||||
|
u32 pointer;
|
||||||
|
} multiboot_tag_efi32_ih;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 type;
|
||||||
|
u32 size;
|
||||||
|
u64 pointer;
|
||||||
|
} multiboot_tag_efi64_ih;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 type;
|
||||||
|
u32 size;
|
||||||
|
u32 load_base_addr;
|
||||||
|
} multiboot_tag_load_base_addr;
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#include "console.h"
|
|
||||||
#include "print.h"
|
|
||||||
|
|
||||||
// Multiboot 2 puts us in 32-bit protected mode with interrupts disabled
|
|
||||||
void kmain(void) {
|
|
||||||
console_clear();
|
|
||||||
kprintf("booting nub-os\n");
|
|
||||||
}
|
|
||||||
73
src/print.c
73
src/print.c
@@ -1,73 +0,0 @@
|
|||||||
#include "print.h"
|
|
||||||
#include "console.h"
|
|
||||||
#include "def.h"
|
|
||||||
#include "string.h"
|
|
||||||
|
|
||||||
// Supported formats:
|
|
||||||
// - `d`: i32 (decimal)
|
|
||||||
// - `u`: u32 (decimal)
|
|
||||||
// - `x`: u32 (hex)
|
|
||||||
// - `c`: char (ascii)
|
|
||||||
// - `s`: char* (ascii string)
|
|
||||||
//
|
|
||||||
// ```c
|
|
||||||
// printf(
|
|
||||||
// "The answer is %d is located at offset %x in file %s",
|
|
||||||
// 42,
|
|
||||||
// 0x2000
|
|
||||||
// "hitchhiker.txt"
|
|
||||||
// );
|
|
||||||
// ```
|
|
||||||
void kprintf(const char *fmt, ...) {
|
|
||||||
va_list args;
|
|
||||||
va_start(args, fmt);
|
|
||||||
|
|
||||||
bool should_format = false;
|
|
||||||
|
|
||||||
for (size_t i = 0; fmt[i] != '\0'; i++) {
|
|
||||||
if (should_format) {
|
|
||||||
should_format = false;
|
|
||||||
|
|
||||||
if (fmt[i] == '%') {
|
|
||||||
console_putchar('%', VGA_DEFAULT_COLOR);
|
|
||||||
} else if (fmt[i] == 's') {
|
|
||||||
const char *str = va_arg(args, const char *);
|
|
||||||
for (size_t j = 0; str[j] != '\0'; j++) {
|
|
||||||
console_putchar(str[j], VGA_DEFAULT_COLOR);
|
|
||||||
}
|
|
||||||
} else if (fmt[i] == 'c') {
|
|
||||||
char character = (char)va_arg(args, u32);
|
|
||||||
console_putchar(character, VGA_DEFAULT_COLOR);
|
|
||||||
} else if (fmt[i] == 'd') {
|
|
||||||
u32 val = va_arg(args, u32);
|
|
||||||
char buf[21];
|
|
||||||
itoa(val, buf);
|
|
||||||
for (size_t j = 0; buf[j] != '\0'; j++) {
|
|
||||||
console_putchar(buf[j], VGA_DEFAULT_COLOR);
|
|
||||||
}
|
|
||||||
} else if (fmt[i] == 'u') {
|
|
||||||
u32 val = va_arg(args, u32);
|
|
||||||
char buf[21];
|
|
||||||
uitoa(val, buf);
|
|
||||||
for (size_t j = 0; buf[j] != '\0'; j++) {
|
|
||||||
console_putchar(buf[j], VGA_DEFAULT_COLOR);
|
|
||||||
}
|
|
||||||
} else if (fmt[i] == 'x') {
|
|
||||||
u32 val = va_arg(args, u32);
|
|
||||||
char buf[17];
|
|
||||||
uitoa_hex(val, buf);
|
|
||||||
for (size_t j = 0; buf[j] != '\0'; j++) {
|
|
||||||
console_putchar(buf[j], VGA_DEFAULT_COLOR);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console_putchar(fmt[i], VGA_DEFAULT_COLOR);
|
|
||||||
}
|
|
||||||
} else if (fmt[i] == '%') {
|
|
||||||
should_format = true;
|
|
||||||
} else {
|
|
||||||
console_putchar(fmt[i], VGA_DEFAULT_COLOR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
void kprintf(const char *fmt, ...);
|
|
||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
typedef __builtin_va_list va_list;
|
typedef __builtin_va_list va_list;
|
||||||
|
|
||||||
|
#define asm __asm__
|
||||||
|
|
||||||
#define va_start(ap, last) __builtin_va_start(ap, last)
|
#define va_start(ap, last) __builtin_va_start(ap, last)
|
||||||
#define va_arg(ap, type) __builtin_va_arg(ap, type)
|
#define va_arg(ap, type) __builtin_va_arg(ap, type)
|
||||||
#define va_end(ap) __builtin_va_end(ap)
|
#define va_end(ap) __builtin_va_end(ap)
|
||||||
@@ -14,6 +16,8 @@ typedef __builtin_va_list va_list;
|
|||||||
typedef unsigned long size_t;
|
typedef unsigned long size_t;
|
||||||
typedef unsigned long uintptr_t;
|
typedef unsigned long uintptr_t;
|
||||||
|
|
||||||
|
typedef unsigned long uptr;
|
||||||
|
|
||||||
#define offsetof(type, member) __builtin_offsetof(type, member)
|
#define offsetof(type, member) __builtin_offsetof(type, member)
|
||||||
|
|
||||||
typedef unsigned char u8;
|
typedef unsigned char u8;
|
||||||
@@ -22,6 +26,8 @@ typedef unsigned short u16;
|
|||||||
typedef signed short i16;
|
typedef signed short i16;
|
||||||
typedef unsigned int u32;
|
typedef unsigned int u32;
|
||||||
typedef signed int i32;
|
typedef signed int i32;
|
||||||
|
typedef unsigned long long u64;
|
||||||
|
typedef signed long long i64;
|
||||||
|
|
||||||
#define I8_MIN (-128)
|
#define I8_MIN (-128)
|
||||||
#define I8_MAX 127
|
#define I8_MAX 127
|
||||||
@@ -41,6 +47,12 @@ typedef signed int i32;
|
|||||||
#define U32_MIN 0x0
|
#define U32_MIN 0x0
|
||||||
#define U32_MAX 0xffffffffU
|
#define U32_MAX 0xffffffffU
|
||||||
|
|
||||||
|
#define I64_MIN (-9223372036854775807LL - 1)
|
||||||
|
#define I64_MAX 9223372036854775807LL
|
||||||
|
|
||||||
|
#define U64_MIN 0x0
|
||||||
|
#define U64_MAX 0xffffffffffffffffULL
|
||||||
|
|
||||||
#define I8_C(x) x
|
#define I8_C(x) x
|
||||||
#define U8_C(x) x##U
|
#define U8_C(x) x##U
|
||||||
|
|
||||||
@@ -50,6 +62,9 @@ typedef signed int i32;
|
|||||||
#define I32_C(x) x
|
#define I32_C(x) x
|
||||||
#define U32_C(x) x##U
|
#define U32_C(x) x##U
|
||||||
|
|
||||||
|
#define I64_C(x) x##LL
|
||||||
|
#define U64_C(x) x##ULL
|
||||||
|
|
||||||
#define KiB(count) (U64_C(count) * U64_C(1024))
|
#define KiB(count) (U64_C(count) * U64_C(1024))
|
||||||
#define MiB(count) (U64_C(count) * U64_C(1024) * U64_C(1024))
|
#define MiB(count) (U64_C(count) * U64_C(1024) * U64_C(1024))
|
||||||
#define GiB(count) (U64_C(count) * U64_C(1024) * U64_C(1024) * U64_C(1024))
|
#define GiB(count) (U64_C(count) * U64_C(1024) * U64_C(1024) * U64_C(1024))
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "def.h"
|
#include <def.h>
|
||||||
|
|
||||||
int strcmp(const char *a, const char *b);
|
int strcmp(const char *a, const char *b);
|
||||||
void reverse(char *str, size_t length);
|
void reverse(char *str, size_t length);
|
||||||
Reference in New Issue
Block a user