feat: initial
This commit is contained in:
commit
92d8a91be4
20 changed files with 1058 additions and 0 deletions
3
kernel/include/init/init.h
Normal file
3
kernel/include/init/init.h
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
[[maybe_unused]] [[noreturn]] __attribute__((used)) void init();
|
||||
303
kernel/include/init/multiboot2.h
Normal file
303
kernel/include/init/multiboot2.h
Normal file
|
|
@ -0,0 +1,303 @@
|
|||
#pragma once
|
||||
|
||||
#include "util/number.h"
|
||||
#include "util/function.h"
|
||||
#include "memory/pointer.h"
|
||||
|
||||
namespace multiboot {
|
||||
|
||||
inline constexpr uint32_t magic = 0x36d76289;
|
||||
inline constexpr uint32_t alignment = 8;
|
||||
|
||||
enum class tag_type : uint32_t {
|
||||
end = 0,
|
||||
cmdline = 1,
|
||||
boot_loader_name = 2,
|
||||
module = 3,
|
||||
basic_meminfo = 4,
|
||||
bootdev = 5,
|
||||
mmap = 6,
|
||||
vbe = 7,
|
||||
framebuffer = 8,
|
||||
elf_sections = 9,
|
||||
apm = 10,
|
||||
efi32 = 14,
|
||||
efi64 = 15,
|
||||
smbios = 16,
|
||||
acpi_old = 17,
|
||||
acpi_new = 18,
|
||||
network = 19,
|
||||
efi_mmap = 20,
|
||||
efi_bs = 21,
|
||||
efi32_ih = 22,
|
||||
efi64_ih = 23,
|
||||
load_base_addr = 24,
|
||||
};
|
||||
|
||||
enum class framebuffer_type : uint8_t {
|
||||
indexed = 0,
|
||||
rgb = 1,
|
||||
ega_text = 2,
|
||||
};
|
||||
|
||||
enum class mem_type : uint32_t {
|
||||
available = 1,
|
||||
reserved = 2,
|
||||
acpi_reclaimable = 3,
|
||||
nvs = 4,
|
||||
badram = 5,
|
||||
};
|
||||
|
||||
struct color {
|
||||
uint8_t red;
|
||||
uint8_t green;
|
||||
uint8_t blue;
|
||||
};
|
||||
|
||||
struct mem_entry {
|
||||
uint64_t addr;
|
||||
uint64_t len;
|
||||
mem_type type;
|
||||
uint32_t zero;
|
||||
};
|
||||
|
||||
struct tag {
|
||||
tag_type type;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
struct tag_string {
|
||||
tag_type type;
|
||||
uint32_t size;
|
||||
char string[0];
|
||||
};
|
||||
|
||||
struct tag_module {
|
||||
tag_type type;
|
||||
uint32_t size;
|
||||
uint32_t mod_start;
|
||||
uint32_t mod_end;
|
||||
char cmdline[0];
|
||||
};
|
||||
|
||||
struct tag_basic_meminfo {
|
||||
tag_type type;
|
||||
uint32_t size;
|
||||
uint32_t mem_lower;
|
||||
uint32_t mem_upper;
|
||||
};
|
||||
|
||||
struct tag_bootdev {
|
||||
tag_type type;
|
||||
uint32_t size;
|
||||
uint32_t biosdev;
|
||||
uint32_t slice;
|
||||
uint32_t part;
|
||||
};
|
||||
|
||||
struct tag_mmap {
|
||||
tag_type type;
|
||||
uint32_t size;
|
||||
uint32_t entry_size;
|
||||
uint32_t entry_version;
|
||||
mem_entry entries[0];
|
||||
};
|
||||
|
||||
struct vbe_info_block {
|
||||
uint8_t external_specification[512];
|
||||
};
|
||||
|
||||
struct vbe_mode_info_block {
|
||||
uint8_t external_specification[256];
|
||||
};
|
||||
|
||||
struct tag_vbe {
|
||||
tag_type type;
|
||||
uint32_t size;
|
||||
uint16_t vbe_mode;
|
||||
uint16_t vbe_interface_seg;
|
||||
uint16_t vbe_interface_off;
|
||||
uint16_t vbe_interface_len;
|
||||
vbe_info_block vbe_control_info;
|
||||
vbe_mode_info_block vbe_mode_info;
|
||||
};
|
||||
|
||||
|
||||
struct tag_framebuffer {
|
||||
tag_type type;
|
||||
uint32_t size;
|
||||
uint64_t framebuffer_addr;
|
||||
uint32_t framebuffer_pitch;
|
||||
uint32_t framebuffer_width;
|
||||
uint32_t framebuffer_height;
|
||||
uint8_t framebuffer_bpp;
|
||||
framebuffer_type framebuffer_type;
|
||||
uint16_t reserved;
|
||||
|
||||
union {
|
||||
struct {
|
||||
uint16_t framebuffer_palette_num_colors;
|
||||
color framebuffer_palette[0];
|
||||
};
|
||||
struct {
|
||||
uint8_t framebuffer_red_field_position;
|
||||
uint8_t framebuffer_red_mask_size;
|
||||
uint8_t framebuffer_green_field_position;
|
||||
uint8_t framebuffer_green_mask_size;
|
||||
uint8_t framebuffer_blue_field_position;
|
||||
uint8_t framebuffer_blue_mask_size;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
struct tag_elf_sections {
|
||||
tag_type type;
|
||||
uint32_t size;
|
||||
uint32_t num;
|
||||
uint32_t entsize;
|
||||
uint32_t shndx;
|
||||
char sections[0];
|
||||
};
|
||||
|
||||
struct tag_apm {
|
||||
tag_type type;
|
||||
uint32_t size;
|
||||
uint16_t version;
|
||||
uint16_t cseg;
|
||||
uint32_t offset;
|
||||
uint16_t cseg_16;
|
||||
uint16_t dseg;
|
||||
uint16_t flags;
|
||||
uint16_t cseg_len;
|
||||
uint16_t cseg_16_len;
|
||||
uint16_t dseg_len;
|
||||
};
|
||||
|
||||
struct tag_efi32 {
|
||||
tag_type type;
|
||||
uint32_t size;
|
||||
uint32_t pointer;
|
||||
};
|
||||
|
||||
struct tag_efi64 {
|
||||
tag_type type;
|
||||
uint32_t size;
|
||||
uint64_t pointer;
|
||||
};
|
||||
|
||||
struct tag_smbios {
|
||||
tag_type type;
|
||||
uint32_t size;
|
||||
uint8_t major;
|
||||
uint8_t minor;
|
||||
uint8_t reserved[6];
|
||||
uint8_t tables[0];
|
||||
};
|
||||
|
||||
struct tag_old_acpi {
|
||||
tag_type type;
|
||||
uint32_t size;
|
||||
uint8_t rsdp[0];
|
||||
};
|
||||
|
||||
struct tag_new_acpi {
|
||||
tag_type type;
|
||||
uint32_t size;
|
||||
uint8_t rsdp[0];
|
||||
};
|
||||
|
||||
struct tag_network {
|
||||
tag_type type;
|
||||
uint32_t size;
|
||||
uint8_t dhcpack[0];
|
||||
};
|
||||
|
||||
struct tag_efi_mmap {
|
||||
tag_type type;
|
||||
uint32_t size;
|
||||
uint32_t descr_size;
|
||||
uint32_t descr_vers;
|
||||
uint8_t efi_mmap[0];
|
||||
};
|
||||
|
||||
struct tag_efi32_ih {
|
||||
tag_type type;
|
||||
uint32_t size;
|
||||
uint32_t pointer;
|
||||
};
|
||||
|
||||
struct tag_efi64_ih {
|
||||
tag_type type;
|
||||
uint32_t size;
|
||||
uint64_t pointer;
|
||||
};
|
||||
|
||||
struct tag_load_base_addr {
|
||||
tag_type type;
|
||||
uint32_t size;
|
||||
uint32_t load_base_addr;
|
||||
};
|
||||
|
||||
struct info {
|
||||
uint32_t total_size;
|
||||
uint32_t reserved;
|
||||
};
|
||||
|
||||
inline info* get_multiboot_info() {
|
||||
auto addr = read_symbol("__multiboot_info");
|
||||
uint32_t phys = *paddr_t{addr}.access<uint32_t>();
|
||||
return paddr_t{phys}.access<info>();
|
||||
}
|
||||
|
||||
template<typename Fn>
|
||||
void visit(const tag* t, Fn&& fn) {
|
||||
#define MB_DISPATCH(tag_enum, TagType) \
|
||||
case tag_type::tag_enum: \
|
||||
if constexpr (requires { fn(static_cast<const TagType*>(nullptr)); }) \
|
||||
fn(reinterpret_cast<const TagType*>(t)); \
|
||||
break;
|
||||
|
||||
switch (t->type) {
|
||||
MB_DISPATCH(cmdline, tag_string)
|
||||
MB_DISPATCH(boot_loader_name, tag_string)
|
||||
MB_DISPATCH(module, tag_module)
|
||||
MB_DISPATCH(basic_meminfo, tag_basic_meminfo)
|
||||
MB_DISPATCH(bootdev, tag_bootdev)
|
||||
MB_DISPATCH(mmap, tag_mmap)
|
||||
MB_DISPATCH(vbe, tag_vbe)
|
||||
MB_DISPATCH(framebuffer, tag_framebuffer)
|
||||
MB_DISPATCH(elf_sections, tag_elf_sections)
|
||||
MB_DISPATCH(apm, tag_apm)
|
||||
MB_DISPATCH(efi32, tag_efi32)
|
||||
MB_DISPATCH(efi64, tag_efi64)
|
||||
MB_DISPATCH(smbios, tag_smbios)
|
||||
MB_DISPATCH(acpi_old, tag_old_acpi)
|
||||
MB_DISPATCH(acpi_new, tag_new_acpi)
|
||||
MB_DISPATCH(network, tag_network)
|
||||
MB_DISPATCH(efi_mmap, tag_efi_mmap)
|
||||
MB_DISPATCH(efi32_ih, tag_efi32_ih)
|
||||
MB_DISPATCH(efi64_ih, tag_efi64_ih)
|
||||
MB_DISPATCH(load_base_addr, tag_load_base_addr)
|
||||
default: break;
|
||||
}
|
||||
|
||||
#undef MB_DISPATCH
|
||||
}
|
||||
|
||||
template<typename Fn>
|
||||
void visit_all(const info* mb, Fn&& fn) {
|
||||
auto ptr = reinterpret_cast<const uint8_t*>(mb) + sizeof(info);
|
||||
const auto end = reinterpret_cast<const uint8_t*>(mb) + mb->total_size;
|
||||
while (ptr < end) {
|
||||
auto t = reinterpret_cast<const tag*>(ptr);
|
||||
if (t->type == tag_type::end) break;
|
||||
visit(t, fn);
|
||||
ptr += (t->size + alignment - 1) & ~(alignment - 1);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Fn>
|
||||
void visit_all(Fn&& fn) {
|
||||
visit_all(get_multiboot_info(), fn);
|
||||
}
|
||||
} // namespace multiboot
|
||||
38
kernel/include/init/print.h
Normal file
38
kernel/include/init/print.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
enum class Color : uint8_t {
|
||||
Black = 0,
|
||||
Blue = 1,
|
||||
Green = 2,
|
||||
Cyan = 3,
|
||||
Red = 4,
|
||||
Magenta = 5,
|
||||
Brown = 6,
|
||||
LightGray = 7,
|
||||
DarkGray = 8,
|
||||
LightBlue = 9,
|
||||
LightGreen = 10,
|
||||
LightCyan = 11,
|
||||
LightRed = 12,
|
||||
LightMagenta = 13,
|
||||
Yellow = 14,
|
||||
White = 15,
|
||||
};
|
||||
|
||||
struct TextAttr {
|
||||
Color fg;
|
||||
Color bg;
|
||||
|
||||
constexpr TextAttr(Color fg = Color::White, Color bg = Color::Black) : fg(fg), bg(bg) {}
|
||||
|
||||
// Returns the attribute in the high byte, ready to OR with a character value.
|
||||
constexpr uint16_t word() const {
|
||||
return (uint16_t)(((uint8_t)bg << 4) | (uint8_t)fg) << 8;
|
||||
}
|
||||
};
|
||||
|
||||
void clear();
|
||||
void print(const char* str, TextAttr attr = {});
|
||||
void print_dec(uint64_t value, TextAttr attr = {});
|
||||
void print_hex(uint64_t value, TextAttr attr = {});
|
||||
39
kernel/include/memory/pointer.h
Normal file
39
kernel/include/memory/pointer.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#pragma once
|
||||
|
||||
#include "util/number.h"
|
||||
|
||||
constexpr uint64_t high_base = 0xFFFF800000000000;
|
||||
|
||||
#define read_symbol(symbol) [](){uint64_t res; asm volatile("movabsq $" symbol ", %0": "=r"(res)); return res;}()
|
||||
|
||||
struct paddr_t {
|
||||
uint64_t address;
|
||||
|
||||
template<typename T>
|
||||
T* access() {
|
||||
return reinterpret_cast<T*>(address+high_base);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
inline void* operator new(size_t, void* p) {
|
||||
return p;
|
||||
}
|
||||
|
||||
inline void* operator new[](size_t, void* p) {
|
||||
return p;
|
||||
}
|
||||
|
||||
inline void* memcpy(void* dest, const void* src, size_t n) {
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
((uint8_t*) dest)[i] = ((uint8_t*) src)[i];
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
inline void* memset(void* dest, int c, size_t n) {
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
((uint8_t*) dest)[i] = (uint8_t) c;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
19
kernel/include/memory/sections.h
Normal file
19
kernel/include/memory/sections.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#pragma once
|
||||
#include "memory/pointer.h"
|
||||
|
||||
struct KernelSection {
|
||||
uint64_t vma_start;
|
||||
uint64_t vma_end;
|
||||
const char* name;
|
||||
|
||||
paddr_t phys_start() const { return paddr_t{vma_start >= high_base ? vma_start - high_base : vma_start}; }
|
||||
paddr_t phys_end() const { return paddr_t{vma_end >= high_base ? vma_end - high_base : vma_end}; }
|
||||
};
|
||||
|
||||
extern KernelSection __reserved_ranges_start__[], __reserved_ranges_end__[];
|
||||
|
||||
template<typename Fn>
|
||||
void for_each_reserved_section(Fn&& fn) {
|
||||
for (auto* s = __reserved_ranges_start__; s < __reserved_ranges_end__; ++s)
|
||||
fn(*s);
|
||||
}
|
||||
9
kernel/include/util/function.h
Normal file
9
kernel/include/util/function.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
template<typename... Ts>
|
||||
struct overloaded : Ts... {
|
||||
using Ts::operator()...;
|
||||
};
|
||||
|
||||
template<typename... Ts>
|
||||
overloaded(Ts...) -> overloaded<Ts...>;
|
||||
6
kernel/include/util/number.h
Normal file
6
kernel/include/util/number.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
using size_t = uint64_t;
|
||||
using ssize_t = int64_t;
|
||||
Loading…
Add table
Add a link
Reference in a new issue