initial state
Currently limine based, cribbing from osdev wiki a bit, and from dreamportdev
This commit is contained in:
commit
0d436e5255
136
Makefile
Normal file
136
Makefile
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
# Nuke built-in rules.
|
||||||
|
.SUFFIXES:
|
||||||
|
|
||||||
|
override OUTPUT := os
|
||||||
|
|
||||||
|
# User controllable toolchain and toolchain prefix.
|
||||||
|
TOOLCHAIN :=
|
||||||
|
TOOLCHAIN_PREFIX :=
|
||||||
|
ifneq ($(TOOLCHAIN),)
|
||||||
|
ifeq ($(TOOLCHAIN_PREFIX),)
|
||||||
|
TOOLCHAIN_PREFIX := $(TOOLCHAIN)-
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# User controllable C compiler command.
|
||||||
|
ifneq ($(TOOLCHAIN_PREFIX),)
|
||||||
|
CC := $(TOOLCHAIN_PREFIX)gcc
|
||||||
|
else
|
||||||
|
CC := cc
|
||||||
|
endif
|
||||||
|
|
||||||
|
# User controllable linker command.
|
||||||
|
LD := $(TOOLCHAIN_PREFIX)ld
|
||||||
|
|
||||||
|
# Defaults overrides for variables if using "llvm" as toolchain.
|
||||||
|
ifeq ($(TOOLCHAIN),llvm)
|
||||||
|
CC := clang
|
||||||
|
LD := ld.lld
|
||||||
|
endif
|
||||||
|
|
||||||
|
# User controllable C flags.
|
||||||
|
CFLAGS := -g -O2 -pipe -Iinclude
|
||||||
|
|
||||||
|
# User controllable C preprocessor flags. We set none by default.
|
||||||
|
CPPFLAGS :=
|
||||||
|
|
||||||
|
# User controllable nasm flags.
|
||||||
|
NASMFLAGS := -g
|
||||||
|
|
||||||
|
# User controllable linker flags. We set none by default.
|
||||||
|
LDFLAGS :=
|
||||||
|
|
||||||
|
# Check if CC is Clang.
|
||||||
|
override CC_IS_CLANG := $(shell ! $(CC) --version 2>/dev/null | grep -q '^Target: '; echo $$?)
|
||||||
|
|
||||||
|
# If the C compiler is Clang, set the target as needed.
|
||||||
|
ifeq ($(CC_IS_CLANG),1)
|
||||||
|
override CC += \
|
||||||
|
-target x86_64-unknown-none-elf
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Internal C flags that should not be changed by the user.
|
||||||
|
override CFLAGS += \
|
||||||
|
-Wall \
|
||||||
|
-Wextra \
|
||||||
|
-std=gnu11 \
|
||||||
|
-ffreestanding \
|
||||||
|
-fno-stack-protector \
|
||||||
|
-fno-stack-check \
|
||||||
|
-fno-lto \
|
||||||
|
-fno-PIC \
|
||||||
|
-ffunction-sections \
|
||||||
|
-fdata-sections \
|
||||||
|
-m64 \
|
||||||
|
-march=x86-64 \
|
||||||
|
-mabi=sysv \
|
||||||
|
-mno-80387 \
|
||||||
|
-mno-mmx \
|
||||||
|
-mno-sse \
|
||||||
|
-mno-sse2 \
|
||||||
|
-mno-red-zone \
|
||||||
|
-mcmodel=kernel
|
||||||
|
|
||||||
|
# Internal C preprocessor flags that should not be changed by the user.
|
||||||
|
override CPPFLAGS := \
|
||||||
|
-I src \
|
||||||
|
$(CPPFLAGS) \
|
||||||
|
-MMD \
|
||||||
|
-MP
|
||||||
|
|
||||||
|
# Internal nasm flags that should not be changed by the user.
|
||||||
|
override NASMFLAGS := \
|
||||||
|
-f elf64 \
|
||||||
|
$(patsubst -g,-g -F dwarf,$(NASMFLAGS)) \
|
||||||
|
-Wall
|
||||||
|
|
||||||
|
# Internal linker flags that should not be changed by the user.
|
||||||
|
override LDFLAGS += \
|
||||||
|
-m elf_x86_64 \
|
||||||
|
-nostdlib \
|
||||||
|
-static \
|
||||||
|
-z max-page-size=0x1000 \
|
||||||
|
--gc-sections \
|
||||||
|
-T linker.ld
|
||||||
|
|
||||||
|
# Use "find" to glob all *.c, *.S, and *.asm files in the tree and obtain the
|
||||||
|
# object and header dependency file names.
|
||||||
|
override SRCFILES := $(shell find -L src -type f 2>/dev/null | LC_ALL=C sort)
|
||||||
|
override CFILES := $(filter %.c,$(SRCFILES))
|
||||||
|
override ASFILES := $(filter %.S,$(SRCFILES))
|
||||||
|
override NASMFILES := $(filter %.asm,$(SRCFILES))
|
||||||
|
override OBJ := $(addprefix obj/,$(CFILES:.c=.c.o) $(ASFILES:.S=.S.o) $(NASMFILES:.asm=.asm.o))
|
||||||
|
override HEADER_DEPS := $(addprefix obj/,$(CFILES:.c=.c.d) $(ASFILES:.S=.S.d))
|
||||||
|
|
||||||
|
# Default target. This must come first, before header dependencies.
|
||||||
|
.PHONY: all
|
||||||
|
all: bin/$(OUTPUT)
|
||||||
|
sh limine.sh
|
||||||
|
|
||||||
|
# Include header dependencies.
|
||||||
|
-include $(HEADER_DEPS)
|
||||||
|
|
||||||
|
# Link rules for the final executable.
|
||||||
|
bin/$(OUTPUT): linker.ld $(OBJ)
|
||||||
|
mkdir -p "$(dir $@)"
|
||||||
|
$(LD) $(LDFLAGS) $(OBJ) -o $@
|
||||||
|
|
||||||
|
# Compilation rules for *.c files.
|
||||||
|
obj/%.c.o: %.c Makefile
|
||||||
|
mkdir -p "$(dir $@)"
|
||||||
|
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
# Compilation rules for *.S files.
|
||||||
|
obj/%.S.o: %.S Makefile
|
||||||
|
mkdir -p "$(dir $@)"
|
||||||
|
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
# Compilation rules for *.asm (nasm) files.
|
||||||
|
obj/%.asm.o: %.asm Makefile
|
||||||
|
mkdir -p "$(dir $@)"
|
||||||
|
nasm $(NASMFLAGS) $< -o $@
|
||||||
|
|
||||||
|
# Remove object files and the final executable.
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -rf bin obj
|
||||||
26
flake.lock
generated
Normal file
26
flake.lock
generated
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1770057536,
|
||||||
|
"narHash": "sha256-Y/Dqu+7StqRVlzQEbow5l2Ws02P9IrHO3eVnpVWbLTE=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "79faf5ae0424fe8cd1d07064a513667e6b6ae65a",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
23
flake.nix
Normal file
23
flake.nix
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
description = "NEURON with custom mechanisms";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs }:
|
||||||
|
let
|
||||||
|
system = "x86_64-linux";
|
||||||
|
pkgs = import nixpkgs { inherit system; };
|
||||||
|
in {
|
||||||
|
devShells.${system}.default = pkgs.mkShell {
|
||||||
|
packages = [
|
||||||
|
pkgs.limine
|
||||||
|
pkgs.clang
|
||||||
|
pkgs.gcc
|
||||||
|
pkgs.gnumake
|
||||||
|
pkgs.nasm
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
576
include/limine.h
Normal file
576
include/limine.h
Normal file
@ -0,0 +1,576 @@
|
|||||||
|
/* SPDX-License-Identifier: 0BSD */
|
||||||
|
|
||||||
|
/* Copyright (C) 2022-2026 Mintsuki and contributors.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||||
|
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIMINE_H
|
||||||
|
#define LIMINE_H 1
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Misc */
|
||||||
|
|
||||||
|
#ifdef LIMINE_NO_POINTERS
|
||||||
|
# define LIMINE_PTR(TYPE) uint64_t
|
||||||
|
#else
|
||||||
|
# define LIMINE_PTR(TYPE) TYPE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LIMINE_REQUESTS_START_MARKER { 0xf6b8f4b39de7d1ae, 0xfab91a6940fcb9cf, \
|
||||||
|
0x785c6ed015d3e316, 0x181e920a7852b9d9 }
|
||||||
|
#define LIMINE_REQUESTS_END_MARKER { 0xadc0e0531bb10d03, 0x9572709f31764c62 }
|
||||||
|
|
||||||
|
#define LIMINE_BASE_REVISION(N) { 0xf9562b2d5c95a6c8, 0x6a7b384944536bdc, (N) }
|
||||||
|
|
||||||
|
#define LIMINE_BASE_REVISION_SUPPORTED(VAR) ((VAR)[2] == 0)
|
||||||
|
|
||||||
|
#define LIMINE_LOADED_BASE_REVISION_VALID(VAR) ((VAR)[1] != 0x6a7b384944536bdc)
|
||||||
|
#define LIMINE_LOADED_BASE_REVISION(VAR) ((VAR)[1])
|
||||||
|
|
||||||
|
#define LIMINE_COMMON_MAGIC 0xc7b1dd30df4c8b88, 0x0a82e883a194f07b
|
||||||
|
|
||||||
|
struct limine_uuid {
|
||||||
|
uint32_t a;
|
||||||
|
uint16_t b;
|
||||||
|
uint16_t c;
|
||||||
|
uint8_t d[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LIMINE_MEDIA_TYPE_GENERIC 0
|
||||||
|
#define LIMINE_MEDIA_TYPE_OPTICAL 1
|
||||||
|
#define LIMINE_MEDIA_TYPE_TFTP 2
|
||||||
|
|
||||||
|
struct limine_file {
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(void *) address;
|
||||||
|
uint64_t size;
|
||||||
|
LIMINE_PTR(char *) path;
|
||||||
|
LIMINE_PTR(char *) string;
|
||||||
|
uint32_t media_type;
|
||||||
|
uint32_t unused;
|
||||||
|
uint32_t tftp_ip;
|
||||||
|
uint32_t tftp_port;
|
||||||
|
uint32_t partition_index;
|
||||||
|
uint32_t mbr_disk_id;
|
||||||
|
struct limine_uuid gpt_disk_uuid;
|
||||||
|
struct limine_uuid gpt_part_uuid;
|
||||||
|
struct limine_uuid part_uuid;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Boot info */
|
||||||
|
|
||||||
|
#define LIMINE_BOOTLOADER_INFO_REQUEST_ID { LIMINE_COMMON_MAGIC, 0xf55038d8e2a1202f, 0x279426fcf5f59740 }
|
||||||
|
|
||||||
|
struct limine_bootloader_info_response {
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(char *) name;
|
||||||
|
LIMINE_PTR(char *) version;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_bootloader_info_request {
|
||||||
|
uint64_t id[4];
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(struct limine_bootloader_info_response *) response;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Executable command line */
|
||||||
|
|
||||||
|
#define LIMINE_EXECUTABLE_CMDLINE_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x4b161536e598651e, 0xb390ad4a2f1f303a }
|
||||||
|
|
||||||
|
struct limine_executable_cmdline_response {
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(char *) cmdline;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_executable_cmdline_request {
|
||||||
|
uint64_t id[4];
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(struct limine_executable_cmdline_response *) response;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Firmware type */
|
||||||
|
|
||||||
|
#define LIMINE_FIRMWARE_TYPE_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x8c2f75d90bef28a8, 0x7045a4688eac00c3 }
|
||||||
|
|
||||||
|
#define LIMINE_FIRMWARE_TYPE_X86BIOS 0
|
||||||
|
#define LIMINE_FIRMWARE_TYPE_EFI32 1
|
||||||
|
#define LIMINE_FIRMWARE_TYPE_EFI64 2
|
||||||
|
#define LIMINE_FIRMWARE_TYPE_SBI 3
|
||||||
|
|
||||||
|
struct limine_firmware_type_response {
|
||||||
|
uint64_t revision;
|
||||||
|
uint64_t firmware_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_firmware_type_request {
|
||||||
|
uint64_t id[4];
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(struct limine_firmware_type_response *) response;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Stack size */
|
||||||
|
|
||||||
|
#define LIMINE_STACK_SIZE_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x224ef0460a8e8926, 0xe1cb0fc25f46ea3d }
|
||||||
|
|
||||||
|
struct limine_stack_size_response {
|
||||||
|
uint64_t revision;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_stack_size_request {
|
||||||
|
uint64_t id[4];
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(struct limine_stack_size_response *) response;
|
||||||
|
uint64_t stack_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* HHDM */
|
||||||
|
|
||||||
|
#define LIMINE_HHDM_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x48dcf1cb8ad2b852, 0x63984e959a98244b }
|
||||||
|
|
||||||
|
struct limine_hhdm_response {
|
||||||
|
uint64_t revision;
|
||||||
|
uint64_t offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_hhdm_request {
|
||||||
|
uint64_t id[4];
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(struct limine_hhdm_response *) response;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Framebuffer */
|
||||||
|
|
||||||
|
#define LIMINE_FRAMEBUFFER_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x9d5827dcd881dd75, 0xa3148604f6fab11b }
|
||||||
|
|
||||||
|
#define LIMINE_FRAMEBUFFER_RGB 1
|
||||||
|
|
||||||
|
struct limine_video_mode {
|
||||||
|
uint64_t pitch;
|
||||||
|
uint64_t width;
|
||||||
|
uint64_t height;
|
||||||
|
uint16_t bpp;
|
||||||
|
uint8_t memory_model;
|
||||||
|
uint8_t red_mask_size;
|
||||||
|
uint8_t red_mask_shift;
|
||||||
|
uint8_t green_mask_size;
|
||||||
|
uint8_t green_mask_shift;
|
||||||
|
uint8_t blue_mask_size;
|
||||||
|
uint8_t blue_mask_shift;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_framebuffer {
|
||||||
|
LIMINE_PTR(void *) address;
|
||||||
|
uint64_t width;
|
||||||
|
uint64_t height;
|
||||||
|
uint64_t pitch;
|
||||||
|
uint16_t bpp;
|
||||||
|
uint8_t memory_model;
|
||||||
|
uint8_t red_mask_size;
|
||||||
|
uint8_t red_mask_shift;
|
||||||
|
uint8_t green_mask_size;
|
||||||
|
uint8_t green_mask_shift;
|
||||||
|
uint8_t blue_mask_size;
|
||||||
|
uint8_t blue_mask_shift;
|
||||||
|
uint8_t unused[7];
|
||||||
|
uint64_t edid_size;
|
||||||
|
LIMINE_PTR(void *) edid;
|
||||||
|
/* Response revision 1 */
|
||||||
|
uint64_t mode_count;
|
||||||
|
LIMINE_PTR(struct limine_video_mode **) modes;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_framebuffer_response {
|
||||||
|
uint64_t revision;
|
||||||
|
uint64_t framebuffer_count;
|
||||||
|
LIMINE_PTR(struct limine_framebuffer **) framebuffers;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_framebuffer_request {
|
||||||
|
uint64_t id[4];
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(struct limine_framebuffer_response *) response;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Paging mode */
|
||||||
|
|
||||||
|
#define LIMINE_PAGING_MODE_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x95c1a0edab0944cb, 0xa4e5cb3842f7488a }
|
||||||
|
|
||||||
|
#define LIMINE_PAGING_MODE_X86_64_4LVL 0
|
||||||
|
#define LIMINE_PAGING_MODE_X86_64_5LVL 1
|
||||||
|
#define LIMINE_PAGING_MODE_X86_64_MIN LIMINE_PAGING_MODE_X86_64_4LVL
|
||||||
|
#define LIMINE_PAGING_MODE_X86_64_DEFAULT LIMINE_PAGING_MODE_X86_64_4LVL
|
||||||
|
|
||||||
|
#define LIMINE_PAGING_MODE_AARCH64_4LVL 0
|
||||||
|
#define LIMINE_PAGING_MODE_AARCH64_5LVL 1
|
||||||
|
#define LIMINE_PAGING_MODE_AARCH64_MIN LIMINE_PAGING_MODE_AARCH64_4LVL
|
||||||
|
#define LIMINE_PAGING_MODE_AARCH64_DEFAULT LIMINE_PAGING_MODE_AARCH64_4LVL
|
||||||
|
|
||||||
|
#define LIMINE_PAGING_MODE_RISCV_SV39 0
|
||||||
|
#define LIMINE_PAGING_MODE_RISCV_SV48 1
|
||||||
|
#define LIMINE_PAGING_MODE_RISCV_SV57 2
|
||||||
|
#define LIMINE_PAGING_MODE_RISCV_MIN LIMINE_PAGING_MODE_RISCV_SV39
|
||||||
|
#define LIMINE_PAGING_MODE_RISCV_DEFAULT LIMINE_PAGING_MODE_RISCV_SV48
|
||||||
|
|
||||||
|
#define LIMINE_PAGING_MODE_LOONGARCH_4LVL 0
|
||||||
|
#define LIMINE_PAGING_MODE_LOONGARCH_MIN LIMINE_PAGING_MODE_LOONGARCH_4LVL
|
||||||
|
#define LIMINE_PAGING_MODE_LOONGARCH_DEFAULT LIMINE_PAGING_MODE_LOONGARCH_4LVL
|
||||||
|
|
||||||
|
struct limine_paging_mode_response {
|
||||||
|
uint64_t revision;
|
||||||
|
uint64_t mode;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_paging_mode_request {
|
||||||
|
uint64_t id[4];
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(struct limine_paging_mode_response *) response;
|
||||||
|
uint64_t mode;
|
||||||
|
uint64_t max_mode;
|
||||||
|
uint64_t min_mode;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* MP */
|
||||||
|
|
||||||
|
#define LIMINE_MP_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x95a67b819a1b857e, 0xa0b61b723b6a73e0 }
|
||||||
|
|
||||||
|
struct limine_mp_info;
|
||||||
|
|
||||||
|
typedef void (*limine_goto_address)(struct limine_mp_info *);
|
||||||
|
|
||||||
|
#if defined (__x86_64__) || defined (__i386__)
|
||||||
|
|
||||||
|
#define LIMINE_MP_RESPONSE_X86_64_X2APIC (1 << 0)
|
||||||
|
|
||||||
|
struct limine_mp_info {
|
||||||
|
uint32_t processor_id;
|
||||||
|
uint32_t lapic_id;
|
||||||
|
uint64_t reserved;
|
||||||
|
LIMINE_PTR(limine_goto_address) goto_address;
|
||||||
|
uint64_t extra_argument;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_mp_response {
|
||||||
|
uint64_t revision;
|
||||||
|
uint32_t flags;
|
||||||
|
uint32_t bsp_lapic_id;
|
||||||
|
uint64_t cpu_count;
|
||||||
|
LIMINE_PTR(struct limine_mp_info **) cpus;
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif defined (__aarch64__)
|
||||||
|
|
||||||
|
struct limine_mp_info {
|
||||||
|
uint32_t processor_id;
|
||||||
|
uint32_t reserved1;
|
||||||
|
uint64_t mpidr;
|
||||||
|
uint64_t reserved;
|
||||||
|
LIMINE_PTR(limine_goto_address) goto_address;
|
||||||
|
uint64_t extra_argument;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_mp_response {
|
||||||
|
uint64_t revision;
|
||||||
|
uint64_t flags;
|
||||||
|
uint64_t bsp_mpidr;
|
||||||
|
uint64_t cpu_count;
|
||||||
|
LIMINE_PTR(struct limine_mp_info **) cpus;
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif defined (__riscv) && (__riscv_xlen == 64)
|
||||||
|
|
||||||
|
struct limine_mp_info {
|
||||||
|
uint64_t processor_id;
|
||||||
|
uint64_t hartid;
|
||||||
|
uint64_t reserved;
|
||||||
|
LIMINE_PTR(limine_goto_address) goto_address;
|
||||||
|
uint64_t extra_argument;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_mp_response {
|
||||||
|
uint64_t revision;
|
||||||
|
uint64_t flags;
|
||||||
|
uint64_t bsp_hartid;
|
||||||
|
uint64_t cpu_count;
|
||||||
|
LIMINE_PTR(struct limine_mp_info **) cpus;
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif defined (__loongarch__) && (__loongarch_grlen == 64)
|
||||||
|
|
||||||
|
struct limine_mp_info {
|
||||||
|
uint64_t reserved;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_mp_response {
|
||||||
|
uint64_t cpu_count;
|
||||||
|
LIMINE_PTR(struct limine_mp_info **) cpus;
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error Unknown architecture
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LIMINE_MP_REQUEST_X86_64_X2APIC (1 << 0)
|
||||||
|
|
||||||
|
struct limine_mp_request {
|
||||||
|
uint64_t id[4];
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(struct limine_mp_response *) response;
|
||||||
|
uint64_t flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Memory map */
|
||||||
|
|
||||||
|
#define LIMINE_MEMMAP_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x67cf3d9d378a806f, 0xe304acdfc50c3c62 }
|
||||||
|
|
||||||
|
#define LIMINE_MEMMAP_USABLE 0
|
||||||
|
#define LIMINE_MEMMAP_RESERVED 1
|
||||||
|
#define LIMINE_MEMMAP_ACPI_RECLAIMABLE 2
|
||||||
|
#define LIMINE_MEMMAP_ACPI_NVS 3
|
||||||
|
#define LIMINE_MEMMAP_BAD_MEMORY 4
|
||||||
|
#define LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE 5
|
||||||
|
#define LIMINE_MEMMAP_EXECUTABLE_AND_MODULES 6
|
||||||
|
#define LIMINE_MEMMAP_FRAMEBUFFER 7
|
||||||
|
#define LIMINE_MEMMAP_ACPI_TABLES 8
|
||||||
|
|
||||||
|
struct limine_memmap_entry {
|
||||||
|
uint64_t base;
|
||||||
|
uint64_t length;
|
||||||
|
uint64_t type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_memmap_response {
|
||||||
|
uint64_t revision;
|
||||||
|
uint64_t entry_count;
|
||||||
|
LIMINE_PTR(struct limine_memmap_entry **) entries;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_memmap_request {
|
||||||
|
uint64_t id[4];
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(struct limine_memmap_response *) response;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Entry point */
|
||||||
|
|
||||||
|
#define LIMINE_ENTRY_POINT_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x13d86c035a1cd3e1, 0x2b0caa89d8f3026a }
|
||||||
|
|
||||||
|
typedef void (*limine_entry_point)(void);
|
||||||
|
|
||||||
|
struct limine_entry_point_response {
|
||||||
|
uint64_t revision;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_entry_point_request {
|
||||||
|
uint64_t id[4];
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(struct limine_entry_point_response *) response;
|
||||||
|
LIMINE_PTR(limine_entry_point) entry;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Executable File */
|
||||||
|
|
||||||
|
#define LIMINE_EXECUTABLE_FILE_REQUEST_ID { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 }
|
||||||
|
|
||||||
|
struct limine_executable_file_response {
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(struct limine_file *) executable_file;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_executable_file_request {
|
||||||
|
uint64_t id[4];
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(struct limine_executable_file_response *) response;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Module */
|
||||||
|
|
||||||
|
#define LIMINE_MODULE_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x3e7e279702be32af, 0xca1c4f3bd1280cee }
|
||||||
|
|
||||||
|
#define LIMINE_INTERNAL_MODULE_REQUIRED (1 << 0)
|
||||||
|
#define LIMINE_INTERNAL_MODULE_COMPRESSED (1 << 1)
|
||||||
|
|
||||||
|
struct limine_internal_module {
|
||||||
|
LIMINE_PTR(const char *) path;
|
||||||
|
LIMINE_PTR(const char *) string;
|
||||||
|
uint64_t flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_module_response {
|
||||||
|
uint64_t revision;
|
||||||
|
uint64_t module_count;
|
||||||
|
LIMINE_PTR(struct limine_file **) modules;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_module_request {
|
||||||
|
uint64_t id[4];
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(struct limine_module_response *) response;
|
||||||
|
|
||||||
|
/* Request revision 1 */
|
||||||
|
uint64_t internal_module_count;
|
||||||
|
LIMINE_PTR(struct limine_internal_module **) internal_modules;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* RSDP */
|
||||||
|
|
||||||
|
#define LIMINE_RSDP_REQUEST_ID { LIMINE_COMMON_MAGIC, 0xc5e77b6b397e7b43, 0x27637845accdcf3c }
|
||||||
|
|
||||||
|
struct limine_rsdp_response {
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(void *) address;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_rsdp_request {
|
||||||
|
uint64_t id[4];
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(struct limine_rsdp_response *) response;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* SMBIOS */
|
||||||
|
|
||||||
|
#define LIMINE_SMBIOS_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x9e9046f11e095391, 0xaa4a520fefbde5ee }
|
||||||
|
|
||||||
|
struct limine_smbios_response {
|
||||||
|
uint64_t revision;
|
||||||
|
uint64_t entry_32;
|
||||||
|
uint64_t entry_64;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_smbios_request {
|
||||||
|
uint64_t id[4];
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(struct limine_smbios_response *) response;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* EFI system table */
|
||||||
|
|
||||||
|
#define LIMINE_EFI_SYSTEM_TABLE_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x5ceba5163eaaf6d6, 0x0a6981610cf65fcc }
|
||||||
|
|
||||||
|
struct limine_efi_system_table_response {
|
||||||
|
uint64_t revision;
|
||||||
|
uint64_t address;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_efi_system_table_request {
|
||||||
|
uint64_t id[4];
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(struct limine_efi_system_table_response *) response;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* EFI memory map */
|
||||||
|
|
||||||
|
#define LIMINE_EFI_MEMMAP_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x7df62a431d6872d5, 0xa4fcdfb3e57306c8 }
|
||||||
|
|
||||||
|
struct limine_efi_memmap_response {
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(void *) memmap;
|
||||||
|
uint64_t memmap_size;
|
||||||
|
uint64_t desc_size;
|
||||||
|
uint64_t desc_version;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_efi_memmap_request {
|
||||||
|
uint64_t id[4];
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(struct limine_efi_memmap_response *) response;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Date at boot */
|
||||||
|
|
||||||
|
#define LIMINE_DATE_AT_BOOT_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x502746e184c088aa, 0xfbc5ec83e6327893 }
|
||||||
|
|
||||||
|
struct limine_date_at_boot_response {
|
||||||
|
uint64_t revision;
|
||||||
|
int64_t timestamp;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_date_at_boot_request {
|
||||||
|
uint64_t id[4];
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(struct limine_date_at_boot_response *) response;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Executable address */
|
||||||
|
|
||||||
|
#define LIMINE_EXECUTABLE_ADDRESS_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487 }
|
||||||
|
|
||||||
|
struct limine_executable_address_response {
|
||||||
|
uint64_t revision;
|
||||||
|
uint64_t physical_base;
|
||||||
|
uint64_t virtual_base;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_executable_address_request {
|
||||||
|
uint64_t id[4];
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(struct limine_executable_address_response *) response;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Device Tree Blob */
|
||||||
|
|
||||||
|
#define LIMINE_DTB_REQUEST_ID { LIMINE_COMMON_MAGIC, 0xb40ddb48fb54bac7, 0x545081493f81ffb7 }
|
||||||
|
|
||||||
|
struct limine_dtb_response {
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(void *) dtb_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_dtb_request {
|
||||||
|
uint64_t id[4];
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(struct limine_dtb_response *) response;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* RISC-V Boot Hart ID */
|
||||||
|
|
||||||
|
#define LIMINE_RISCV_BSP_HARTID_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x1369359f025525f9, 0x2ff2a56178391bb6 }
|
||||||
|
|
||||||
|
struct limine_riscv_bsp_hartid_response {
|
||||||
|
uint64_t revision;
|
||||||
|
uint64_t bsp_hartid;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_riscv_bsp_hartid_request {
|
||||||
|
uint64_t id[4];
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(struct limine_riscv_bsp_hartid_response *) response;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Bootloader Performance */
|
||||||
|
|
||||||
|
#define LIMINE_BOOTLOADER_PERFORMANCE_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x6b50ad9bf36d13ad, 0xdc4c7e88fc759e17 }
|
||||||
|
|
||||||
|
struct limine_bootloader_performance_response {
|
||||||
|
uint64_t revision;
|
||||||
|
uint64_t reset_usec;
|
||||||
|
uint64_t init_usec;
|
||||||
|
uint64_t exec_usec;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limine_bootloader_performance_request {
|
||||||
|
uint64_t id[4];
|
||||||
|
uint64_t revision;
|
||||||
|
LIMINE_PTR(struct limine_bootloader_performance_response *) response;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
1
limine
Submodule
1
limine
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 7a6892a36f1fb6dbdd6e6f6d00b8062d5bcb813b
|
||||||
5
limine.conf
Normal file
5
limine.conf
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
timeout: 5
|
||||||
|
|
||||||
|
/LispOS
|
||||||
|
protocol: limine
|
||||||
|
path: boot():/boot/os
|
||||||
28
limine.sh
Normal file
28
limine.sh
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# Create an empty zeroed-out 64MiB image file.
|
||||||
|
dd if=/dev/zero bs=1M count=0 seek=64 of=image.hdd
|
||||||
|
|
||||||
|
# Create a partition table.
|
||||||
|
, sgdisk image.hdd -n 1:2048 -t 1:ef00 -m 1
|
||||||
|
|
||||||
|
|
||||||
|
#rm -rf limine
|
||||||
|
# Download the latest Limine binary release for the 10.x branch.
|
||||||
|
#git clone https://codeberg.org/Limine/Limine.git limine --branch=v10.x-binary --depth=1
|
||||||
|
|
||||||
|
# Build "limine" utility.
|
||||||
|
#make -C limine
|
||||||
|
|
||||||
|
# Install the Limine BIOS stages onto the image.
|
||||||
|
./limine/limine bios-install image.hdd
|
||||||
|
|
||||||
|
# Format the image as fat32.
|
||||||
|
, mformat -i image.hdd@@1M
|
||||||
|
|
||||||
|
# Make relevant subdirectories.
|
||||||
|
, mmd -i image.hdd@@1M ::/EFI ::/EFI/BOOT ::/boot ::/boot/limine
|
||||||
|
|
||||||
|
# Copy over the relevant files.
|
||||||
|
, mcopy -i image.hdd@@1M bin/os ::/boot
|
||||||
|
, mcopy -i image.hdd@@1M limine.conf limine/limine-bios.sys ::/boot/limine
|
||||||
|
, mcopy -i image.hdd@@1M limine/BOOTX64.EFI ::/EFI/BOOT
|
||||||
|
, mcopy -i image.hdd@@1M limine/BOOTIA32.EFI ::/EFI/BOOT
|
||||||
57
linker.ld
Normal file
57
linker.ld
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
OUTPUT_FORMAT(elf64-x86-64)
|
||||||
|
|
||||||
|
ENTRY(kmain)
|
||||||
|
|
||||||
|
/* program headers to get MMU perms */
|
||||||
|
PHDRS {
|
||||||
|
limine_requests PT_LOAD;
|
||||||
|
text PT_LOAD;
|
||||||
|
rodata PT_LOAD;
|
||||||
|
data PT_LOAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
/* we want topmost 2GiB of addr space */
|
||||||
|
. = 0xffffffff80000000;
|
||||||
|
|
||||||
|
.limine_requests : {
|
||||||
|
KEEP(*(.limine_requests_start))
|
||||||
|
KEEP(*(.limine_requests))
|
||||||
|
KEEP(*(.limine_requests_end))
|
||||||
|
} :limine_requests
|
||||||
|
|
||||||
|
. = ALIGN(CONSTANT(MAXPAGESIZE));
|
||||||
|
|
||||||
|
.text : {
|
||||||
|
*(.text .text.*)
|
||||||
|
} :text
|
||||||
|
|
||||||
|
. = ALIGN(CONSTANT(MAXPAGESIZE));
|
||||||
|
|
||||||
|
.rodata : {
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
} :rodata
|
||||||
|
|
||||||
|
|
||||||
|
.note.gnu.build-id : {
|
||||||
|
*(.note.gnu.build-id)
|
||||||
|
} :rodata
|
||||||
|
|
||||||
|
. = ALIGN(CONSTANT(MAXPAGESIZE));
|
||||||
|
|
||||||
|
.data : {
|
||||||
|
*(.data .data.*)
|
||||||
|
} :data
|
||||||
|
|
||||||
|
/* .bss need sto be the last thing mapped */
|
||||||
|
.bss : {
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(COMMON)
|
||||||
|
} :data
|
||||||
|
|
||||||
|
/DISCARD/ : {
|
||||||
|
*(.eh_frame*)
|
||||||
|
*(.note .note.*)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
1
obj/src/int.c.d
Normal file
1
obj/src/int.c.d
Normal file
@ -0,0 +1 @@
|
|||||||
|
obj/src/int.c.o: src/int.c
|
||||||
BIN
obj/src/int.c.o
Normal file
BIN
obj/src/int.c.o
Normal file
Binary file not shown.
2
obj/src/main.c.d
Normal file
2
obj/src/main.c.d
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
obj/src/main.c.o: src/main.c src/../include/limine.h
|
||||||
|
src/../include/limine.h:
|
||||||
BIN
obj/src/main.c.o
Normal file
BIN
obj/src/main.c.o
Normal file
Binary file not shown.
271
src/int.c
Normal file
271
src/int.c
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define pstruct struct __attribute__((packed))
|
||||||
|
|
||||||
|
pstruct int_desc {
|
||||||
|
uint16_t addr_low;
|
||||||
|
uint16_t selector;
|
||||||
|
uint8_t ist;
|
||||||
|
uint8_t flags;
|
||||||
|
uint16_t addr_mid;
|
||||||
|
uint32_t addr_high;
|
||||||
|
uint32_t resv;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum INT_DESC_FLAGS {
|
||||||
|
ID_GATE_INT = 0b00001110,
|
||||||
|
ID_GATE_TRAP = 0b00001111,
|
||||||
|
ID_DPL = 0b00100000,
|
||||||
|
ID_PRESENT = 0b10000000,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define CODE64_SELECTOR 0x28
|
||||||
|
|
||||||
|
struct int_desc idt[256];
|
||||||
|
|
||||||
|
void set_idt(uint8_t vect, void* handler, uint8_t dpl) {
|
||||||
|
struct int_desc* ent = &idt[vect];
|
||||||
|
uint64_t addr = (uint64_t) handler;
|
||||||
|
ent->addr_low = addr & 0xFFFF;
|
||||||
|
ent->addr_mid = (addr >> 16) & 0xFFFF;
|
||||||
|
ent->addr_mid = addr >> 32;
|
||||||
|
|
||||||
|
ent->selector = CODE64_SELECTOR;
|
||||||
|
ent->flags = ID_GATE_INT | dpl*ID_DPL | ID_PRESENT;
|
||||||
|
ent->ist = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pstruct idtr {
|
||||||
|
uint16_t limit;
|
||||||
|
uint64_t base;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define IDTR_LIMIT (sizeof(struct int_desc)*256 - 1)
|
||||||
|
|
||||||
|
void load_idt(void* addr) {
|
||||||
|
struct idtr ir = (struct idtr) {
|
||||||
|
.limit = IDTR_LIMIT,
|
||||||
|
.base = (uint64_t) addr,
|
||||||
|
};
|
||||||
|
|
||||||
|
asm volatile("lidt %0" :: "m"(ir));
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void draw(uint8_t vect);
|
||||||
|
|
||||||
|
struct cpu_ctx {
|
||||||
|
uint64_t r15, r14, r13, r12, r11, r10, r9, r8, rdi, rsi, rdx, rcx, rbx, rax;
|
||||||
|
|
||||||
|
uint64_t vect;
|
||||||
|
uint64_t err;
|
||||||
|
|
||||||
|
uint64_t iret_rip;
|
||||||
|
uint64_t iret_cs;
|
||||||
|
uint64_t iret_flags;
|
||||||
|
uint64_t iret_rsp;
|
||||||
|
uint64_t iret_ss;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cpu_ctx* interrupt_dispatch(struct cpu_ctx* ctx) {
|
||||||
|
draw(ctx->vect);
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void int_stub(void) {
|
||||||
|
__asm__ volatile (
|
||||||
|
"push %%rax\n"
|
||||||
|
"push %%rbx\n"
|
||||||
|
"push %%rcx\n"
|
||||||
|
"push %%rdx\n"
|
||||||
|
"push %%rsi\n"
|
||||||
|
"push %%rdi\n"
|
||||||
|
"push %%r8\n"
|
||||||
|
"push %%r9\n"
|
||||||
|
"push %%r10\n"
|
||||||
|
"push %%r11\n"
|
||||||
|
"push %%r12\n"
|
||||||
|
"push %%r13\n"
|
||||||
|
"push %%r14\n"
|
||||||
|
"push %%r15\n"
|
||||||
|
"mov %%rsp, %%rdi\n"
|
||||||
|
"call interrupt_dispatch\n"
|
||||||
|
"mov %%rax, %%rsp\n"
|
||||||
|
"pop %%r15\n"
|
||||||
|
"pop %%r14\n"
|
||||||
|
"pop %%r13\n"
|
||||||
|
"pop %%r12\n"
|
||||||
|
"pop %%r11\n"
|
||||||
|
"pop %%r10\n"
|
||||||
|
"pop %%r9\n"
|
||||||
|
"pop %%r8\n"
|
||||||
|
"pop %%rdi\n"
|
||||||
|
"pop %%rsi\n"
|
||||||
|
"pop %%rdx\n"
|
||||||
|
"pop %%rcx\n"
|
||||||
|
"pop %%rbx\n"
|
||||||
|
"pop %%rax\n"
|
||||||
|
"add $16, %%rsp\n"
|
||||||
|
"iret\n"
|
||||||
|
:
|
||||||
|
:
|
||||||
|
: "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Macro to generate interrupt stubs without error codes (push dummy 0)
|
||||||
|
#define ISR_NO_ERR(num) \
|
||||||
|
__attribute__((naked)) void isr##num(void) { \
|
||||||
|
asm volatile( \
|
||||||
|
"push $0\n" \
|
||||||
|
"push %0\n" \
|
||||||
|
"jmp int_stub\n" \
|
||||||
|
: : "i"(num)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
// Macro to generate interrupt stubs with error codes
|
||||||
|
#define ISR_ERR(num) \
|
||||||
|
__attribute__((naked)) void isr##num(void) { \
|
||||||
|
asm volatile( \
|
||||||
|
"push %0\n" \
|
||||||
|
"jmp int_stub\n" \
|
||||||
|
: : "i"(num)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
// CPU exceptions (0-31)
|
||||||
|
ISR_NO_ERR(0) // Divide by zero
|
||||||
|
ISR_NO_ERR(1) // Debug
|
||||||
|
ISR_NO_ERR(2) // NMI
|
||||||
|
ISR_NO_ERR(3) // Breakpoint
|
||||||
|
ISR_NO_ERR(4) // Overflow
|
||||||
|
ISR_NO_ERR(5) // Bound range exceeded
|
||||||
|
ISR_NO_ERR(6) // Invalid opcode
|
||||||
|
ISR_NO_ERR(7) // Device not available
|
||||||
|
ISR_ERR(8) // Double fault (pushes error code)
|
||||||
|
ISR_NO_ERR(9) // Coprocessor segment overrun
|
||||||
|
ISR_ERR(10) // Invalid TSS (pushes error code)
|
||||||
|
ISR_ERR(11) // Segment not present (pushes error code)
|
||||||
|
ISR_ERR(12) // Stack-segment fault (pushes error code)
|
||||||
|
ISR_ERR(13) // General protection fault (pushes error code)
|
||||||
|
ISR_ERR(14) // Page fault (pushes error code)
|
||||||
|
ISR_NO_ERR(15) // Reserved
|
||||||
|
ISR_NO_ERR(16) // x87 FPU error
|
||||||
|
ISR_ERR(17) // Alignment check (pushes error code)
|
||||||
|
ISR_NO_ERR(18) // Machine check
|
||||||
|
ISR_NO_ERR(19) // SIMD floating-point exception
|
||||||
|
ISR_NO_ERR(20) // Virtualization exception
|
||||||
|
ISR_ERR(21) // Control protection exception (pushes error code)
|
||||||
|
ISR_NO_ERR(22) // Reserved
|
||||||
|
ISR_NO_ERR(23) // Reserved
|
||||||
|
ISR_NO_ERR(24) // Reserved
|
||||||
|
ISR_NO_ERR(25) // Reserved
|
||||||
|
ISR_NO_ERR(26) // Reserved
|
||||||
|
ISR_NO_ERR(27) // Reserved
|
||||||
|
ISR_NO_ERR(28) // Reserved
|
||||||
|
ISR_NO_ERR(29) // Reserved
|
||||||
|
ISR_ERR(30) // Security exception (pushes error code)
|
||||||
|
ISR_NO_ERR(31) // Reserved
|
||||||
|
|
||||||
|
// IRQs and user-defined interrupts (32-255)
|
||||||
|
ISR_NO_ERR(32) ISR_NO_ERR(33) ISR_NO_ERR(34) ISR_NO_ERR(35)
|
||||||
|
ISR_NO_ERR(36) ISR_NO_ERR(37) ISR_NO_ERR(38) ISR_NO_ERR(39)
|
||||||
|
ISR_NO_ERR(40) ISR_NO_ERR(41) ISR_NO_ERR(42) ISR_NO_ERR(43)
|
||||||
|
ISR_NO_ERR(44) ISR_NO_ERR(45) ISR_NO_ERR(46) ISR_NO_ERR(47)
|
||||||
|
ISR_NO_ERR(48) ISR_NO_ERR(49) ISR_NO_ERR(50) ISR_NO_ERR(51)
|
||||||
|
ISR_NO_ERR(52) ISR_NO_ERR(53) ISR_NO_ERR(54) ISR_NO_ERR(55)
|
||||||
|
ISR_NO_ERR(56) ISR_NO_ERR(57) ISR_NO_ERR(58) ISR_NO_ERR(59)
|
||||||
|
ISR_NO_ERR(60) ISR_NO_ERR(61) ISR_NO_ERR(62) ISR_NO_ERR(63)
|
||||||
|
ISR_NO_ERR(64) ISR_NO_ERR(65) ISR_NO_ERR(66) ISR_NO_ERR(67)
|
||||||
|
ISR_NO_ERR(68) ISR_NO_ERR(69) ISR_NO_ERR(70) ISR_NO_ERR(71)
|
||||||
|
ISR_NO_ERR(72) ISR_NO_ERR(73) ISR_NO_ERR(74) ISR_NO_ERR(75)
|
||||||
|
ISR_NO_ERR(76) ISR_NO_ERR(77) ISR_NO_ERR(78) ISR_NO_ERR(79)
|
||||||
|
ISR_NO_ERR(80) ISR_NO_ERR(81) ISR_NO_ERR(82) ISR_NO_ERR(83)
|
||||||
|
ISR_NO_ERR(84) ISR_NO_ERR(85) ISR_NO_ERR(86) ISR_NO_ERR(87)
|
||||||
|
ISR_NO_ERR(88) ISR_NO_ERR(89) ISR_NO_ERR(90) ISR_NO_ERR(91)
|
||||||
|
ISR_NO_ERR(92) ISR_NO_ERR(93) ISR_NO_ERR(94) ISR_NO_ERR(95)
|
||||||
|
ISR_NO_ERR(96) ISR_NO_ERR(97) ISR_NO_ERR(98) ISR_NO_ERR(99)
|
||||||
|
ISR_NO_ERR(100) ISR_NO_ERR(101) ISR_NO_ERR(102) ISR_NO_ERR(103)
|
||||||
|
ISR_NO_ERR(104) ISR_NO_ERR(105) ISR_NO_ERR(106) ISR_NO_ERR(107)
|
||||||
|
ISR_NO_ERR(108) ISR_NO_ERR(109) ISR_NO_ERR(110) ISR_NO_ERR(111)
|
||||||
|
ISR_NO_ERR(112) ISR_NO_ERR(113) ISR_NO_ERR(114) ISR_NO_ERR(115)
|
||||||
|
ISR_NO_ERR(116) ISR_NO_ERR(117) ISR_NO_ERR(118) ISR_NO_ERR(119)
|
||||||
|
ISR_NO_ERR(120) ISR_NO_ERR(121) ISR_NO_ERR(122) ISR_NO_ERR(123)
|
||||||
|
ISR_NO_ERR(124) ISR_NO_ERR(125) ISR_NO_ERR(126) ISR_NO_ERR(127)
|
||||||
|
ISR_NO_ERR(128) ISR_NO_ERR(129) ISR_NO_ERR(130) ISR_NO_ERR(131)
|
||||||
|
ISR_NO_ERR(132) ISR_NO_ERR(133) ISR_NO_ERR(134) ISR_NO_ERR(135)
|
||||||
|
ISR_NO_ERR(136) ISR_NO_ERR(137) ISR_NO_ERR(138) ISR_NO_ERR(139)
|
||||||
|
ISR_NO_ERR(140) ISR_NO_ERR(141) ISR_NO_ERR(142) ISR_NO_ERR(143)
|
||||||
|
ISR_NO_ERR(144) ISR_NO_ERR(145) ISR_NO_ERR(146) ISR_NO_ERR(147)
|
||||||
|
ISR_NO_ERR(148) ISR_NO_ERR(149) ISR_NO_ERR(150) ISR_NO_ERR(151)
|
||||||
|
ISR_NO_ERR(152) ISR_NO_ERR(153) ISR_NO_ERR(154) ISR_NO_ERR(155)
|
||||||
|
ISR_NO_ERR(156) ISR_NO_ERR(157) ISR_NO_ERR(158) ISR_NO_ERR(159)
|
||||||
|
ISR_NO_ERR(160) ISR_NO_ERR(161) ISR_NO_ERR(162) ISR_NO_ERR(163)
|
||||||
|
ISR_NO_ERR(164) ISR_NO_ERR(165) ISR_NO_ERR(166) ISR_NO_ERR(167)
|
||||||
|
ISR_NO_ERR(168) ISR_NO_ERR(169) ISR_NO_ERR(170) ISR_NO_ERR(171)
|
||||||
|
ISR_NO_ERR(172) ISR_NO_ERR(173) ISR_NO_ERR(174) ISR_NO_ERR(175)
|
||||||
|
ISR_NO_ERR(176) ISR_NO_ERR(177) ISR_NO_ERR(178) ISR_NO_ERR(179)
|
||||||
|
ISR_NO_ERR(180) ISR_NO_ERR(181) ISR_NO_ERR(182) ISR_NO_ERR(183)
|
||||||
|
ISR_NO_ERR(184) ISR_NO_ERR(185) ISR_NO_ERR(186) ISR_NO_ERR(187)
|
||||||
|
ISR_NO_ERR(188) ISR_NO_ERR(189) ISR_NO_ERR(190) ISR_NO_ERR(191)
|
||||||
|
ISR_NO_ERR(192) ISR_NO_ERR(193) ISR_NO_ERR(194) ISR_NO_ERR(195)
|
||||||
|
ISR_NO_ERR(196) ISR_NO_ERR(197) ISR_NO_ERR(198) ISR_NO_ERR(199)
|
||||||
|
ISR_NO_ERR(200) ISR_NO_ERR(201) ISR_NO_ERR(202) ISR_NO_ERR(203)
|
||||||
|
ISR_NO_ERR(204) ISR_NO_ERR(205) ISR_NO_ERR(206) ISR_NO_ERR(207)
|
||||||
|
ISR_NO_ERR(208) ISR_NO_ERR(209) ISR_NO_ERR(210) ISR_NO_ERR(211)
|
||||||
|
ISR_NO_ERR(212) ISR_NO_ERR(213) ISR_NO_ERR(214) ISR_NO_ERR(215)
|
||||||
|
ISR_NO_ERR(216) ISR_NO_ERR(217) ISR_NO_ERR(218) ISR_NO_ERR(219)
|
||||||
|
ISR_NO_ERR(220) ISR_NO_ERR(221) ISR_NO_ERR(222) ISR_NO_ERR(223)
|
||||||
|
ISR_NO_ERR(224) ISR_NO_ERR(225) ISR_NO_ERR(226) ISR_NO_ERR(227)
|
||||||
|
ISR_NO_ERR(228) ISR_NO_ERR(229) ISR_NO_ERR(230) ISR_NO_ERR(231)
|
||||||
|
ISR_NO_ERR(232) ISR_NO_ERR(233) ISR_NO_ERR(234) ISR_NO_ERR(235)
|
||||||
|
ISR_NO_ERR(236) ISR_NO_ERR(237) ISR_NO_ERR(238) ISR_NO_ERR(239)
|
||||||
|
ISR_NO_ERR(240) ISR_NO_ERR(241) ISR_NO_ERR(242) ISR_NO_ERR(243)
|
||||||
|
ISR_NO_ERR(244) ISR_NO_ERR(245) ISR_NO_ERR(246) ISR_NO_ERR(247)
|
||||||
|
ISR_NO_ERR(248) ISR_NO_ERR(249) ISR_NO_ERR(250) ISR_NO_ERR(251)
|
||||||
|
ISR_NO_ERR(252) ISR_NO_ERR(253) ISR_NO_ERR(254) ISR_NO_ERR(255)
|
||||||
|
|
||||||
|
// Array of all ISR handlers for easy initialization
|
||||||
|
void* isr_table[256] = {
|
||||||
|
isr0, isr1, isr2, isr3, isr4, isr5, isr6, isr7,
|
||||||
|
isr8, isr9, isr10, isr11, isr12, isr13, isr14, isr15,
|
||||||
|
isr16, isr17, isr18, isr19, isr20, isr21, isr22, isr23,
|
||||||
|
isr24, isr25, isr26, isr27, isr28, isr29, isr30, isr31,
|
||||||
|
isr32, isr33, isr34, isr35, isr36, isr37, isr38, isr39,
|
||||||
|
isr40, isr41, isr42, isr43, isr44, isr45, isr46, isr47,
|
||||||
|
isr48, isr49, isr50, isr51, isr52, isr53, isr54, isr55,
|
||||||
|
isr56, isr57, isr58, isr59, isr60, isr61, isr62, isr63,
|
||||||
|
isr64, isr65, isr66, isr67, isr68, isr69, isr70, isr71,
|
||||||
|
isr72, isr73, isr74, isr75, isr76, isr77, isr78, isr79,
|
||||||
|
isr80, isr81, isr82, isr83, isr84, isr85, isr86, isr87,
|
||||||
|
isr88, isr89, isr90, isr91, isr92, isr93, isr94, isr95,
|
||||||
|
isr96, isr97, isr98, isr99, isr100, isr101, isr102, isr103,
|
||||||
|
isr104, isr105, isr106, isr107, isr108, isr109, isr110, isr111,
|
||||||
|
isr112, isr113, isr114, isr115, isr116, isr117, isr118, isr119,
|
||||||
|
isr120, isr121, isr122, isr123, isr124, isr125, isr126, isr127,
|
||||||
|
isr128, isr129, isr130, isr131, isr132, isr133, isr134, isr135,
|
||||||
|
isr136, isr137, isr138, isr139, isr140, isr141, isr142, isr143,
|
||||||
|
isr144, isr145, isr146, isr147, isr148, isr149, isr150, isr151,
|
||||||
|
isr152, isr153, isr154, isr155, isr156, isr157, isr158, isr159,
|
||||||
|
isr160, isr161, isr162, isr163, isr164, isr165, isr166, isr167,
|
||||||
|
isr168, isr169, isr170, isr171, isr172, isr173, isr174, isr175,
|
||||||
|
isr176, isr177, isr178, isr179, isr180, isr181, isr182, isr183,
|
||||||
|
isr184, isr185, isr186, isr187, isr188, isr189, isr190, isr191,
|
||||||
|
isr192, isr193, isr194, isr195, isr196, isr197, isr198, isr199,
|
||||||
|
isr200, isr201, isr202, isr203, isr204, isr205, isr206, isr207,
|
||||||
|
isr208, isr209, isr210, isr211, isr212, isr213, isr214, isr215,
|
||||||
|
isr216, isr217, isr218, isr219, isr220, isr221, isr222, isr223,
|
||||||
|
isr224, isr225, isr226, isr227, isr228, isr229, isr230, isr231,
|
||||||
|
isr232, isr233, isr234, isr235, isr236, isr237, isr238, isr239,
|
||||||
|
isr240, isr241, isr242, isr243, isr244, isr245, isr246, isr247,
|
||||||
|
isr248, isr249, isr250, isr251, isr252, isr253, isr254, isr255,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Initialize all IDT entries
|
||||||
|
void init_idt(void) {
|
||||||
|
for (int i = 0; i < 256; i++) {
|
||||||
|
set_idt(i, isr_table[i], 0);
|
||||||
|
}
|
||||||
|
load_idt(idt);
|
||||||
|
}
|
||||||
119
src/main.c
Normal file
119
src/main.c
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "../include/limine.h"
|
||||||
|
|
||||||
|
// credit owed to https://wiki.osdev.org/Limine_Bare_Bones
|
||||||
|
|
||||||
|
__attribute__((used, section(".limine_requests")))
|
||||||
|
static volatile uint64_t limine_base_revision[] = LIMINE_BASE_REVISION(4);
|
||||||
|
|
||||||
|
__attribute__((used, section(".limine_requests")))
|
||||||
|
static volatile struct limine_framebuffer_request fb_req = {
|
||||||
|
.id = LIMINE_FRAMEBUFFER_REQUEST_ID,
|
||||||
|
.revision = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
__attribute__((used, section(".limine_requests_start")))
|
||||||
|
static volatile uint64_t limine_requests_start_marker[] = LIMINE_REQUESTS_START_MARKER;
|
||||||
|
|
||||||
|
__attribute__((used, section(".limine_requests_end")))
|
||||||
|
static volatile uint64_t limine_requests_end_marker[] = LIMINE_REQUESTS_END_MARKER;
|
||||||
|
|
||||||
|
void* memcpy(void* restrict dst, const void* src, size_t n) {
|
||||||
|
uint8_t* restrict pdst = (uint8_t* restrict)dst;
|
||||||
|
const uint8_t* restrict psrc = (const uint8_t* restrict)src;
|
||||||
|
|
||||||
|
for(size_t i = 0; i < n; i++) {
|
||||||
|
pdst[i] = psrc[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* memset(void* s, int c, size_t n) {
|
||||||
|
uint8_t* p = (uint8_t*) s;
|
||||||
|
|
||||||
|
for(size_t i = 0; i < n; i++) {
|
||||||
|
p[i] = (uint8_t)c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* memmove(void* dst, const void* src, size_t n) {
|
||||||
|
uint8_t* restrict pdst = (uint8_t* restrict)dst;
|
||||||
|
const uint8_t* restrict psrc = (const uint8_t* restrict)src;
|
||||||
|
|
||||||
|
if(src > dst) {
|
||||||
|
for(size_t i = 0; i < n; i++) {
|
||||||
|
pdst[i] = psrc[i];
|
||||||
|
}
|
||||||
|
} else if(src < dst) {
|
||||||
|
for(size_t i = n; i > 0; i--) {
|
||||||
|
pdst[i-1] = psrc[i-1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
int memcmp(const void* s1, const void* s2, size_t n) {
|
||||||
|
const uint8_t* p1 = (const uint8_t* )s1;
|
||||||
|
const uint8_t* p2 = (const uint8_t* )s2;
|
||||||
|
|
||||||
|
for(size_t i = 0; i < n; i++) {
|
||||||
|
if(p1[i] != p2[i]) {
|
||||||
|
return p1[i] < p2[i] ? -1 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hang() {
|
||||||
|
for(;;) {
|
||||||
|
asm ("hlt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct limine_framebuffer* fb;
|
||||||
|
|
||||||
|
void draw(uint8_t vect) {
|
||||||
|
for(size_t y = 0; y < fb->height; y++) {
|
||||||
|
for(size_t x = 0; x < fb->width; x++) {
|
||||||
|
volatile uint32_t* fb_ptr = fb->address;
|
||||||
|
fb_ptr[y * fb->width + x] = (
|
||||||
|
(x + y) * 0x00010000 |
|
||||||
|
(x ^ y) * 0x00000100 |
|
||||||
|
(x - y) * 0x00000001
|
||||||
|
)*vect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void init_idt(void);
|
||||||
|
|
||||||
|
void kmain() {
|
||||||
|
if(LIMINE_BASE_REVISION_SUPPORTED(limine_base_revision) == false) {
|
||||||
|
hang();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fb_req.response == NULL || fb_req.response->framebuffer_count < 1) {
|
||||||
|
hang();
|
||||||
|
}
|
||||||
|
|
||||||
|
fb = fb_req.response->framebuffers[0];
|
||||||
|
|
||||||
|
init_idt();
|
||||||
|
|
||||||
|
for(size_t i = 0; ~i & (1<<30); i++) {
|
||||||
|
draw(i&0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
hang();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user