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
+5 -2
View File
@@ -2,7 +2,7 @@
OBJS = bin/boot.o bin/kernel.o bin/idt.o bin/isr.o bin/screen.o \ OBJS = bin/boot.o bin/kernel.o bin/idt.o bin/isr.o bin/screen.o \
bin/utils.o bin/string.o bin/stdio.o bin/disk.o bin/pic.o bin/pit.o \ bin/utils.o bin/string.o bin/stdio.o bin/disk.o bin/pic.o bin/pit.o \
bin/keyboard.o bin/paging.o bin/heap.o bin/page_alloc.o bin/page_tables.o \ bin/keyboard.o bin/paging.o bin/heap.o bin/page_alloc.o bin/page_tables.o \
bin/fat.o bin/task.o bin/switch.o bin/sys_exit.o bin/fat.o bin/task.o bin/switch.o bin/sys_exit.o bin/gdt.o
# Define the compiler and assembler # Define the compiler and assembler
CC = gcc -D__is_katauos CC = gcc -D__is_katauos
@@ -48,7 +48,7 @@ image:
sudo losetup -D sudo losetup -D
test: test:
qemu-system-i386 -drive file=boot.iso,media=disk,format=raw -m 512M -d int qemu-system-i386 -drive file=boot.iso,media=disk,format=raw -m 4096M -d int
#qemu-system-i386 -s -S -kernel myos.bin #qemu-system-i386 -s -S -kernel myos.bin
debug: debug:
@@ -120,6 +120,9 @@ bin/task.o: src/tasking/task.c
bin/sys_exit.o: src/tasking/sys_exit.asm bin/sys_exit.o: src/tasking/sys_exit.asm
$(AS) $(ASFLAGS) $< -o $@ $(AS) $(ASFLAGS) $< -o $@
bin/gdt.o: src/kernel/gdt.c
$(CC) $(CFLAGS) -c $< -o $@
clean: clean:
rm -rf bin/ rm -rf bin/
rm -f $(OUTPUT) rm -f $(OUTPUT)
+35 -7
View File
@@ -1,17 +1,45 @@
OUTPUT_FORMAT(elf32-i386) OUTPUT_FORMAT(elf32-i386)
ENTRY(start) ENTRY(start)
vaddr = 0xC0000000; /* virtual start address */
paddr = 0x100000; /* physical address at 1MB */
SECTIONS SECTIONS
{ {
. = 0x100000; . = 0x100000;
.setup ALIGN(4096) :
{
*(.setup)
}
. += vaddr;
.text BLOCK(4K) : ALIGN(4K) { .text BLOCK(4K) : ALIGN(4K) {
*(.multiboot)
*(.text) *(.text)
} }
.rodata BLOCK(4K) : ALIGN(4K) { *(.rodata) } _etext = .;
.data BLOCK(4K) : ALIGN(4K) { *(.data) }
.bss BLOCK(4K) : ALIGN(4K) { .data ALIGN(4096) : AT(ADDR(.data) - vaddr)
*(.COMMON) {
*(.bss) *(.data)
*(.rodata*)
} }
kernel_end = .; _edata = .;
/* uninitialized data */
.bss ALIGN(4096) : AT(ADDR(.bss) - vaddr)
{
*(COMMON*)
*(.bss*)
}
_end = .;
/DISCARD/ :
{
*(.comment)
*(.eh_frame)
*(.note*)
}
} }
+92 -66
View File
@@ -1,14 +1,53 @@
bits 32 bits 32
section .multiboot %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 */
%define PAGE_OFFSET 0xC0000000
%define GDT_BASE (0xFFFFFFFF - (PAGE_OFFSET - 1))
section .setup
align 4 align 4
tmp_gdtr:
dw ((3 * 8) - 1)
tmp_gdta:
dd tmp_gdt
align 4
tmp_gdt:
; null entry
dw 0x0000
dw 0x0000
dw 0x0000
dw 0x0000
; /* 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 */
align 4
multiboot_header:
dd 0x1BADB002 dd 0x1BADB002
dd 0x00 dd 0x00
dd - (0x1BADB002 + 0x00) dd - (0x1BADB002 + 0x00)
section .data dd 0
align 4 dd 0
multiboot_info:
dd 0 dd 0
dd 0 dd 0
dd 0 dd 0
@@ -17,78 +56,65 @@ multiboot_info:
dd 0 dd 0
dd 0 dd 0
global tss ; section .text
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:
section .bss
stack_bottom:
resb 16384
stack_top:
section .gdt
%include "src/gdt.asm"
section .text
global start:function (start.end - start) global start:function (start.end - start)
extern kmain ; this function is gonna be located in our c code(kernel.c) 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: start:
mov esp, stack_top ; mov esp, stack_top
cli cli
push ebx ; Сохраняем оригинальный ebx (указатель Multiboot) ; push ebx ; Сохраняем оригинальный ebx (указатель Multiboot)
lgdt [gdt] ;lgdt [gdt]
lgdt [tmp_gdtr]
; Заполняем адрес TSS в дескрипторе GDT mov cx, 0x10 ; data segment
mov eax, tss ; Получаем 32-битный адрес tss mov ds, cx
mov ebx, gdt_tss ; Адрес дескриптора TSS в GDT mov es, cx
mov [ebx + 2], ax ; Нижние 16 бит адреса TSS mov fs, cx
shr eax, 16 ; Сдвигаем для доступа к старшим битам mov gs, cx
mov [ebx + 4], al ; Средние 8 бит адреса TSS mov ss, cx
mov [ebx + 7], ah ; Верхние 8 бит адреса TSS jmp 0x8:.huita ; 0x8 - code segment
mov ax, DATA_SEG .text
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp CODE_SEG:.huita
align 4
.huita: .huita:
mov ax, TSS_SEG mov esp, PAGE_OFFSET + 0x10000 ; default stack address
ltr ax 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 pop ebx ; Восстанавливаем оригинальный ebx
push ebx ; Передаем его в kmain push ebx ; Передаем его в kmain
call kmain call kmain
+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 "../include/paging.h"
#include <stdint.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_directory[1024] __attribute__((aligned(4096)));
uint32_t kernel_page_table[1024] __attribute__((aligned(4096))); uint32_t kernel_page_table[1024] __attribute__((aligned(4096)));
uint32_t user_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() { void enablePaging() {
asm volatile ( asm volatile (