288 lines
7.2 KiB
C
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;
|
|
//==============================================================================
|