Files
MentOS/mentos/inc/kernel.h
T
Luigi Capogrosso 7d9085fecf Finish v0.3.0
2019-05-08 17:07:11 +02:00

288 lines
7.2 KiB
C

/// MentOS, The Mentoring Operating system project
/// @file kernel.h
/// @brief Kernel generic data structure and functions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "elf.h"
#include "stddef.h"
#include "stdint.h"
#include "stdbool.h"
#include "multiboot.h"
/// The maximum length of a file name.
#define MAX_FILENAME_LENGTH 64
/// The maximum length of a path.
#define MAX_PATH_LENGTH 256
/// The maximum number of modules.
#define MAX_MODULES 10
/// This should be in %eax.
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
/// Our kernel now loads at 0xC0000000, so what low memory address such as
/// 0xb800 you used to access, should be LOAD_MEMORY_ADDRESS + 0xb800
#define LOAD_MEMORY_ADDRESS 0x00000000
// TODO: doxygen comment.
extern uintptr_t initial_esp;
/// @brief Halt.
inline static void halt()
{
__asm__ __volatile__("hlt" ::: "memory");
}
/// @brief Pause.
inline static void pause()
{
__asm__ __volatile__("pause" ::: "memory");
}
#define K 1024
#define M (1024 * K)
#define G (1024 * M)
/// Pointer the beging of the module.
extern char *module_start[MAX_MODULES];
/// Address to the end of the module.
extern char *module_end[MAX_MODULES];
/// Elf symbols of the kernel.
extern elf_symbols_t kernel_elf;
/// @brief Entry point of the kernel.
/// @param boot_informations Information concerning the boot.
/// @return The exit status of the kernel.
int kmain(uint32_t magic, multiboot_info_t *header, uintptr_t esp);
/// @brief Register structs for interrupt/exception.
typedef struct register_t {
/// FS and GS have no hardware-assigned uses.
uint32_t gs;
/// FS and GS have no hardware-assigned uses.
uint32_t fs;
/// Extra Segment determined by the programmer.
uint32_t es;
/// Data Segment.
uint32_t ds;
/// 32-bit destination register.
uint32_t edi;
/// 32-bit source register.
uint32_t esi;
/// 32-bit base pointer register.
uint32_t ebp;
/// 32-bit stack pointer register.
uint32_t esp;
/// 32-bit base register.
uint32_t ebx;
/// 32-bit data register.
uint32_t edx;
/// 32-bit counter.
uint32_t ecx;
/// 32-bit accumulator register.
uint32_t eax;
/// Interrupt number.
uint32_t int_no;
/// Error code.
uint32_t err_code;
/// Instruction Pointer Register.
uint32_t eip;
/// Code Segment.
uint32_t cs;
/// 32-bit flag register.
uint32_t eflags;
// TODO: Check meaning!
uint32_t useresp;
/// Stack Segment.
uint32_t ss;
} register_t;
/*
* /// @brief Register structs for bios service.
* typedef struct register16_t
* {
* /// Destination Index.
* uint16_t di;
* /// Source Index.
* uint16_t si;
* /// Base Pointer.
* uint16_t bp;
* /// Stack Pointer.
* uint16_t sp;
* /// Also known as the base register.
* uint16_t bx;
* /// Also known as the data register.
* uint16_t dx;
* /// Also known as the count register.
* uint16_t cx;
* /// Is the primary accumulator.
* uint16_t ax;
* /// Data Segment.
* uint16_t ds;
* /// Extra Segment determined by the programmer.
* uint16_t es;
* /// FS and GS have no hardware-assigned uses.
* uint16_t fs;
* /// FS and GS have no hardware-assigned uses.
* uint16_t gs;
* /// Stack Segment.
* uint16_t ss;
* /// 32-bit flag register.
* uint16_t eflags;
* } register16_t;
*/
//==== Interrupt stack frame ===================================================
// Interrupt stack frame. When the CPU moves from Ring3 to Ring0 because of
// an interrupt, the following registes/values are moved into the kernel's stack
// TODO: doxygen comment.
typedef struct pt_regs {
/// FS and GS have no hardware-assigned uses.
uint32_t gs;
/// FS and GS have no hardware-assigned uses.
uint32_t fs;
/// Extra Segment determined by the programmer.
uint32_t es;
/// Data Segment.
uint32_t ds;
/// 32-bit destination register.
uint32_t edi;
/// 32-bit source register.
uint32_t esi;
/// 32-bit base pointer register.
uint32_t ebp;
/// 32-bit stack pointer register.
uint32_t esp;
/// 32-bit base register.
uint32_t ebx;
/// 32-bit data register.
uint32_t edx;
/// 32-bit counter.
uint32_t ecx;
/// 32-bit accumulator register.
uint32_t eax;
/// Interrupt number.
uint32_t int_no;
/// Error code.
uint32_t err_code;
/// Instruction Pointer Register.
uint32_t eip;
/// Code Segment.
uint32_t cs;
/// 32-bit flag register.
uint32_t eflags;
// TODO: Check meaning!
uint32_t useresp;
/// Stack Segment.
uint32_t ss;
} pt_regs;
//==============================================================================
//==== Floating Point Unit (FPU) Register ======================================
// Data structure used to save FPU registers.
/// @brief Environment information of floating point unit.
typedef struct {
/// Control word (16bits).
long en_cw;
/// Status word (16bits).
long en_sw;
/// Tag word (16bits).
long en_tw;
/// Floating point instruction pointer.
long en_fip;
/// Floating code segment selector.
unsigned short en_fcs;
/// Opcode last executed (11 bits).
unsigned short en_opcode;
/// Floating operand offset.
long en_foo;
/// Floating operand segment selector.
long en_fos;
} env87;
/// @brief Contents of each floating point accumulator.
typedef struct {
unsigned char fp_bytes[10];
} fpacc87;
/// @brief Floating point context.
typedef struct {
/// Floating point control/status.
env87 sv_env;
/// Accumulator contents, 0-7.
fpacc87 sv_ac[8];
/// Padding for (now unused) saved status word.
unsigned char sv_pad0[4];
/*
* Bogus padding for emulators. Emulators should use their own
* struct and arrange to store into this struct (ending here)
* before it is inspected for ptracing or for core dumps. Some
* emulators overwrite the whole struct. We have no good way of
* knowing how much padding to leave. Leave just enough for the
* GPL emulator's i387_union (176 bytes total).
*/
unsigned char sv_pad[64]; // Padding; used by emulators
} save87;
// TODO: doxygen comment.
typedef struct {
/// Control word (16bits).
uint16_t en_cw;
/// Status word (16bits).
uint16_t en_sw;
/// Tag word (16bits).
uint16_t en_tw;
/// Opcode last executed (11 bits).
uint16_t en_opcode;
/// Floating point instruction pointer.
uint32_t en_fip;
/// Floating code segment selector.
uint16_t en_fcs;
/// Padding.
uint16_t en_pad0;
/// Floating operand offset.
uint32_t en_foo;
/// Floating operand segment selector.
uint16_t en_fos;
/// Padding.
uint16_t en_pad1;
/// SSE sontorol/status register.
uint32_t en_mxcsr;
/// Valid bits in mxcsr.
uint32_t en_mxcsr_mask;
} envxmm;
/// @brief Contents of each SSE extended accumulator.
typedef struct {
unsigned char xmm_bytes[16];
} xmmacc;
// TODO: doxygen comment.
typedef struct {
envxmm sv_env;
struct {
fpacc87 fp_acc;
/// Padding.
unsigned char fp_pad[6];
} sv_fp[8];
xmmacc sv_xmm[8];
/// Padding.
unsigned char sv_pad[224];
} __attribute__((__aligned__(16))) savexmm;
// TODO: doxygen comment.
typedef union {
save87 sv_87;
savexmm sv_xmm;
} savefpu;
//==============================================================================