some test things

This commit is contained in:
2025-05-10 15:48:06 +03:00
parent 7e97987e95
commit b836a37264
5 changed files with 379 additions and 84 deletions
+101 -75
View File
@@ -1,96 +1,122 @@
bits 32
section .multiboot
align 4
dd 0x1BADB002
dd 0x00
dd - (0x1BADB002+0x00)
%define CR0_MP 0x00000002 /* bit 01 -> enable monitor coprocessor */
%define CR0_NE 0x00000020 /* bit 05 -> enable native x87 FPU mode */
%define CR0_WP 0x00010000 /* bit 16 -> enable write protect (for CoW) */
%define CR0_AM 0x00040000 /* bit 18 -> enable alignment checking */
%define CR0_PG 0x80000000 /* bit 31 -> enable paging */
section .data
%define PAGE_OFFSET 0xC0000000
%define GDT_BASE (0xFFFFFFFF - (PAGE_OFFSET - 1))
section .setup
align 4
multiboot_info:
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
tmp_gdtr:
dw ((3 * 8) - 1)
tmp_gdta:
dd tmp_gdt
global tss
global tss_end
align 4
tss:
dd 0 ; 0-3
dd stack_top ; 4-7
dd DATA_SEG ; 8-11
dd 0 ; 12-15
dd 0 ; 16-19
dd 0 ; 20-23
dd 0 ; 24-27
dd 0 ; 28-31
dd 0 ; 32-35
dd 0 ; 36-39
dd 0 ; 40-43
dd 0 ; 44-47
dd 0 ; 48-51
dd 0 ; 52-55
dd 0 ; 56-59
dd 0 ; 60-63
dd 0 ; 64-67
dd 0 ; 68-71
dd DATA_SEG ; 72-75
dd CODE_SEG ; 76-79
dd DATA_SEG ; 80-83
dd DATA_SEG ; 84-87
dd DATA_SEG ; 88-91
dd DATA_SEG ; 92-95
dd 0 ; 96-99
dw 0 ; 100-101
dw 104 ; 102-103
tss_end:
tmp_gdt:
; null entry
dw 0x0000
dw 0x0000
dw 0x0000
dw 0x0000
section .bss
stack_bottom:
resb 16384
stack_top:
; /* KERNEL CODE */
dw 0xFFFF ; /* segment limit 15-00 */
dw 0x0000 ; /* base address 15-00 */
db 0x00 ; /* base address 23-16 */
db 0x9A ; /* P=1 DPL=00 S=1 TYPE=1010 (exec/read) */
db 0xCF ; /* G=1 DB=1 0=0 AVL=0 SEGLIM=1111 */
db GDT_BASE >> 24 ; /* base address 31-24 */
; /* KERNEL DATA */
dw 0xFFFF ; /* segment limit 15-00 */
dw 0x0000 ; /* base address 15-00 */
db 0x00 ; /* base address 23-16 */
db 0x92 ; /* P=1 DPL=00 S=1 TYPE=0010 (read/write) */
db 0xCF ; /* G=1 DB=1 0=0 AVL=0 SEGLIM=1111 */
db GDT_BASE >> 24 ; /* base address 31-24 */
section .gdt
%include "src/gdt.asm"
align 4
multiboot_header:
dd 0x1BADB002
dd 0x00
dd - (0x1BADB002 + 0x00)
section .text
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
; section .text
global start:function (start.end - start)
extern kmain ; this function is gonna be located in our c code(kernel.c)
extern get_last_boot_addr
extern gdt_init
extern bss_init
extern setup_tmp_pgdir
align 4
start:
mov esp, stack_top
; mov esp, stack_top
cli
push ebx ; Сохраняем оригинальный ebx (указатель Multiboot)
; push ebx ; Сохраняем оригинальный ebx (указатель Multiboot)
lgdt [gdt]
;lgdt [gdt]
lgdt [tmp_gdtr]
; Заполняем адрес TSS в дескрипторе GDT
mov eax, tss ; Получаем 32-битный адрес tss
mov ebx, gdt_tss ; Адрес дескриптора TSS в GDT
mov [ebx + 2], ax ; Нижние 16 бит адреса TSS
shr eax, 16 ; Сдвигаем для доступа к старшим битам
mov [ebx + 4], al ; Средние 8 бит адреса TSS
mov [ebx + 7], ah ; Верхние 8 бит адреса TSS
mov cx, 0x10 ; data segment
mov ds, cx
mov es, cx
mov fs, cx
mov gs, cx
mov ss, cx
jmp 0x8:.huita ; 0x8 - code segment
mov ax, DATA_SEG
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp CODE_SEG:.huita
.text
align 4
.huita:
mov ax, TSS_SEG
ltr ax
pop ebx ; Восстанавливаем оригинальный ebx
push ebx ; Передаем его в kmain
call kmain
hlt
mov esp, PAGE_OFFSET + 0x10000 ; default stack address
push 0
popf ; reset EFLAGS
push ebx ; save Multiboot info structure
push eax ; save Multiboot magic value
call setup_tmp_pgdir
mov cr3, eax
mov eax, cr0
and eax, 0x00000011 ; disable all, preserve ET & PE (GRUB)
or eax, 0x80000000 ; CR0_PG ; enable PG
or eax, 0x40000 ; CR0_AM ; enable AM
or eax, 0x10000 ; CR0_WP ; enable WP
or eax, 0x20 ; CR0_NE ; enable NE
or eax, 0x2 ; CR0_MP ; enable MP
mov cr0, eax
call bss_init ; initialize BSS segment
call gdt_init ; setup and load definitive GDT
call get_last_boot_addr
pop ecx ; restore Multiboot magic value
pop ebx ; restore Multiboot info structure
push eax ; save last boot address
push ebx ; save Multiboot info structure
push ecx ; save Multiboot magic value
pop ebx ; Восстанавливаем оригинальный ebx
push ebx ; Передаем его в kmain
call kmain
hlt
.end:
+171
View File
@@ -0,0 +1,171 @@
//#include "../include/gdt.h"
#include <stdint.h>
#include "../include/string.h"
struct desc_r {
uint16_t limit;
uint32_t base_addr;
} __attribute__((packed));
struct seg_desc {
unsigned sd_lolimit : 16; /* segment limit 0-15 bits */
unsigned sd_lobase : 24; /* base address 0-23 bits */
unsigned sd_loflags : 8; /* flags (P, DPL, S and TYPE) */
unsigned sd_hilimit : 4; /* segment limit 16-19 bits */
unsigned sd_hiflags : 4; /* flags (G, DB, 0 and AVL) */
unsigned sd_hibase : 8; /* base address 24-31 bits */
} __attribute__((packed));
struct gate_desc {
unsigned gd_looffset: 16; /* offset 0-15 bits */
unsigned gd_selector: 16; /* segment selector */
unsigned gd_flags : 16; /* flags (P, DPL, TYPE, 0 and NULL) */
unsigned gd_hioffset: 16; /* offset 16-31 bits */
} __attribute__((packed));
extern char _end[], _edata[];
#define KERNEL_CS 0x08 /* kernel code segment */
#define KERNEL_DS 0x10 /* kernel data segment */
#define USER_CS 0x18 /* user code segment */
#define USER_DS 0x20 /* user data segment */
#define TSS 0x28 /* TSS segment */
void load_gdt(uint32_t gdt_ptr) {
asm volatile (
"lgdt (%0)\n\t"
"movw %1, %%ax\n\t"
"movw %%ax, %%ds\n\t"
"movw %%ax, %%es\n\t"
"movw %%ax, %%fs\n\t"
"movw %%ax, %%gs\n\t"
"movw %%ax, %%ss\n\t"
"ljmp %2, $1f\n\t"
"1:\n\t"
:
: "r" (gdt_ptr), "i" (KERNEL_DS), "i" (KERNEL_CS)
: "eax"
);
}
#define PAGE_SIZE 4096
#define PAGE_SHIFT 0x0C
#define PAGE_MASK ~(PAGE_SIZE - 1) /* 0xFFFFF000 */
#define PAGE_ALIGN(addr) (((addr) + (PAGE_SIZE - 1)) & PAGE_MASK)
#define KERNEL_BSS_SIZE ((int)_end - (int)_edata)
#define NR_GDT_ENTRIES 6 /* entries in GDT descriptor */
#define NR_IDT_ENTRIES 256 /* entries in IDT descriptor */
/* low flags of Segment Descriptors */
#define SD_CODE 0x0A /* CODE Exec/Read */
#define SD_DATA 0x02 /* DATA Read/Write */
#define SD_32INTRGATE 0x0E /* 32-bit Interrupt Gate (0D110) */
#define SD_32TRAPGATE 0x0F /* 32-bit Trap Gate (0D111) */
#define SD_CD 0x10 /* 0 = system / 1 = code/data */
#define SD_DPL0 0x00 /* priority level 0 (kernel) */
#define SD_DPL3 0x60 /* priority level 3 (user) */
#define SD_PRESENT 0x80 /* segment present or valid */
/* high flags Segment Descriptors */
#define SD_OPSIZE32 0x04 /* 32-bit code and data segments */
#define SD_PAGE4KB 0x08 /* page granularity (4KB) */
/* low flags of the TSS Descriptors */
#define SD_TSSPRESENT 0x89 /* TSS present and not busy flag */
/* EFLAGS */
#define EF_IOPL 12 /* IOPL bit */
#define KERNEL_CS 0x08 /* kernel code segment */
#define KERNEL_DS 0x10 /* kernel data segment */
#define USER_CS 0x18 /* user code segment */
#define USER_DS 0x20 /* user data segment */
#define TSS 0x28 /* TSS segment */
struct tss_entry_struct {
uint32_t prev_tss; // The previous TSS - with hardware task switching these form a kind of backward linked list.
uint32_t esp0; // The stack pointer to load when changing to kernel mode.
uint32_t ss0; // The stack segment to load when changing to kernel mode.
// Everything below here is unused.
uint32_t esp1; // esp and ss 1 and 2 would be used when switching to rings 1 or 2.
uint32_t ss1;
uint32_t esp2;
uint32_t ss2;
uint32_t cr3;
uint32_t eip;
uint32_t eflags;
uint32_t eax;
uint32_t ecx;
uint32_t edx;
uint32_t ebx;
uint32_t esp;
uint32_t ebp;
uint32_t esi;
uint32_t edi;
uint32_t es;
uint32_t cs;
uint32_t ss;
uint32_t ds;
uint32_t fs;
uint32_t gs;
uint32_t ldt;
uint16_t trap;
uint16_t iomap_base;
} __packed;
void bss_init()
{
memset((void *)((int)_edata), 0, KERNEL_BSS_SIZE);
}
uint32_t get_last_boot_addr()
{
return ((unsigned int)_end & PAGE_MASK) + PAGE_SIZE;
}
struct seg_desc gdt[NR_GDT_ENTRIES];
struct desc_r gdtr = {
sizeof(gdt) - 1,
(unsigned int)&gdt
};
static void gdt_set_entry(int num, unsigned int base_addr, unsigned int limit, char loflags, char hiflags)
{
num /= sizeof(struct seg_desc);
gdt[num].sd_lolimit = limit & 0xFFFF;
gdt[num].sd_lobase = base_addr & 0xFFFFFF;
gdt[num].sd_loflags = loflags;
gdt[num].sd_hilimit = (limit >> 16) & 0x0F;
gdt[num].sd_hiflags = hiflags;
gdt[num].sd_hibase = (base_addr >> 24) & 0xFF;
}
void gdt_init(void)
{
unsigned char loflags;
gdt_set_entry(0, 0, 0, 0, 0); /* null descriptor */
loflags = SD_CODE | SD_CD | SD_DPL0 | SD_PRESENT;
gdt_set_entry(KERNEL_CS, 0, 0xFFFFFFFF, loflags, SD_OPSIZE32 | SD_PAGE4KB);
loflags = SD_DATA | SD_CD | SD_DPL0 | SD_PRESENT;
gdt_set_entry(KERNEL_DS, 0, 0xFFFFFFFF, loflags, SD_OPSIZE32 | SD_PAGE4KB);
loflags = SD_CODE | SD_CD | SD_DPL3 | SD_PRESENT;
gdt_set_entry(USER_CS, 0, 0xFFFFFFFF, loflags, SD_OPSIZE32 | SD_PAGE4KB);
loflags = SD_DATA | SD_CD | SD_DPL3 | SD_PRESENT;
gdt_set_entry(USER_DS, 0, 0xFFFFFFFF, loflags, SD_OPSIZE32 | SD_PAGE4KB);
loflags = SD_TSSPRESENT;
gdt_set_entry(TSS, 0, sizeof(struct tss_entry_struct), loflags, SD_OPSIZE32);
load_gdt((unsigned int)&gdtr);
}
+67
View File
@@ -1,10 +1,77 @@
#include "../include/paging.h"
#include <stdint.h>
#include "../include/multiboot.h"
#include "../include/string.h"
uint32_t kernel_page_directory[1024] __attribute__((aligned(4096)));
uint32_t kernel_page_table[1024] __attribute__((aligned(4096)));
uint32_t user_page_table[1024] __attribute__((aligned(4096)));
#define PAGE_OFFSET 0xC0000000
#define PAGE_SIZE 4096
#define PAGE_PRESENT 0x1
#define PAGE_RW 0x002 /* Read/Write */
#define PAGE_USER 0x004 /* User */
#define PAGE_NOALLOC 0x200 /* No Page Allocated (OS managed) */
#define PAGE_SHIFT 0x0C
#define PAGE_MASK ~(PAGE_SIZE - 1) /* 0xFFFFF000 */
#define GDT_BASE (0xFFFFFFFF - (PAGE_OFFSET - 1))
#define GET_PGDIR(address) ((unsigned int)((address) >> 22) & 0x3FF)
#define GET_PGTBL(address) ((unsigned int)((address) >> 12) & 0x3FF)
#define PAGE_ALIGN(addr) (((addr) + (PAGE_SIZE - 1)) & PAGE_MASK)
unsigned int *kpage_dir;
unsigned int setup_tmp_pgdir(unsigned int magic, unsigned int info)
{
int n, pd;
unsigned int addr, memksize;
unsigned int *pgtbl;
struct multiboot_info *mbi;
if(magic != MULTIBOOT_BOOTLOADER_MAGIC) {
/* 4MB of memory assumed */
memksize = 4096;
} else {
mbi = (struct multiboot_info *)(PAGE_OFFSET + info);
if(!(mbi->flags & MULTIBOOT_INFO_MEMORY)) {
/* 4MB of memory assumed */
memksize = 4096;
} else {
/* we need to add the first 1MB to memksize */
memksize = (unsigned int)mbi->mem_upper + 1024;
/* CONFIG_VM_SPLIT22 marks the maximum physical memory supported */
if(memksize > ((0xFFFFFFFF - PAGE_OFFSET) / 1024)) {
memksize = (0xFFFFFFFF - PAGE_OFFSET) / 1024;
}
}
}
addr = PAGE_OFFSET + (memksize * 1024) - memksize;
addr = PAGE_ALIGN(addr);
kpage_dir = (unsigned int *)addr;
memset(kpage_dir, 0, PAGE_SIZE);
addr += PAGE_SIZE;
pgtbl = (unsigned int *)addr;
memset(pgtbl, 0, memksize);
for(n = 0; n < memksize / sizeof(unsigned int); n++) {
pgtbl[n] = (n << PAGE_SHIFT) | PAGE_PRESENT | PAGE_RW;
if(!(n % 1024)) {
pd = n / 1024;
kpage_dir[pd] = (unsigned int)(addr + (PAGE_SIZE * pd) + GDT_BASE) | PAGE_PRESENT | PAGE_RW;
kpage_dir[GET_PGDIR(PAGE_OFFSET) + pd] = (unsigned int)(addr + (PAGE_SIZE * pd) + GDT_BASE) | PAGE_PRESENT | PAGE_RW;
}
}
return (unsigned int)kpage_dir - PAGE_OFFSET;
}
void enablePaging() {
asm volatile (