forked from PoliEcho-holding-org/kern
Changed camelCase to snake_case
This commit is contained in:
@@ -58,6 +58,11 @@ Todos
|
|||||||
- [ ] RAMFS
|
- [ ] RAMFS
|
||||||
- [ ] FAT32
|
- [ ] FAT32
|
||||||
- [ ] DevFS
|
- [ ] DevFS
|
||||||
|
- [ ] /dev/std*
|
||||||
|
- [ ] /dev/tty
|
||||||
|
- [ ] /dev/sd*
|
||||||
|
- [ ] /dev/fb0
|
||||||
|
- [ ] /dev/null, /dev/zero, ...
|
||||||
- [ ] SysFS
|
- [ ] SysFS
|
||||||
- [ ] ProcFS
|
- [ ] ProcFS
|
||||||
|
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ should not be placed after/before unary operators or member access operators.
|
|||||||
Naming
|
Naming
|
||||||
------
|
------
|
||||||
_The hardest thing in programming_
|
_The hardest thing in programming_
|
||||||
Identifiers should use camelCase (starting with lowercase). And may have a
|
Identifiers should use snake_case (starting with lowercase). And should have a
|
||||||
short prefix separated with an underscore (e.g. 'sys_malloc').
|
short prefix to indicate what system they're from (e.g. 'vmm_alloc' & 'pmm_alloc').
|
||||||
|
|
||||||
Global variables (that should be sparse) and global functions need good,
|
Global variables (that should be sparse) and global functions need good,
|
||||||
descriptive names. A disk reading function shouldn't be called 'dskrd()'.
|
descriptive names. A disk reading function shouldn't be called 'dskrd()'.
|
||||||
@@ -69,15 +69,14 @@ should be named 'i' and not loopCounter.
|
|||||||
Some good naming examples:
|
Some good naming examples:
|
||||||
```c
|
```c
|
||||||
// Random good function names
|
// Random good function names
|
||||||
int32_t disk_findFreeBlock(uint32_t count);
|
int32_t disk_find_free_block(uint32_t count);
|
||||||
int32_t tty_write(const void* buf, size_t len);
|
int32_t tty_write(const void* buf, size_t len);
|
||||||
uint8_t getRtcRegister(uint8_t reg);
|
uint8_t get_rtc_register(uint8_t reg);
|
||||||
|
|
||||||
// Serial functions all start with 'serial_'
|
// Serial functions all start with 'serial_'
|
||||||
int serial_init();
|
int serial_init();
|
||||||
void serial_write(uint8_t byte);
|
void serial_write(uint8_t byte);
|
||||||
uint8_t serial_read();
|
uint8_t serial_read();
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Labels, for 'goto' statements or assembly, should be snake_case.
|
Labels, for 'goto' statements or assembly, should be snake_case.
|
||||||
@@ -212,5 +211,5 @@ For example `drivers/fat32.h would have this guard:
|
|||||||
Hex literals
|
Hex literals
|
||||||
************
|
************
|
||||||
Hexadecimal literals are preffered over binary and should be written in uppercase.
|
Hexadecimal literals are preffered over binary and should be written in uppercase.
|
||||||
Example: 0xA1B2
|
Example: 0xA1B2C0DE
|
||||||
|
|
||||||
|
|||||||
@@ -3,18 +3,48 @@ Memory Management
|
|||||||
|
|
||||||
Memory management is split into three layers: physical, virtual & the heap.
|
Memory management is split into three layers: physical, virtual & the heap.
|
||||||
|
|
||||||
|
pmm.h
|
||||||
|
-----
|
||||||
The **physical memory manager** (PMM) is responsible for allocating physical
|
The **physical memory manager** (PMM) is responsible for allocating physical
|
||||||
memory. It gives `pmm_*` functions. The `pmm_allocPage()` function allocates a
|
memory. It gives `pmm_*` functions. The `pmm_allocPage()` function allocates a
|
||||||
4kB page frame and retuns its **physical address**.
|
4kB page frame and retuns its **physical address**.
|
||||||
|
|
||||||
|
vmm.h
|
||||||
|
-----
|
||||||
The **virtual memory manager** (VMM) is responsible for allocating virtual
|
The **virtual memory manager** (VMM) is responsible for allocating virtual
|
||||||
memory. It provides `vmm_*` functions. The `vmm_alloc()` function takes in a
|
memory. It provides `vmm_*` functions. The `vmm_alloc()` function takes in a
|
||||||
number of 4kB pages to allocate and returns the **virtual address** of the
|
number of 4kB pages to allocate and returns the **virtual address** of the
|
||||||
first page. Userspace can interface with the VMM using the `mmap()` and
|
first page. Userspace can interface with the VMM using the `mmap()` and
|
||||||
`munmap()` syscalls.
|
`munmap()` syscalls.
|
||||||
|
|
||||||
**The heap** is an area of memory that both kernel and user space have.
|
kmalloc.h
|
||||||
Kernel space uses the `kalloc()` and it's derivative functions for the heap.
|
---------
|
||||||
User space may use the `brk()` and `sbrk()` syscalls to grow and shrink the
|
The `kmalloc.h` header provides memory management functions for kernel memory.
|
||||||
heap.
|
|
||||||
|
`void* kmalloc(size_t size)`
|
||||||
|
****************************
|
||||||
|
**Parameters**
|
||||||
|
* `size_t size` - Number of bytes to allocate
|
||||||
|
|
||||||
|
**Descriptions**
|
||||||
|
This function allocates `size` bytes of contiguous memory.
|
||||||
|
|
||||||
|
**Returns**
|
||||||
|
A pointer to allocated memory or NULL.
|
||||||
|
|
||||||
|
`void* kzalloc(size_t size)`
|
||||||
|
****************************
|
||||||
|
**Parameters**
|
||||||
|
* `size_t size` - Number of bytes to allocate
|
||||||
|
|
||||||
|
**Description**
|
||||||
|
This function allocates `size` bytes of contiguous, zeroed-out memory.
|
||||||
|
|
||||||
|
**Returns**
|
||||||
|
A pointer to allocated memory or NULL.
|
||||||
|
|
||||||
|
`void* kcalloc(size_t count, size_t size)`
|
||||||
|
******************************************
|
||||||
|
**Parameters**
|
||||||
|
* `size_t count` -
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ typedef struct bitmap_t {
|
|||||||
void* bmap_ptr(bitmap_t* map, size_t bit);
|
void* bmap_ptr(bitmap_t* map, size_t bit);
|
||||||
void bmap_set(bitmap_t* map, size_t bit, int val);
|
void bmap_set(bitmap_t* map, size_t bit, int val);
|
||||||
int bmap_get(bitmap_t* map, size_t bit);
|
int bmap_get(bitmap_t* map, size_t bit);
|
||||||
void bmap_setarea(bitmap_t* map, size_t base, size_t len, int val);
|
void bmap_set_area(bitmap_t* map, size_t base, size_t len, int val);
|
||||||
void bmap_setall(bitmap_t* map, int val);
|
size_t bmap_get_area(bitmap_t* map, size_t len, int val);
|
||||||
size_t bmap_findarea(bitmap_t* map, size_t len, int val);
|
void bmap_set_all(bitmap_t* map, int val);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+14
-14
@@ -29,20 +29,20 @@ struct boot_memmap {
|
|||||||
* Some values may not be provided by the bootloader, in this case
|
* Some values may not be provided by the bootloader, in this case
|
||||||
* pointers will be NULL and integer values will be 0 if applicable.
|
* pointers will be NULL and integer values will be 0 if applicable.
|
||||||
* Some unprovided values may also be implied. Eg.:
|
* Some unprovided values may also be implied. Eg.:
|
||||||
* If 'memmap = NULL' then 'memmapLen' doesn't matter.
|
* If 'memmap = NULL' then 'memmap_size' doesn't matter.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
struct boot_info {
|
struct boot_info {
|
||||||
uint32_t memLower;
|
uint32_t mem_lower;
|
||||||
uint32_t memUpper;
|
uint32_t mem_upper;
|
||||||
uint8_t bootDrive;
|
uint8_t boot_drive;
|
||||||
uint8_t bootPart1;
|
uint8_t boot_part1;
|
||||||
uint8_t bootPart2;
|
uint8_t boot_part2;
|
||||||
uint8_t bootPart3;
|
uint8_t boot_part3;
|
||||||
char* cmdline;
|
struct boot_memmap* memmap;
|
||||||
struct boot_memmap* memmap;
|
size_t memmap_size;
|
||||||
size_t memmapLen;
|
char* cmdline;
|
||||||
char* bootname;
|
char* bootname;
|
||||||
} __packed;
|
} __packed;
|
||||||
extern struct boot_info bootloader;
|
extern struct boot_info bootloader;
|
||||||
|
|
||||||
@@ -53,9 +53,9 @@ extern struct boot_info bootloader;
|
|||||||
*/
|
*/
|
||||||
int boot_init(int type, ...);
|
int boot_init(int type, ...);
|
||||||
|
|
||||||
int boot_initMB1(void* ptr, uint32_t magic);
|
int boot_init_mb1(void* ptr, uint32_t magic);
|
||||||
// TODO:
|
// TODO:
|
||||||
// int boot_initMB2(...);
|
// int boot_init_mb2(...);
|
||||||
// int boot_initLimine(...);
|
// int boot_init_limine(...);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -48,20 +48,20 @@
|
|||||||
|
|
||||||
#define GDT_DESC(_lim, _base, _acc, _flag) (struct gdt_entry){\
|
#define GDT_DESC(_lim, _base, _acc, _flag) (struct gdt_entry){\
|
||||||
.limit = (_lim) & 0xffff,\
|
.limit = (_lim) & 0xffff,\
|
||||||
.baseLow = (uint16_t)(_base),\
|
.base_low = (uint16_t)(_base),\
|
||||||
.baseMid = (uint8_t)((_base) >> 16),\
|
.base_mid = (uint8_t)((_base) >> 16),\
|
||||||
.access = (_acc),\
|
.access = (_acc),\
|
||||||
.flags = ((_flag & 0x0f) << 4) | (((_lim) >> 16) & 0x0f),\
|
.flags = ((_flag & 0x0f) << 4) | (((_lim) >> 16) & 0x0f),\
|
||||||
.baseHigh = (uint8_t)((_base) >> 24),\
|
.base_high = (uint8_t)((_base) >> 24),\
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gdt_entry {
|
struct gdt_entry {
|
||||||
uint16_t limit;
|
uint16_t limit;
|
||||||
uint16_t baseLow;
|
uint16_t base_low;
|
||||||
uint8_t baseMid;
|
uint8_t base_mid;
|
||||||
uint8_t access;
|
uint8_t access;
|
||||||
uint8_t flags; // low 4 bits are 4 msbs of limit, high 4 bits are flags
|
uint8_t flags; // low 4 bits are 4 msbs of limit, high 4 bits are flags
|
||||||
uint8_t baseHigh;
|
uint8_t base_high;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
struct gdt_pointer {
|
struct gdt_pointer {
|
||||||
|
|||||||
@@ -9,11 +9,11 @@
|
|||||||
#define IDT_FLAG_USER 0xee // P = 1, Priv = 11, S = 0, Type = 1110 (32-bit int)
|
#define IDT_FLAG_USER 0xee // P = 1, Priv = 11, S = 0, Type = 1110 (32-bit int)
|
||||||
|
|
||||||
struct idt_entry {
|
struct idt_entry {
|
||||||
uint16_t offsetLow;
|
uint16_t offset_low;
|
||||||
uint16_t selector;
|
uint16_t selector;
|
||||||
uint8_t __unused;
|
uint8_t __unused;
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
uint16_t offsetHigh;
|
uint16_t offset_high;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
struct idt_pointer {
|
struct idt_pointer {
|
||||||
@@ -22,6 +22,6 @@ struct idt_pointer {
|
|||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
int idt_init(void);
|
int idt_init(void);
|
||||||
void idt_setGate(uint8_t i, void* handler, uint8_t flags);
|
void idt_set_gate(uint8_t i, void* handler, uint8_t flags);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
|
|
||||||
// Interrupt frame (ie. what's on the stack on interrupt)
|
// Interrupt frame (ie. what's on the stack on interrupt)
|
||||||
struct isr_intFrame {
|
struct isr_int_frame {
|
||||||
// Pushed by OS
|
// Pushed by OS
|
||||||
uint32_t esp, ebx, ecx, edx, esi, edi, ebp;
|
uint32_t esp, ebx, ecx, edx, esi, edi, ebp;
|
||||||
uint32_t ds, es, fs, gs, eax;
|
uint32_t ds, es, fs, gs, eax;
|
||||||
@@ -13,14 +13,14 @@ struct isr_intFrame {
|
|||||||
// Pushed by CPU
|
// Pushed by CPU
|
||||||
uint32_t eip, cs, eflags, user_esp, user_ss;
|
uint32_t eip, cs, eflags, user_esp, user_ss;
|
||||||
};
|
};
|
||||||
typedef void (*isr_handlerPtr)(struct isr_intFrame* iframe);
|
typedef void (*isr_handler_ptr)(struct isr_int_frame* iframe);
|
||||||
|
|
||||||
int isr_init(void);
|
int isr_init(void);
|
||||||
void isr_registerIRQ(uint8_t i, isr_handlerPtr handler);
|
void isr_register_IRQ(uint8_t i, isr_handler_ptr handler);
|
||||||
int isr_handleInterrupt(struct isr_intFrame iframe);
|
int isr_handle_interrupt(struct isr_int_frame iframe);
|
||||||
|
|
||||||
// Assembly definitions (isr.s)
|
// Assembly definitions (isr.s)
|
||||||
extern void* isr_redirectTable[48]; // ISR Table
|
extern void* isr_redirect_table[48]; // ISR Table
|
||||||
extern void isr128(); // int 0x80 - syscall
|
extern void isr128(); // int 0x80 - syscall
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ typedef char* va_list;
|
|||||||
#define ceil(_x, _y) ((((_x) + (_y)) (_y)) * (_y))
|
#define ceil(_x, _y) ((((_x) + (_y)) (_y)) * (_y))
|
||||||
#define floor(_x, _y) ((_x) - ((_x) % (_y)))
|
#define floor(_x, _y) ((_x) - ((_x) % (_y)))
|
||||||
#define dceil(_x, _y) (((_x) + (_y) - 1) / (_y))
|
#define dceil(_x, _y) (((_x) + (_y) - 1) / (_y))
|
||||||
|
#define fence() __asm__ volatile ("":::"memory")
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Attribute definitions
|
* Attribute definitions
|
||||||
@@ -98,7 +99,7 @@ extern uint32_t __kernel_stack_top, __kernel_stack_bottom;
|
|||||||
#define pr_wrn(_s) printk("[warning] %s\n", (_s))
|
#define pr_wrn(_s) printk("[warning] %s\n", (_s))
|
||||||
#define pr_err(_s) printk("[error] %s\n", (_s))
|
#define pr_err(_s) printk("[error] %s\n", (_s))
|
||||||
#define panic(_s) do {\
|
#define panic(_s) do {\
|
||||||
printk("[kernel] Panic! %s\n", (_s));\
|
printk("[kernel] Panic! %s", (_s));\
|
||||||
while (1) __asm__ volatile ("cli; hlt");\
|
while (1) __asm__ volatile ("cli; hlt");\
|
||||||
} while (0)
|
} while (0)
|
||||||
#define BUG() panic("BUG()")
|
#define BUG() panic("BUG()")
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#ifndef _KMALLOC_H
|
||||||
|
#define _KMALLOC_H
|
||||||
|
|
||||||
|
void* kmalloc(size_t size);
|
||||||
|
void* kzalloc(size_t size);
|
||||||
|
void* kcalloc(size_t count, size_t size);
|
||||||
|
void kfree(void* ptr);
|
||||||
|
|
||||||
|
#endif
|
||||||
+11
-11
@@ -24,18 +24,18 @@
|
|||||||
#define PAGE_FLAG_OWNER (1 << 9)
|
#define PAGE_FLAG_OWNER (1 << 9)
|
||||||
|
|
||||||
extern uint32_t init_pagedir[1024]; // Defined in entry.s for initial paging
|
extern uint32_t init_pagedir[1024]; // Defined in entry.s for initial paging
|
||||||
extern size_t pag_pageCount;
|
extern size_t pag_page_count;
|
||||||
|
|
||||||
int pag_init(void);
|
int pag_init(void);
|
||||||
void pag_registerTempFrame(uint32_t target);
|
void pag_register_temp_frame(uint32_t target);
|
||||||
uint32_t pag_tempFrame(void);
|
uint32_t pag_temp_frame(void);
|
||||||
void pag_mapPage(uint32_t vaddr, uint32_t paddr, uint32_t flags);
|
void pag_map(uint32_t vaddr, uint32_t paddr, uint32_t flags);
|
||||||
uint32_t pag_umapPage(uint32_t vaddr);
|
uint32_t pag_umap(uint32_t vaddr);
|
||||||
void* pag_virtToPhys(uint32_t vaddr);
|
void* pag_virt_to_phys(uint32_t vaddr);
|
||||||
uint32_t* pag_getPagedir();
|
uint32_t* pag_get_pagedir();
|
||||||
void pag_setPagedir(uint32_t* pagedir);
|
void pag_set_pagedir(uint32_t* pagedir);
|
||||||
void pag_syncPagedir();
|
void pag_sync_pagedir();
|
||||||
uint32_t* pag_allocPagedir();
|
uint32_t* pag_alloc_pagedir();
|
||||||
void pag_freePagedir(uint32_t* pagedir);
|
void pag_free_pagedir(uint32_t* pagedir);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
extern bitmap_t pmm_bitmap;
|
extern bitmap_t pmm_bitmap;
|
||||||
|
|
||||||
int pmm_init(void);
|
int pmm_init(void);
|
||||||
void* pmm_allocPage(void);
|
void* pmm_alloc(void);
|
||||||
void pmm_freePage(void* page);
|
void pmm_free(void* page);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
|
|
||||||
#include <isr.h>
|
#include <isr.h>
|
||||||
|
|
||||||
int syscallHandler(struct isr_intFrame* iframe) { return 1; }
|
int syscall_handler(struct isr_int_frame* iframe) { (void)iframe; return 1; }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -9,9 +9,9 @@
|
|||||||
|
|
||||||
int tty_init(void);
|
int tty_init(void);
|
||||||
void tty_clear(void);
|
void tty_clear(void);
|
||||||
void tty_setattr(uint8_t attr);
|
void tty_set_attr(uint8_t attr);
|
||||||
void tty_enableCursor(uint8_t start, uint8_t end);
|
void tty_show_cursor(uint8_t start, uint8_t end);
|
||||||
void tty_disableCursor(void);
|
void tty_hide_cursor(void);
|
||||||
void tty_write(char* buf, size_t len);
|
void tty_write(char* buf, size_t len);
|
||||||
void tty_putc(char c);
|
void tty_putc(char c);
|
||||||
void tty_puts(char* s);
|
void tty_puts(char* s);
|
||||||
|
|||||||
+9
-9
@@ -19,21 +19,14 @@ int bmap_get(bitmap_t* map, size_t bit) {
|
|||||||
return (p[bit / 32] & (1 << (bit % 32))) ? 1 : 0;
|
return (p[bit / 32] & (1 << (bit % 32))) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bmap_setarea(bitmap_t* map, size_t base, size_t len, int val) {
|
void bmap_set_area(bitmap_t* map, size_t base, size_t len, int val) {
|
||||||
uint32_t align = dceil(base, BLOCK_SIZE);
|
uint32_t align = dceil(base, BLOCK_SIZE);
|
||||||
uint32_t count = dceil(len, BLOCK_SIZE);
|
uint32_t count = dceil(len, BLOCK_SIZE);
|
||||||
|
|
||||||
while (count-- > 0) bmap_set(map, align++, val);
|
while (count-- > 0) bmap_set(map, align++, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bmap_setall(bitmap_t* map, int val) {
|
size_t bmap_get_area(bitmap_t* map, size_t len, int val) {
|
||||||
uint8_t b = (val) ? 0xff : 0;
|
|
||||||
for (size_t i = 0; i < map->bytes; i++) ((uint8_t*)map->map)[i] = b;
|
|
||||||
if (val) map->used = map->blocks;
|
|
||||||
else map->used = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t bmap_findarea(bitmap_t* map, size_t len, int val) {
|
|
||||||
if (len == 0) return BMAP_NOT_FOUND;
|
if (len == 0) return BMAP_NOT_FOUND;
|
||||||
|
|
||||||
uint32_t found = 0;
|
uint32_t found = 0;
|
||||||
@@ -47,3 +40,10 @@ size_t bmap_findarea(bitmap_t* map, size_t len, int val) {
|
|||||||
return BMAP_NOT_FOUND;
|
return BMAP_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bmap_set_all(bitmap_t* map, int val) {
|
||||||
|
uint8_t b = (val) ? 0xff : 0;
|
||||||
|
for (size_t i = 0; i < map->bytes; i++) ((uint8_t*)map->map)[i] = b;
|
||||||
|
if (val) map->used = map->blocks;
|
||||||
|
else map->used = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
+20
-10
@@ -8,26 +8,36 @@ struct boot_info bootloader;
|
|||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
int boot_init(int type, ...) {
|
int boot_init(int type, ...) {
|
||||||
|
va_list va;
|
||||||
|
va_start(va, type);
|
||||||
|
|
||||||
|
void* ptr = va_arg(va, void*);
|
||||||
|
uint32_t magic = va_arg(va, uint32_t);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case BOOT_MB1: return boot_init_mb1(ptr, magic);
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int boot_initMB1(void* ptr, uint32_t magic) {
|
int boot_init_mb1(void* ptr, uint32_t magic) {
|
||||||
multiboot_info_t* mbi = ptr;
|
multiboot_info_t* mbi = ptr;
|
||||||
|
|
||||||
if (magic != MULTIBOOT_BOOTLOADER_MAGIC) return 1;
|
if (magic != MULTIBOOT_BOOTLOADER_MAGIC) return 1;
|
||||||
|
|
||||||
// mem_* fields are valid
|
// mem_* fields are valid
|
||||||
if (mbi->flags & MULTIBOOT_INFO_MEMORY) {
|
if (mbi->flags & MULTIBOOT_INFO_MEMORY) {
|
||||||
bootloader.memLower = mbi->mem_lower;
|
bootloader.mem_lower = mbi->mem_lower;
|
||||||
bootloader.memUpper = mbi->mem_upper;
|
bootloader.mem_upper = mbi->mem_upper;
|
||||||
}
|
}
|
||||||
|
|
||||||
// boot_device is valid
|
// boot_device is valid
|
||||||
if (mbi->flags & MULTIBOOT_INFO_BOOTDEV) {
|
if (mbi->flags & MULTIBOOT_INFO_BOOTDEV) {
|
||||||
bootloader.bootDrive = (mbi->boot_device & 0xff000000) >> 24;
|
bootloader.boot_drive = (mbi->boot_device & 0xff000000) >> 24;
|
||||||
bootloader.bootPart1 = (mbi->boot_device & 0x00ff0000) >> 16;
|
bootloader.boot_part1 = (mbi->boot_device & 0x00ff0000) >> 16;
|
||||||
bootloader.bootPart2 = (mbi->boot_device & 0x0000ff00) >> 8;
|
bootloader.boot_part2 = (mbi->boot_device & 0x0000ff00) >> 8;
|
||||||
bootloader.bootPart3 = (mbi->boot_device & 0x000000ff);
|
bootloader.boot_part3 = (mbi->boot_device & 0x000000ff);
|
||||||
}
|
}
|
||||||
|
|
||||||
// cmdline is valid
|
// cmdline is valid
|
||||||
@@ -45,9 +55,9 @@ int boot_initMB1(void* ptr, uint32_t magic) {
|
|||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
multiboot_memory_map_t* entry = (multiboot_memory_map_t*)mbi->mmap_addr;
|
multiboot_memory_map_t* entry = (multiboot_memory_map_t*)mbi->mmap_addr;
|
||||||
uint32_t mapLim = mbi->mmap_addr + mbi->mmap_length;
|
uint32_t limit = mbi->mmap_addr + mbi->mmap_length;
|
||||||
|
|
||||||
while ((uint32_t)entry < mapLim) {
|
while ((uint32_t)entry < limit) {
|
||||||
bootloader.memmap[i].base = entry->addr;
|
bootloader.memmap[i].base = entry->addr;
|
||||||
bootloader.memmap[i].size = entry->len;
|
bootloader.memmap[i].size = entry->len;
|
||||||
bootloader.memmap[i].type = (uint8_t)entry->type;
|
bootloader.memmap[i].type = (uint8_t)entry->type;
|
||||||
@@ -55,7 +65,7 @@ int boot_initMB1(void* ptr, uint32_t magic) {
|
|||||||
entry++;
|
entry++;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
bootloader.memmapLen = i;
|
bootloader.memmap_size = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: drives_*
|
// TODO: drives_*
|
||||||
|
|||||||
+3
-3
@@ -7,14 +7,14 @@ __align(16) // performace :fire:
|
|||||||
static struct idt_entry idt[IDT_ENTRIES];
|
static struct idt_entry idt[IDT_ENTRIES];
|
||||||
static struct idt_pointer idtp;
|
static struct idt_pointer idtp;
|
||||||
|
|
||||||
void idt_setGate(uint8_t i, void* handler, uint8_t flags) {
|
void idt_set_gate(uint8_t i, void* handler, uint8_t flags) {
|
||||||
uint32_t offset = (uint32_t)handler;
|
uint32_t offset = (uint32_t)handler;
|
||||||
struct idt_entry* entry = &idt[i];
|
struct idt_entry* entry = &idt[i];
|
||||||
|
|
||||||
entry->offsetLow = (uint16_t)offset;
|
entry->offset_low = (uint16_t)offset;
|
||||||
entry->selector = GDT_KERNEL_CODE;
|
entry->selector = GDT_KERNEL_CODE;
|
||||||
entry->flags = flags;
|
entry->flags = flags;
|
||||||
entry->offsetHigh = (uint16_t)(offset >> 16);
|
entry->offset_high = (uint16_t)(offset >> 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
int idt_init(void) {
|
int idt_init(void) {
|
||||||
|
|||||||
+13
-13
@@ -5,7 +5,7 @@
|
|||||||
#include <idt.h>
|
#include <idt.h>
|
||||||
#include <isr.h>
|
#include <isr.h>
|
||||||
|
|
||||||
isr_handlerPtr irqHandlers[16];
|
isr_handler_ptr irq_handlers[16];
|
||||||
|
|
||||||
const char* exceptions[] = {
|
const char* exceptions[] = {
|
||||||
"Division By Zero",
|
"Division By Zero",
|
||||||
@@ -43,7 +43,7 @@ const char* exceptions[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// I have no clue how this works or what it does, but it doesn't work without it
|
// I have no clue how this works or what it does, but it doesn't work without it
|
||||||
void isr_remapPIC(void) {
|
void isr_remap_pic(void) {
|
||||||
outb(0x20, 0x11); iowait();
|
outb(0x20, 0x11); iowait();
|
||||||
outb(0xa0, 0x11); iowait();
|
outb(0xa0, 0x11); iowait();
|
||||||
outb(0x21, 0x20); iowait();
|
outb(0x21, 0x20); iowait();
|
||||||
@@ -58,15 +58,15 @@ void isr_remapPIC(void) {
|
|||||||
|
|
||||||
int isr_init(void) {
|
int isr_init(void) {
|
||||||
idt_init();
|
idt_init();
|
||||||
isr_remapPIC();
|
isr_remap_pic();
|
||||||
|
|
||||||
for (int i = 0; i < 48; i++) {
|
for (int i = 0; i < 48; i++) {
|
||||||
// First 32 IRSs are exceptions (traps) and the next 16 are hardware interrupts
|
// First 32 IRSs are exceptions (traps) and the next 16 are hardware interrupts
|
||||||
idt_setGate(i, isr_redirectTable[i], (i < 32) ? IDT_FLAG_TRAP : IDT_FLAG_INT);
|
idt_set_gate(i, isr_redirect_table[i], (i < 32) ? IDT_FLAG_TRAP : IDT_FLAG_INT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// System call (should be callable from userspace)
|
// System call (should be callable from userspace)
|
||||||
idt_setGate(0x80, (void*)(uint32_t)isr128, IDT_FLAG_USER);
|
idt_set_gate(0x80, (void*)(uint32_t)isr128, IDT_FLAG_USER);
|
||||||
|
|
||||||
// Let interrupts interrupt
|
// Let interrupts interrupt
|
||||||
__asm__ volatile ("sti");
|
__asm__ volatile ("sti");
|
||||||
@@ -75,31 +75,31 @@ int isr_init(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void isr_registerIRQ(uint8_t i, isr_handlerPtr handler) {
|
void isr_register_irq(uint8_t i, isr_handler_ptr handler) {
|
||||||
irqHandlers[i] = handler;
|
irq_handlers[i] = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
void isr_sendEOI(uint8_t irq) {
|
void isr_send_eoi(uint8_t irq) {
|
||||||
if (irq >= 8) {
|
if (irq >= 8) {
|
||||||
outb(0xa0, 0x20);
|
outb(0xa0, 0x20);
|
||||||
}
|
}
|
||||||
outb(0x20, 0x20);
|
outb(0x20, 0x20);
|
||||||
}
|
}
|
||||||
|
|
||||||
int isr_handleInterrupt(struct isr_intFrame iframe) {
|
int isr_handle_interrupt(struct isr_int_frame iframe) {
|
||||||
if (iframe.interrupt < 32) {
|
if (iframe.interrupt < 32) {
|
||||||
// ISRs 0-31 - Exceptions
|
// ISRs 0-31 - Exceptions
|
||||||
panic(exceptions[iframe.error]);
|
panic(exceptions[iframe.error]);
|
||||||
} else if (iframe.interrupt >= 32 && iframe.interrupt < 48) {
|
} else if (iframe.interrupt >= 32 && iframe.interrupt < 48) {
|
||||||
// ISRs 32-47 - Hardware interrupts
|
// ISRs 32-47 - Hardware interrupts
|
||||||
uint8_t irq = iframe.interrupt - 32;
|
uint8_t irq = iframe.interrupt - 32;
|
||||||
if (irqHandlers[irq]) {
|
if (irq_handlers[irq]) {
|
||||||
irqHandlers[irq](&iframe);
|
irq_handlers[irq](&iframe);
|
||||||
isr_sendEOI(irq);
|
isr_send_eoi(irq);
|
||||||
}
|
}
|
||||||
} else if (iframe.interrupt == 128) {
|
} else if (iframe.interrupt == 128) {
|
||||||
// ISR 128 - System call
|
// ISR 128 - System call
|
||||||
return syscallHandler(&iframe);
|
return syscall_handler(&iframe);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+5
-5
@@ -2,7 +2,7 @@
|
|||||||
[bits 32]
|
[bits 32]
|
||||||
|
|
||||||
isr_common:
|
isr_common:
|
||||||
;; Push registers to the intFrame_t struct
|
;; Push registers to the int_frame_t struct
|
||||||
push eax
|
push eax
|
||||||
push gs
|
push gs
|
||||||
push fs
|
push fs
|
||||||
@@ -16,8 +16,8 @@ isr_common:
|
|||||||
push ebx
|
push ebx
|
||||||
push esp
|
push esp
|
||||||
|
|
||||||
[extern isr_handleInterrupt]
|
[extern isr_handle_interrupt]
|
||||||
call isr_handleInterrupt
|
call isr_handle_interrupt
|
||||||
isr_return:
|
isr_return:
|
||||||
add esp, 4 ; Keep ESP
|
add esp, 4 ; Keep ESP
|
||||||
pop ebx
|
pop ebx
|
||||||
@@ -109,8 +109,8 @@ isr128:
|
|||||||
jmp isr_common
|
jmp isr_common
|
||||||
|
|
||||||
;; Create table of ISRs
|
;; Create table of ISRs
|
||||||
[global isr_redirectTable]
|
[global isr_redirect_table]
|
||||||
isr_redirectTable:
|
isr_redirect_table:
|
||||||
%assign i 0
|
%assign i 0
|
||||||
%rep 48
|
%rep 48
|
||||||
dd isr%+i
|
dd isr%+i
|
||||||
|
|||||||
+5
-2
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
__noreturn
|
__noreturn
|
||||||
void kmain(void* ptr, uint32_t magic) {
|
void kmain(void* ptr, uint32_t magic) {
|
||||||
if (boot_initMB1(ptr, magic) != 0) panic("Unsupported bootloader.");
|
if (boot_init_mb1(ptr, magic) != 0) panic("Unsupported bootloader.");
|
||||||
|
|
||||||
// Serial console for debugging
|
// Serial console for debugging
|
||||||
if (serial_init(COM1) != 0) panic("Failed to initialize Serial driver.");
|
if (serial_init(COM1) != 0) panic("Failed to initialize Serial driver.");
|
||||||
@@ -30,7 +30,10 @@ void kmain(void* ptr, uint32_t magic) {
|
|||||||
tty_puts("kern.\n\n");
|
tty_puts("kern.\n\n");
|
||||||
|
|
||||||
debugf("[kernel] Basic initialization complete!\n");
|
debugf("[kernel] Basic initialization complete!\n");
|
||||||
|
|
||||||
|
// TODO: Init VFS
|
||||||
|
// TODO:
|
||||||
|
|
||||||
panic("kmain() reached end.");
|
panic("kmain() reached end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+39
-39
@@ -6,10 +6,10 @@
|
|||||||
|
|
||||||
#define PAGE_DIR_COUNT 256
|
#define PAGE_DIR_COUNT 256
|
||||||
static uint32_t pagedirs[PAGE_DIR_COUNT][1024] __align(4096);
|
static uint32_t pagedirs[PAGE_DIR_COUNT][1024] __align(4096);
|
||||||
static uint8_t pagedirUsed[PAGE_DIR_COUNT];
|
static uint8_t pagedir_used[PAGE_DIR_COUNT];
|
||||||
|
|
||||||
// TODO: Should this be initialized? If so, to what?
|
// TODO: Should this be initialized? If so, to what?
|
||||||
size_t pag_pageCount = 0;
|
size_t pag_page_count = 0;
|
||||||
|
|
||||||
// Invalidates the pagedir entry in the CPUs TLB cache
|
// Invalidates the pagedir entry in the CPUs TLB cache
|
||||||
static inline void invalidate(uint32_t vaddr) {
|
static inline void invalidate(uint32_t vaddr) {
|
||||||
@@ -17,11 +17,11 @@ static inline void invalidate(uint32_t vaddr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Temp paging thing
|
// Temp paging thing
|
||||||
uint32_t tempFrameStart;
|
uint32_t temp_frame_start;
|
||||||
void pag_registerTempFrame(uint32_t target) { tempFrameStart = target; }
|
void pag_register_temp_frame(uint32_t target) { temp_frame_start = target; }
|
||||||
uint32_t pag_tempFrame(void) {
|
uint32_t pag_temp_frame(void) {
|
||||||
uint32_t fin = tempFrameStart;
|
uint32_t fin = temp_frame_start;
|
||||||
tempFrameStart += PAGE_SIZE;
|
temp_frame_start += PAGE_SIZE;
|
||||||
return fin;
|
return fin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,21 +42,21 @@ int pag_init(void) {
|
|||||||
|
|
||||||
// TODO: This sometimes causes a #PF
|
// TODO: This sometimes causes a #PF
|
||||||
memset(pagedirs, 0, PAGE_SIZE * PAGE_DIR_COUNT);
|
memset(pagedirs, 0, PAGE_SIZE * PAGE_DIR_COUNT);
|
||||||
memset(pagedirUsed, 0, PAGE_DIR_COUNT);
|
memset(pagedir_used, 0, PAGE_DIR_COUNT);
|
||||||
|
|
||||||
debugf("[pag] Paging initalized.\n");
|
debugf("[pag] Paging initalized.\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pag_mapPage(uint32_t vaddr, uint32_t paddr, uint32_t flags) {
|
void pag_map(uint32_t vaddr, uint32_t paddr, uint32_t flags) {
|
||||||
// Save the pagedir we were in
|
// Save the pagedir we were in
|
||||||
uint32_t* prevpd = NULL;
|
uint32_t* prevpd = NULL;
|
||||||
|
|
||||||
// Switch to the init pagedir if in kernel memory
|
// Switch to the init pagedir if in kernel memory
|
||||||
if (vaddr >= KERNEL_BASE) {
|
if (vaddr >= KERNEL_BASE) {
|
||||||
prevpd = pag_getPagedir();
|
prevpd = pag_get_pagedir();
|
||||||
if (prevpd != init_pagedir) pag_setPagedir(init_pagedir);
|
if (prevpd != init_pagedir) pag_set_pagedir(init_pagedir);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract indecies
|
// Extract indecies
|
||||||
@@ -68,7 +68,7 @@ void pag_mapPage(uint32_t vaddr, uint32_t paddr, uint32_t flags) {
|
|||||||
|
|
||||||
// Allocate a pagetab if it didn't exist
|
// Allocate a pagetab if it didn't exist
|
||||||
if (!(pagedir[pdi] & PAGE_FLAG_PRESENT)) {
|
if (!(pagedir[pdi] & PAGE_FLAG_PRESENT)) {
|
||||||
uint32_t tabaddr = pmm_bitmap.ready ? (uint32_t)pmm_allocPage() : pag_tempFrame();
|
uint32_t tabaddr = pmm_bitmap.ready ? (uint32_t)pmm_alloc() : pag_temp_frame();
|
||||||
|
|
||||||
pagedir[pdi] = tabaddr |
|
pagedir[pdi] = tabaddr |
|
||||||
PAGE_FLAG_PRESENT | PAGE_FLAG_WRITE | PAGE_FLAG_OWNER | flags;
|
PAGE_FLAG_PRESENT | PAGE_FLAG_WRITE | PAGE_FLAG_OWNER | flags;
|
||||||
@@ -83,23 +83,23 @@ void pag_mapPage(uint32_t vaddr, uint32_t paddr, uint32_t flags) {
|
|||||||
|
|
||||||
// The actuall mapping
|
// The actuall mapping
|
||||||
pagetab[pti] = paddr | PAGE_FLAG_PRESENT | flags;
|
pagetab[pti] = paddr | PAGE_FLAG_PRESENT | flags;
|
||||||
pag_pageCount++;
|
pag_page_count++;
|
||||||
invalidate(vaddr);
|
invalidate(vaddr);
|
||||||
|
|
||||||
// Do we need to return to the original pagedir?
|
// Do we need to return to the original pagedir?
|
||||||
if (prevpd != NULL) {
|
if (prevpd != NULL) {
|
||||||
pag_syncPagedir(); // Sync it to other pagedirs
|
pag_sync_pagedir(); // Sync it to other pagedirs
|
||||||
if (prevpd != init_pagedir) pag_setPagedir(prevpd);
|
if (prevpd != init_pagedir) pag_set_pagedir(prevpd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t pag_umapPage(uint32_t vaddr) {
|
uint32_t pag_umap(uint32_t vaddr) {
|
||||||
// Same saving as in pag_mapPage()
|
// Same saving as in pag_map()
|
||||||
uint32_t* prevpd = NULL;
|
uint32_t* prevpd = NULL;
|
||||||
|
|
||||||
if (vaddr >= KERNEL_BASE) {
|
if (vaddr >= KERNEL_BASE) {
|
||||||
prevpd = pag_getPagedir();
|
prevpd = pag_get_pagedir();
|
||||||
if (prevpd != init_pagedir) pag_setPagedir(init_pagedir);
|
if (prevpd != init_pagedir) pag_set_pagedir(init_pagedir);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract indecies
|
// Extract indecies
|
||||||
@@ -111,7 +111,7 @@ uint32_t pag_umapPage(uint32_t vaddr) {
|
|||||||
|
|
||||||
uint32_t pte = pagetab[pti];
|
uint32_t pte = pagetab[pti];
|
||||||
pagetab[pti] = 0;
|
pagetab[pti] = 0;
|
||||||
pag_pageCount--;
|
pag_page_count--;
|
||||||
|
|
||||||
// Look if we can free the pagetab
|
// Look if we can free the pagetab
|
||||||
int remove = 1;
|
int remove = 1;
|
||||||
@@ -125,24 +125,24 @@ uint32_t pag_umapPage(uint32_t vaddr) {
|
|||||||
uint32_t pde = pagedir[pdi];
|
uint32_t pde = pagedir[pdi];
|
||||||
if (remove && pde & PAGE_FLAG_OWNER) {
|
if (remove && pde & PAGE_FLAG_OWNER) {
|
||||||
uint32_t tabaddr = PHYS_ADDR(pde);
|
uint32_t tabaddr = PHYS_ADDR(pde);
|
||||||
pmm_freePage((void*)tabaddr);
|
pmm_free((void*)tabaddr);
|
||||||
pagedir[pdi] = 0;
|
pagedir[pdi] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
invalidate(vaddr);
|
invalidate(vaddr);
|
||||||
|
|
||||||
// Free the page frame
|
// Free the page frame
|
||||||
if (pte & PAGE_FLAG_OWNER) pmm_freePage((void*)PHYS_ADDR(pte));
|
if (pte & PAGE_FLAG_OWNER) pmm_free((void*)PHYS_ADDR(pte));
|
||||||
|
|
||||||
if (prevpd != NULL) {
|
if (prevpd != NULL) {
|
||||||
pag_syncPagedir(); // Sync it to other pagedirs
|
pag_sync_pagedir(); // Sync it to other pagedirs
|
||||||
if (prevpd != init_pagedir) pag_setPagedir(prevpd);
|
if (prevpd != init_pagedir) pag_set_pagedir(prevpd);
|
||||||
}
|
}
|
||||||
|
|
||||||
return pte;
|
return pte;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* pag_virtToPhys(uint32_t vaddr) {
|
void* pag_virt_to_phys(uint32_t vaddr) {
|
||||||
uint32_t pdi = vaddr >> 22;
|
uint32_t pdi = vaddr >> 22;
|
||||||
uint32_t pti = vaddr >> 12 & 0x3FF;
|
uint32_t pti = vaddr >> 12 & 0x3FF;
|
||||||
|
|
||||||
@@ -151,14 +151,14 @@ void* pag_virtToPhys(uint32_t vaddr) {
|
|||||||
return (void*)((pagetab[pti] & ~0xFFF) + ((uint32_t)vaddr & 0xFFF));
|
return (void*)((pagetab[pti] & ~0xFFF) + ((uint32_t)vaddr & 0xFFF));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t* pag_getPagedir() {
|
uint32_t* pag_get_pagedir() {
|
||||||
uint32_t pagedir;
|
uint32_t pagedir;
|
||||||
__asm__ volatile ("mov %%cr3, %0" : "=r"(pagedir));
|
__asm__ volatile ("mov %%cr3, %0" : "=r"(pagedir));
|
||||||
pagedir += KERNEL_BASE;
|
pagedir += KERNEL_BASE;
|
||||||
return (uint32_t*)pagedir;
|
return (uint32_t*)pagedir;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pag_setPagedir(uint32_t* pagedir) {
|
void pag_set_pagedir(uint32_t* pagedir) {
|
||||||
pagedir = (uint32_t*)((uint32_t)pagedir - KERNEL_BASE);
|
pagedir = (uint32_t*)((uint32_t)pagedir - KERNEL_BASE);
|
||||||
__asm__ volatile (
|
__asm__ volatile (
|
||||||
"mov %0, %%eax\n"
|
"mov %0, %%eax\n"
|
||||||
@@ -167,9 +167,9 @@ void pag_setPagedir(uint32_t* pagedir) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pag_syncPagedir() {
|
void pag_sync_pagedir() {
|
||||||
for (size_t i = 0; i < PAGE_DIR_COUNT; i++) {
|
for (size_t i = 0; i < PAGE_DIR_COUNT; i++) {
|
||||||
if (!pagedirUsed[i]) continue;
|
if (!pagedir_used[i]) continue;
|
||||||
|
|
||||||
uint32_t* pagedir = pagedirs[i];
|
uint32_t* pagedir = pagedirs[i];
|
||||||
|
|
||||||
@@ -181,11 +181,11 @@ void pag_syncPagedir() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t* pag_allocPagedir() {
|
uint32_t* pag_alloc_pagedir() {
|
||||||
// Find the first unused page
|
// Find the first unused page
|
||||||
for (size_t i = 0; i < PAGE_DIR_COUNT; i++) {
|
for (size_t i = 0; i < PAGE_DIR_COUNT; i++) {
|
||||||
if (pagedirUsed[i]) continue;
|
if (pagedir_used[i]) continue;
|
||||||
pagedirUsed[i] = 1;
|
pagedir_used[i] = 1;
|
||||||
|
|
||||||
uint32_t* pagedir = pagedirs[i];
|
uint32_t* pagedir = pagedirs[i];
|
||||||
memset(pagedir, 0, PAGE_SIZE);
|
memset(pagedir, 0, PAGE_SIZE);
|
||||||
@@ -207,9 +207,9 @@ uint32_t* pag_allocPagedir() {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pag_freePagedir(uint32_t* pagedir) {
|
void pag_free_pagedir(uint32_t* pagedir) {
|
||||||
uint32_t* prevpd = pag_getPagedir();
|
uint32_t* prevpd = pag_get_pagedir();
|
||||||
pag_setPagedir(pagedir);
|
pag_set_pagedir(pagedir);
|
||||||
|
|
||||||
uint32_t pdi = (uint32_t)pagedir - (uint32_t)pagedirs;
|
uint32_t pdi = (uint32_t)pagedir - (uint32_t)pagedirs;
|
||||||
pdi /= PAGE_SIZE;
|
pdi /= PAGE_SIZE;
|
||||||
@@ -224,15 +224,15 @@ void pag_freePagedir(uint32_t* pagedir) {
|
|||||||
for (size_t j = 0; j < 1024; j++) {
|
for (size_t j = 0; j < 1024; j++) {
|
||||||
uint32_t pte = pagetab[j];
|
uint32_t pte = pagetab[j];
|
||||||
|
|
||||||
if (pte & PAGE_FLAG_OWNER) pmm_freePage((void*)PHYS_ADDR(pte));
|
if (pte & PAGE_FLAG_OWNER) pmm_free((void*)PHYS_ADDR(pte));
|
||||||
}
|
}
|
||||||
memset(pagetab, 0, PAGE_SIZE);
|
memset(pagetab, 0, PAGE_SIZE);
|
||||||
|
|
||||||
if (pde & PAGE_FLAG_OWNER) pmm_freePage((void*)PHYS_ADDR(pde));
|
if (pde & PAGE_FLAG_OWNER) pmm_free((void*)PHYS_ADDR(pde));
|
||||||
pd[i] = 0;
|
pd[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pagedirUsed[pdi] = 0;
|
pagedir_used[pdi] = 0;
|
||||||
pag_setPagedir(prevpd);
|
pag_set_pagedir(prevpd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+20
-20
@@ -20,7 +20,7 @@ int pmm_init(void) {
|
|||||||
// Find enough space for the bitmap
|
// Find enough space for the bitmap
|
||||||
struct boot_memmap* mmap;
|
struct boot_memmap* mmap;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
for (size_t i = 0; i < bootloader.memmapLen; i++) {
|
for (size_t i = 0; i < bootloader.memmap_size; i++) {
|
||||||
mmap = &bootloader.memmap[i];
|
mmap = &bootloader.memmap[i];
|
||||||
|
|
||||||
if (mmap->type == BOOT_MMAP_AVAILABLE && mmap->size >= pmm_bitmap.bytes) {
|
if (mmap->type == BOOT_MMAP_AVAILABLE && mmap->size >= pmm_bitmap.bytes) {
|
||||||
@@ -30,31 +30,31 @@ int pmm_init(void) {
|
|||||||
}
|
}
|
||||||
if (!found) return 1; // Not enough memory
|
if (!found) return 1; // Not enough memory
|
||||||
|
|
||||||
uint32_t pageFrameStart = mmap->base;
|
uint32_t page_frame_start = mmap->base;
|
||||||
pag_registerTempFrame(pageFrameStart);
|
pag_register_temp_frame(page_frame_start);
|
||||||
mmap->base += ptcount * PAGE_SIZE;
|
mmap->base += ptcount * PAGE_SIZE;
|
||||||
|
|
||||||
uint32_t bitmapStart = KERNEL_HEAP_BASE - dceil(pmm_bitmap.bytes, PAGE_SIZE) * PAGE_SIZE;
|
uint32_t bitmap_start = KERNEL_HEAP_BASE - dceil(pmm_bitmap.bytes, PAGE_SIZE) * PAGE_SIZE;
|
||||||
uint32_t bitmapStartPhys = mmap->base;
|
uint32_t bitmap_start_phys = mmap->base;
|
||||||
pmm_bitmap.map = (void*)bitmapStart;
|
pmm_bitmap.map = (void*)bitmap_start;
|
||||||
|
|
||||||
size_t pagecount = dceil(pmm_bitmap.bytes, PAGE_SIZE);
|
size_t page_count = dceil(pmm_bitmap.bytes, PAGE_SIZE);
|
||||||
for (size_t i = 0; i < pagecount; i++) {
|
for (size_t i = 0; i < page_count; i++) {
|
||||||
// NOTE: We can't unmap this with pag_umapPage(), it's in a tempFrame
|
// NOTE: We can't unmap this with pag_umap(), it's in a tempFrame
|
||||||
pag_mapPage(bitmapStart + i * PAGE_SIZE, mmap->base + i * PAGE_SIZE, 0);
|
pag_map(bitmap_start + i * PAGE_SIZE, mmap->base + i * PAGE_SIZE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set all blocks as used
|
// Set all blocks as used
|
||||||
bmap_setall(&pmm_bitmap, 1);
|
bmap_set_all(&pmm_bitmap, 1);
|
||||||
|
|
||||||
debugf("[pmm] Memory map:\n"); // Use the loop to also print the memmap
|
debugf("[pmm] Memory map:\n"); // Use the loop to also print the memmap
|
||||||
|
|
||||||
for (size_t i = 0; i < bootloader.memmapLen; i++) {
|
for (size_t i = 0; i < bootloader.memmap_size; i++) {
|
||||||
mmap = &bootloader.memmap[i];
|
mmap = &bootloader.memmap[i];
|
||||||
if (mmap->size == 0) continue; // Ignore dummy entries
|
if (mmap->size == 0) continue; // Ignore dummy entries
|
||||||
|
|
||||||
if (mmap->type == BOOT_MMAP_AVAILABLE) {
|
if (mmap->type == BOOT_MMAP_AVAILABLE) {
|
||||||
bmap_setarea(&pmm_bitmap, mmap->base, mmap->size, 0);
|
bmap_set_area(&pmm_bitmap, mmap->base, mmap->size, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print entry
|
// Print entry
|
||||||
@@ -63,8 +63,8 @@ int pmm_init(void) {
|
|||||||
(mmap->type == BOOT_MMAP_AVAILABLE) ? "AVAILABLE" : "RESERVED");
|
(mmap->type == BOOT_MMAP_AVAILABLE) ? "AVAILABLE" : "RESERVED");
|
||||||
}
|
}
|
||||||
|
|
||||||
bmap_setarea(&pmm_bitmap, bitmapStartPhys, pmm_bitmap.bytes, 1);
|
bmap_set_area(&pmm_bitmap, bitmap_start_phys, pmm_bitmap.bytes, 1);
|
||||||
bmap_setarea(&pmm_bitmap, pageFrameStart, ptcount * PAGE_SIZE, 1);
|
bmap_set_area(&pmm_bitmap, page_frame_start, ptcount * PAGE_SIZE, 1);
|
||||||
|
|
||||||
bmap_set(&pmm_bitmap, 0, 1); // Reserve block 0 - NULL page
|
bmap_set(&pmm_bitmap, 0, 1); // Reserve block 0 - NULL page
|
||||||
|
|
||||||
@@ -76,17 +76,17 @@ int pmm_init(void) {
|
|||||||
"\tBitmap is %d bytes contained in %d pages\n",
|
"\tBitmap is %d bytes contained in %d pages\n",
|
||||||
pmm_bitmap.blocks - pmm_bitmap.used,
|
pmm_bitmap.blocks - pmm_bitmap.used,
|
||||||
(pmm_bitmap.blocks - pmm_bitmap.used) * BLOCK_SIZE,
|
(pmm_bitmap.blocks - pmm_bitmap.used) * BLOCK_SIZE,
|
||||||
bitmapStartPhys, bitmapStart, pmm_bitmap.bytes, pagecount
|
bitmap_start_phys, bitmap_start, pmm_bitmap.bytes, page_count
|
||||||
);
|
);
|
||||||
|
|
||||||
pmm_bitmap.ready = 1;
|
pmm_bitmap.ready = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* pmm_allocPage(void) {
|
void* pmm_alloc(void) {
|
||||||
if (pmm_bitmap.blocks - pmm_bitmap.used == 0) return NULL;
|
if (pmm_bitmap.blocks - pmm_bitmap.used == 0) return NULL;
|
||||||
|
|
||||||
size_t base = bmap_findarea(&pmm_bitmap, 1, 0);
|
size_t base = bmap_get_area(&pmm_bitmap, 1, 0);
|
||||||
if (base == BMAP_NOT_FOUND) return NULL;
|
if (base == BMAP_NOT_FOUND) return NULL;
|
||||||
|
|
||||||
bmap_set(&pmm_bitmap, base, 1);
|
bmap_set(&pmm_bitmap, base, 1);
|
||||||
@@ -94,9 +94,9 @@ void* pmm_allocPage(void) {
|
|||||||
return bmap_ptr(&pmm_bitmap, base);
|
return bmap_ptr(&pmm_bitmap, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pmm_freePage(void* page) {
|
void pmm_free(void* page) {
|
||||||
size_t base = (size_t)page / BLOCK_SIZE;
|
size_t base = (size_t)page / BLOCK_SIZE;
|
||||||
bmap_setarea(&pmm_bitmap, base, 1, 0);
|
bmap_set_area(&pmm_bitmap, base, 1, 0);
|
||||||
bmap_set(&pmm_bitmap, 0, 1);
|
bmap_set(&pmm_bitmap, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+39
-35
@@ -4,24 +4,28 @@
|
|||||||
#include <tty.h>
|
#include <tty.h>
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
size_t row;
|
size_t row;
|
||||||
size_t col;
|
size_t col;
|
||||||
uint8_t attr;
|
uint8_t attr;
|
||||||
uint8_t* buf;
|
uint8_t* buf;
|
||||||
size_t updateWait;
|
/*
|
||||||
} ctx;
|
* This is for the tty_update_cursor() function. It makes sure we don't update
|
||||||
|
* the cursor if we don't need to, because it's slow due to I/O port writes.
|
||||||
|
*/
|
||||||
|
size_t update_wait;
|
||||||
|
} tty_ctx;
|
||||||
|
|
||||||
int tty_init(void) {
|
int tty_init(void) {
|
||||||
// Map VGA Text memory to KERNEL_FRAMEBUF
|
// Map VGA Text memory to KERNEL_FRAMEBUF
|
||||||
size_t pagecount = dceil(VGA_WIDTH * VGA_HEIGHT * 2, PAGE_SIZE);
|
size_t page_count = dceil(VGA_WIDTH * VGA_HEIGHT * 2, PAGE_SIZE);
|
||||||
for (size_t i = 0; i < pagecount; i++) {
|
for (size_t i = 0; i < page_count; i++) {
|
||||||
pag_mapPage(KERNEL_FRAMEBUF + i * PAGE_SIZE, VGA_MEMORY + i * PAGE_SIZE, 0);
|
pag_map(KERNEL_FRAMEBUF + i * PAGE_SIZE, VGA_MEMORY + i * PAGE_SIZE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.row = 0;
|
tty_ctx.row = 0;
|
||||||
ctx.col = 0;
|
tty_ctx.col = 0;
|
||||||
ctx.attr = 0x07;
|
tty_ctx.attr = 0x07;
|
||||||
ctx.buf = (uint8_t*)KERNEL_FRAMEBUF;
|
tty_ctx.buf = (uint8_t*)KERNEL_FRAMEBUF;
|
||||||
tty_clear();
|
tty_clear();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -29,34 +33,34 @@ int tty_init(void) {
|
|||||||
|
|
||||||
void tty_clear(void) {
|
void tty_clear(void) {
|
||||||
for (int i = 0; i < VGA_WIDTH * VGA_HEIGHT; i++) {
|
for (int i = 0; i < VGA_WIDTH * VGA_HEIGHT; i++) {
|
||||||
ctx.buf[i * 2] = ' ';
|
tty_ctx.buf[i * 2] = ' ';
|
||||||
ctx.buf[i * 2 + 1] = ctx.attr;
|
tty_ctx.buf[i * 2 + 1] = tty_ctx.attr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tty_setattr(uint8_t attr) {
|
void tty_set_attr(uint8_t attr) {
|
||||||
ctx.attr = attr;
|
tty_ctx.attr = attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tty_enableCursor(uint8_t start, uint8_t end) {
|
void tty_show_cursor(uint8_t start, uint8_t end) {
|
||||||
outb(0x3d4, 0x0a);
|
outb(0x3d4, 0x0a);
|
||||||
outb(0x3d5, (inb(0x3d5) & 0xc0) | start);
|
outb(0x3d5, (inb(0x3d5) & 0xc0) | start);
|
||||||
outb(0x3d4, 0x0b);
|
outb(0x3d4, 0x0b);
|
||||||
outb(0x3d5, (inb(0x3d5) & 0xe0) | end);
|
outb(0x3d5, (inb(0x3d5) & 0xe0) | end);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tty_disableCursor(void) {
|
void tty_hide_cursor(void) {
|
||||||
outb(0x3d4, 0x0a);
|
outb(0x3d4, 0x0a);
|
||||||
outb(0x3d5, 0x20);
|
outb(0x3d5, 0x20);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tty_updateCursor(void) {
|
void tty_update_cursor(void) {
|
||||||
if (ctx.updateWait > 0) {
|
if (tty_ctx.update_wait > 0) {
|
||||||
ctx.updateWait--;
|
tty_ctx.update_wait--;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t pos = ctx.row * VGA_WIDTH + ctx.col;
|
uint16_t pos = tty_ctx.row * VGA_WIDTH + tty_ctx.col;
|
||||||
outb(0x3d4, 0x0f);
|
outb(0x3d4, 0x0f);
|
||||||
outb(0x3d5, (uint8_t)pos);
|
outb(0x3d5, (uint8_t)pos);
|
||||||
outb(0x3d4, 0x0e);
|
outb(0x3d4, 0x0e);
|
||||||
@@ -65,37 +69,37 @@ void tty_updateCursor(void) {
|
|||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
void tty_scroll(void) {
|
void tty_scroll(void) {
|
||||||
ctx.row = 0;
|
tty_ctx.row = 0;
|
||||||
ctx.col = 0;
|
tty_ctx.col = 0;
|
||||||
tty_clear();
|
tty_clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void tty_putat(char c, size_t row, size_t col) {
|
void tty_putat(char c, size_t row, size_t col) {
|
||||||
size_t i = row * VGA_WIDTH + col;
|
size_t i = row * VGA_WIDTH + col;
|
||||||
ctx.buf[i * 2] = c;
|
tty_ctx.buf[i * 2] = c;
|
||||||
ctx.buf[i * 2 + 1] = ctx.attr;
|
tty_ctx.buf[i * 2 + 1] = tty_ctx.attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tty_putc(char c) {
|
void tty_putc(char c) {
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
ctx.col = 0;
|
tty_ctx.col = 0;
|
||||||
ctx.row++;
|
tty_ctx.row++;
|
||||||
goto scroll_check;
|
goto scroll_check;
|
||||||
}
|
}
|
||||||
|
|
||||||
tty_putat(c, ctx.row, ctx.col++);
|
tty_putat(c, tty_ctx.row, tty_ctx.col++);
|
||||||
if (ctx.col >= VGA_WIDTH) {
|
if (tty_ctx.col >= VGA_WIDTH) {
|
||||||
ctx.col = 0;
|
tty_ctx.col = 0;
|
||||||
ctx.row++;
|
tty_ctx.row++;
|
||||||
}
|
}
|
||||||
|
|
||||||
scroll_check:
|
scroll_check:
|
||||||
if (ctx.row >= VGA_HEIGHT) tty_scroll();
|
if (tty_ctx.row >= VGA_HEIGHT) tty_scroll();
|
||||||
tty_updateCursor();
|
tty_update_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void tty_write(char* buf, size_t len) {
|
void tty_write(char* buf, size_t len) {
|
||||||
ctx.updateWait = len - 1;
|
tty_ctx.update_wait = len - 1;
|
||||||
for (size_t i = 0; i < len; i++) tty_putc(buf[i]);
|
for (size_t i = 0; i < len; i++) tty_putc(buf[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-18
@@ -5,8 +5,6 @@
|
|||||||
|
|
||||||
#include <vmm.h>
|
#include <vmm.h>
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
bitmap_t vmm_bitmap;
|
bitmap_t vmm_bitmap;
|
||||||
|
|
||||||
int vmm_init(void) {
|
int vmm_init(void) {
|
||||||
@@ -14,18 +12,18 @@ int vmm_init(void) {
|
|||||||
vmm_bitmap.membase = KERNEL_HEAP_BASE;
|
vmm_bitmap.membase = KERNEL_HEAP_BASE;
|
||||||
vmm_bitmap.blocks = dceil(KERNEL_HEAP_SIZE, BLOCK_SIZE);
|
vmm_bitmap.blocks = dceil(KERNEL_HEAP_SIZE, BLOCK_SIZE);
|
||||||
vmm_bitmap.bytes = dceil(vmm_bitmap.blocks, 8);
|
vmm_bitmap.bytes = dceil(vmm_bitmap.blocks, 8);
|
||||||
uint32_t bitmaploc = 0xC6000000;
|
uint32_t bitmap_loc = 0xC6000000;
|
||||||
|
|
||||||
size_t pagecount = dceil(vmm_bitmap.bytes, PAGE_SIZE);
|
size_t page_count = dceil(vmm_bitmap.bytes, PAGE_SIZE);
|
||||||
for (size_t i = 0; i < pagecount; i++) {
|
for (size_t i = 0; i < page_count; i++) {
|
||||||
void* fr = pmm_allocPage();
|
void* fr = pmm_alloc();
|
||||||
if (fr == NULL) return 1;
|
if (fr == NULL) return 1;
|
||||||
pag_mapPage(bitmaploc + i * PAGE_SIZE, (uint32_t)fr, 0);
|
pag_map(bitmap_loc + i * PAGE_SIZE, (uint32_t)fr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set all pages as
|
// Set all pages as
|
||||||
vmm_bitmap.map = (void*)bitmaploc;
|
vmm_bitmap.map = (void*)bitmap_loc;
|
||||||
bmap_setall(&vmm_bitmap, 0);
|
bmap_set_all(&vmm_bitmap, 0);
|
||||||
|
|
||||||
bmap_set(&vmm_bitmap, 0, 1);
|
bmap_set(&vmm_bitmap, 0, 1);
|
||||||
bmap_set(&vmm_bitmap, 8, 1);
|
bmap_set(&vmm_bitmap, 8, 1);
|
||||||
@@ -36,7 +34,7 @@ int vmm_init(void) {
|
|||||||
"\tBitmap is at 0x%08x in virtual memory\n"
|
"\tBitmap is at 0x%08x in virtual memory\n"
|
||||||
"\tBitmap is %d bytes over %d pages\n",
|
"\tBitmap is %d bytes over %d pages\n",
|
||||||
vmm_bitmap.blocks, vmm_bitmap.map,
|
vmm_bitmap.blocks, vmm_bitmap.map,
|
||||||
vmm_bitmap.bytes, pagecount
|
vmm_bitmap.bytes, page_count
|
||||||
);
|
);
|
||||||
|
|
||||||
vmm_bitmap.ready = 1;
|
vmm_bitmap.ready = 1;
|
||||||
@@ -44,16 +42,16 @@ int vmm_init(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* vmm_alloc(size_t pages) {
|
void* vmm_alloc(size_t pages) {
|
||||||
size_t idx = bmap_findarea(&vmm_bitmap, pages, 0);
|
size_t idx = bmap_get_area(&vmm_bitmap, pages, 0);
|
||||||
if (idx == BMAP_NOT_FOUND) return NULL;
|
if (idx == BMAP_NOT_FOUND) return NULL;
|
||||||
void* ptr = bmap_ptr(&vmm_bitmap, idx);
|
void* ptr = bmap_ptr(&vmm_bitmap, idx);
|
||||||
|
|
||||||
bmap_setarea(&vmm_bitmap, idx * BLOCK_SIZE, pages * PAGE_SIZE, 1);
|
bmap_set_area(&vmm_bitmap, idx * BLOCK_SIZE, pages * PAGE_SIZE, 1);
|
||||||
|
|
||||||
for (size_t i = 0; i < pages; i++) {
|
for (size_t i = 0; i < pages; i++) {
|
||||||
void* fr = pmm_allocPage();
|
void* fr = pmm_alloc();
|
||||||
if (fr == NULL) return NULL;
|
if (fr == NULL) return NULL;
|
||||||
pag_mapPage((uint32_t)ptr + i * PAGE_SIZE, (uint32_t)fr, 0);
|
pag_map((uint32_t)ptr + i * PAGE_SIZE, (uint32_t)fr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ptr;
|
return ptr;
|
||||||
@@ -62,13 +60,13 @@ void* vmm_alloc(size_t pages) {
|
|||||||
void vmm_free(void* ptr, size_t pages) {
|
void vmm_free(void* ptr, size_t pages) {
|
||||||
for (size_t i = 0; i < pages; i++) {
|
for (size_t i = 0; i < pages; i++) {
|
||||||
uint32_t vaddr = (uint32_t)ptr + i * PAGE_SIZE;
|
uint32_t vaddr = (uint32_t)ptr + i * PAGE_SIZE;
|
||||||
uint32_t paddr = (uint32_t)pag_virtToPhys((uint32_t)ptr);
|
uint32_t paddr = (uint32_t)pag_virt_to_phys((uint32_t)ptr);
|
||||||
|
|
||||||
pmm_freePage((void*)paddr);
|
pmm_free((void*)paddr);
|
||||||
pag_umapPage(vaddr);
|
pag_umap(vaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t base = ((size_t)ptr - KERNEL_BASE) / BLOCK_SIZE;
|
size_t base = ((size_t)ptr - KERNEL_BASE) / BLOCK_SIZE;
|
||||||
bmap_setarea(&vmm_bitmap, base, pages, 0);
|
bmap_set_area(&vmm_bitmap, base, pages, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user