organization

This commit is contained in:
2025-05-10 15:48:10 +03:00
parent 00c9560660
commit 0bf26a6c70
7 changed files with 158 additions and 221 deletions
+1
View File
@@ -1,3 +1,4 @@
bin/ bin/
myos.bin myos.bin
boot.iso boot.iso
.vscode/
+100
View File
@@ -0,0 +1,100 @@
#ifndef GDT_H
#define GDT_H
#include <stdint.h>
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 */
#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 */
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));
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;
struct seg_desc gdt[NR_GDT_ENTRIES];
struct desc_r gdtr = {
sizeof(gdt) - 1,
(uint32_t)&gdt
};
#endif
+16 -1
View File
@@ -4,12 +4,27 @@
#include "../include/stdio.h" #include "../include/stdio.h"
#include <stdint.h> #include <stdint.h>
#define PAGE_OFFSET 0xC0000000
#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 PAGE_PRESENT 0x1
#define PAGE_RW 0x002 /* Read/Write */
#define PAGE_USER 0x004 /* User */
#define PAGE_NOALLOC 0x200 /* No Page Allocated (OS managed) */
#define GDT_BASE (0xFFFFFFFF - (PAGE_OFFSET - 1))
#define GET_PGDIR(address) ((uint32_t)((address) >> 22) & 0x3FF)
#define GET_PGTBL(address) ((uint32_t)((address) >> 12) & 0x3FF)
extern uint32_t kernel_page_directory[1024] __attribute__((aligned(4096))); extern uint32_t kernel_page_directory[1024] __attribute__((aligned(4096)));
extern uint32_t kernel_page_table[1024] __attribute__((aligned(4096))); extern uint32_t kernel_page_table[1024] __attribute__((aligned(4096)));
extern uint32_t user_page_table[1024] __attribute__((aligned(4096))); extern uint32_t user_page_table[1024] __attribute__((aligned(4096)));
//paging.c //paging.c
void enablePaging(); void enablePaging();
void loadPageDirectory(uint32_t* page_directory); void loadPageDirectory(uint32_t* page_directory);
-61
View File
@@ -1,61 +0,0 @@
section .gdt
extern tss ; Объявляем tss как внешний символ из .data
extern tss_end
gdt_start:
; null entry
dd 0
dd 0
gdt_code:
dw 0xffff ; 00-15 limit
dw 0 ; 16-31 base
db 0 ; 32-39 base
db 10011010b ; 40-47 access
db 11101111b ; 48-55 limit (48-51) and flags (52-55)
db 0 ; 56-63 base
gdt_data:
dw 0xffff ; 00-15 limit
dw 0 ; 16-31 base
db 0 ; 32-39 base
db 10010010b ; 40-47 access
db 11101111b ; 48-55 limit (48-51) and flags (52-55)
db 0 ; 56-63 base
gdt_code_ring3:
dw 0xffff
dw 0
db 0
db 11111010b
db 11101111b
db 0
gdt_data_ring3:
dw 0xffff
dw 0
db 0
db 11110010b
db 11101111b
db 0
gdt_tss:
dw 103 ;tss_end - tss - 1 ; Limit (размер TSS - 1)
dw 0 ; Base (будет заполнено вручную в boot.asm)
db 0 ; Base (средние 8 бит)
db 10001001b ; Access: Present, Ring 0, Type 9 (Available TSS)
db 00000000b ; Limit (48-51) и Flags (52-55): Granularity=0, Size=0
db 0 ; Base (верхние 8 бит)
gdt_end:
gdt:
dw gdt_end - gdt_start - 1
dd gdt_start
CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start
CODE_SEG_RING3 equ gdt_code_ring3 - gdt_start
DATA_SEG_RING3 equ gdt_data_ring3 - gdt_start
TSS_SEG equ gdt_tss - gdt_start
+13 -121
View File
@@ -1,36 +1,16 @@
//#include "../include/gdt.h" #include "../include/gdt.h"
#include <stdint.h>
#include "../include/string.h" #include "../include/string.h"
#include "../include/paging.h"
struct desc_r { void bss_init()
uint16_t limit; {
uint32_t base_addr; memset((void *)((int)_edata), 0, KERNEL_BSS_SIZE);
} __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 */
uint32_t get_last_boot_addr()
{
return ((uint32_t)_end & PAGE_MASK) + PAGE_SIZE;
}
void load_gdt(uint32_t gdt_ptr) { void load_gdt(uint32_t gdt_ptr) {
asm volatile ( asm volatile (
@@ -49,95 +29,7 @@ void load_gdt(uint32_t gdt_ptr) {
); );
} }
#define PAGE_SIZE 4096 static void gdt_set_entry(int num, uint32_t base_addr, uint32_t limit, char loflags, char hiflags)
#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); num /= sizeof(struct seg_desc);
gdt[num].sd_lolimit = limit & 0xFFFF; gdt[num].sd_lolimit = limit & 0xFFFF;
@@ -150,7 +42,7 @@ static void gdt_set_entry(int num, unsigned int base_addr, unsigned int limit, c
void gdt_init(void) void gdt_init(void)
{ {
unsigned char loflags; uint8_t loflags;
gdt_set_entry(0, 0, 0, 0, 0); /* null descriptor */ gdt_set_entry(0, 0, 0, 0, 0); /* null descriptor */
@@ -167,5 +59,5 @@ void gdt_init(void)
loflags = SD_TSSPRESENT; loflags = SD_TSSPRESENT;
gdt_set_entry(TSS, 0, sizeof(struct tss_entry_struct), loflags, SD_OPSIZE32); gdt_set_entry(TSS, 0, sizeof(struct tss_entry_struct), loflags, SD_OPSIZE32);
load_gdt((unsigned int)&gdtr); load_gdt((uint32_t)&gdtr);
} }
+3 -3
View File
@@ -155,9 +155,9 @@ void kmain(unsigned int magic, unsigned int info)
apply_pic_masks(); apply_pic_masks();
paging_init(); //paging_init();
printf("paging_init done\n"); //printf("paging_init done\n");
test_paging(); //test_paging();
init_allocator(); init_allocator();
heap_init(); heap_init();
printf("after heap_init\n"); printf("after heap_init\n");
+25 -35
View File
@@ -7,31 +7,13 @@ 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 uint32_t *kpage_dir;
#define PAGE_SIZE 4096
#define PAGE_PRESENT 0x1 uint32_t setup_tmp_pgdir(uint32_t magic, uint32_t info)
#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; int n, pd;
unsigned int addr, memksize; uint32_t pagedir_address, memksize;
unsigned int *pgtbl; uint32_t *page_table;
struct multiboot_info *mbi; struct multiboot_info *mbi;
if(magic != MULTIBOOT_BOOTLOADER_MAGIC) { if(magic != MULTIBOOT_BOOTLOADER_MAGIC) {
@@ -44,33 +26,41 @@ unsigned int setup_tmp_pgdir(unsigned int magic, unsigned int info)
memksize = 4096; memksize = 4096;
} else { } else {
/* we need to add the first 1MB to memksize */ /* we need to add the first 1MB to memksize */
memksize = (unsigned int)mbi->mem_upper + 1024; memksize = (uint32_t)mbi->mem_upper + 1024;
/* CONFIG_VM_SPLIT22 marks the maximum physical memory supported */
if(memksize > ((0xFFFFFFFF - PAGE_OFFSET) / 1024)) { if(memksize > ((0xFFFFFFFF - PAGE_OFFSET) / 1024)) {
memksize = (0xFFFFFFFF - PAGE_OFFSET) / 1024; memksize = (0xFFFFFFFF - PAGE_OFFSET) / 1024;
} }
} }
} }
addr = PAGE_OFFSET + (memksize * 1024) - memksize; /* address becomes PAGE_OFFSET (0xC0000000) plus the size of memory minus the first page */
addr = PAGE_ALIGN(addr); /* TODO: check if I wrote the comment above correctly*/
pagedir_address = PAGE_OFFSET + (memksize * 1024) - memksize;
pagedir_address = PAGE_ALIGN(pagedir_address);
kpage_dir = (unsigned int *)addr; /*
memory pages:
0 -> page directory
1 -> page table
*/
kpage_dir = (uint32_t *)pagedir_address;
memset(kpage_dir, 0, PAGE_SIZE); memset(kpage_dir, 0, PAGE_SIZE);
addr += PAGE_SIZE; pagedir_address += PAGE_SIZE;
pgtbl = (unsigned int *)addr; page_table = (uint32_t *)pagedir_address;
memset(pgtbl, 0, memksize); memset(page_table, 0, memksize);
for(n = 0; n < memksize / sizeof(unsigned int); n++) { /* if we have 4MB assumed earlier, the memksize will be 4096 and this loop will run while n < 1024 */
pgtbl[n] = (n << PAGE_SHIFT) | PAGE_PRESENT | PAGE_RW; /* so basically 4MB is 1024 pages */
for(n = 0; n < memksize / sizeof(uint32_t); n++) {
page_table[n] = (n << PAGE_SHIFT) | PAGE_PRESENT | PAGE_RW;
if(!(n % 1024)) { if(!(n % 1024)) {
pd = n / 1024; pd = n / 1024;
kpage_dir[pd] = (unsigned int)(addr + (PAGE_SIZE * pd) + GDT_BASE) | PAGE_PRESENT | PAGE_RW; kpage_dir[pd] = (uint32_t)(pagedir_address + (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; kpage_dir[GET_PGDIR(PAGE_OFFSET) + pd] = (uint32_t)(pagedir_address + (PAGE_SIZE * pd) + GDT_BASE) | PAGE_PRESENT | PAGE_RW;
} }
} }
return (unsigned int)kpage_dir - PAGE_OFFSET; return (uint32_t)kpage_dir - PAGE_OFFSET;
} }
void enablePaging() { void enablePaging() {