forked from PoliEcho-holding-org/kern
Changed camelCase to snake_case
This commit is contained in:
@@ -58,6 +58,11 @@ Todos
|
||||
- [ ] RAMFS
|
||||
- [ ] FAT32
|
||||
- [ ] DevFS
|
||||
- [ ] /dev/std*
|
||||
- [ ] /dev/tty
|
||||
- [ ] /dev/sd*
|
||||
- [ ] /dev/fb0
|
||||
- [ ] /dev/null, /dev/zero, ...
|
||||
- [ ] SysFS
|
||||
- [ ] ProcFS
|
||||
|
||||
|
||||
@@ -57,8 +57,8 @@ should not be placed after/before unary operators or member access operators.
|
||||
Naming
|
||||
------
|
||||
_The hardest thing in programming_
|
||||
Identifiers should use camelCase (starting with lowercase). And may have a
|
||||
short prefix separated with an underscore (e.g. 'sys_malloc').
|
||||
Identifiers should use snake_case (starting with lowercase). And should have a
|
||||
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,
|
||||
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:
|
||||
```c
|
||||
// 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);
|
||||
uint8_t getRtcRegister(uint8_t reg);
|
||||
uint8_t get_rtc_register(uint8_t reg);
|
||||
|
||||
// Serial functions all start with 'serial_'
|
||||
int serial_init();
|
||||
void serial_write(uint8_t byte);
|
||||
uint8_t serial_read();
|
||||
|
||||
```
|
||||
|
||||
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
|
||||
************
|
||||
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.
|
||||
|
||||
pmm.h
|
||||
-----
|
||||
The **physical memory manager** (PMM) is responsible for allocating physical
|
||||
memory. It gives `pmm_*` functions. The `pmm_allocPage()` function allocates a
|
||||
4kB page frame and retuns its **physical address**.
|
||||
|
||||
vmm.h
|
||||
-----
|
||||
The **virtual memory manager** (VMM) is responsible for allocating virtual
|
||||
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
|
||||
first page. Userspace can interface with the VMM using the `mmap()` and
|
||||
`munmap()` syscalls.
|
||||
|
||||
**The heap** is an area of memory that both kernel and user space have.
|
||||
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
|
||||
heap.
|
||||
kmalloc.h
|
||||
---------
|
||||
The `kmalloc.h` header provides memory management functions for kernel memory.
|
||||
|
||||
`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_set(bitmap_t* map, size_t bit, int val);
|
||||
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_setall(bitmap_t* map, int val);
|
||||
size_t bmap_findarea(bitmap_t* map, size_t len, int val);
|
||||
void bmap_set_area(bitmap_t* map, size_t base, size_t len, int val);
|
||||
size_t bmap_get_area(bitmap_t* map, size_t len, int val);
|
||||
void bmap_set_all(bitmap_t* map, int val);
|
||||
|
||||
#endif
|
||||
|
||||
+14
-14
@@ -29,20 +29,20 @@ struct boot_memmap {
|
||||
* Some values may not be provided by the bootloader, in this case
|
||||
* pointers will be NULL and integer values will be 0 if applicable.
|
||||
* 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 {
|
||||
uint32_t memLower;
|
||||
uint32_t memUpper;
|
||||
uint8_t bootDrive;
|
||||
uint8_t bootPart1;
|
||||
uint8_t bootPart2;
|
||||
uint8_t bootPart3;
|
||||
char* cmdline;
|
||||
struct boot_memmap* memmap;
|
||||
size_t memmapLen;
|
||||
char* bootname;
|
||||
uint32_t mem_lower;
|
||||
uint32_t mem_upper;
|
||||
uint8_t boot_drive;
|
||||
uint8_t boot_part1;
|
||||
uint8_t boot_part2;
|
||||
uint8_t boot_part3;
|
||||
struct boot_memmap* memmap;
|
||||
size_t memmap_size;
|
||||
char* cmdline;
|
||||
char* bootname;
|
||||
} __packed;
|
||||
extern struct boot_info bootloader;
|
||||
|
||||
@@ -53,9 +53,9 @@ extern struct boot_info bootloader;
|
||||
*/
|
||||
int boot_init(int type, ...);
|
||||
|
||||
int boot_initMB1(void* ptr, uint32_t magic);
|
||||
int boot_init_mb1(void* ptr, uint32_t magic);
|
||||
// TODO:
|
||||
// int boot_initMB2(...);
|
||||
// int boot_initLimine(...);
|
||||
// int boot_init_mb2(...);
|
||||
// int boot_init_limine(...);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -48,20 +48,20 @@
|
||||
|
||||
#define GDT_DESC(_lim, _base, _acc, _flag) (struct gdt_entry){\
|
||||
.limit = (_lim) & 0xffff,\
|
||||
.baseLow = (uint16_t)(_base),\
|
||||
.baseMid = (uint8_t)((_base) >> 16),\
|
||||
.base_low = (uint16_t)(_base),\
|
||||
.base_mid = (uint8_t)((_base) >> 16),\
|
||||
.access = (_acc),\
|
||||
.flags = ((_flag & 0x0f) << 4) | (((_lim) >> 16) & 0x0f),\
|
||||
.baseHigh = (uint8_t)((_base) >> 24),\
|
||||
.base_high = (uint8_t)((_base) >> 24),\
|
||||
}
|
||||
|
||||
struct gdt_entry {
|
||||
uint16_t limit;
|
||||
uint16_t baseLow;
|
||||
uint8_t baseMid;
|
||||
uint16_t base_low;
|
||||
uint8_t base_mid;
|
||||
uint8_t access;
|
||||
uint8_t flags; // low 4 bits are 4 msbs of limit, high 4 bits are flags
|
||||
uint8_t baseHigh;
|
||||
uint8_t base_high;
|
||||
} __packed;
|
||||
|
||||
struct gdt_pointer {
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
#define IDT_FLAG_USER 0xee // P = 1, Priv = 11, S = 0, Type = 1110 (32-bit int)
|
||||
|
||||
struct idt_entry {
|
||||
uint16_t offsetLow;
|
||||
uint16_t offset_low;
|
||||
uint16_t selector;
|
||||
uint8_t __unused;
|
||||
uint8_t flags;
|
||||
uint16_t offsetHigh;
|
||||
uint16_t offset_high;
|
||||
} __packed;
|
||||
|
||||
struct idt_pointer {
|
||||
@@ -22,6 +22,6 @@ struct idt_pointer {
|
||||
} __packed;
|
||||
|
||||
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
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <kernel.h>
|
||||
|
||||
// Interrupt frame (ie. what's on the stack on interrupt)
|
||||
struct isr_intFrame {
|
||||
struct isr_int_frame {
|
||||
// Pushed by OS
|
||||
uint32_t esp, ebx, ecx, edx, esi, edi, ebp;
|
||||
uint32_t ds, es, fs, gs, eax;
|
||||
@@ -13,14 +13,14 @@ struct isr_intFrame {
|
||||
// Pushed by CPU
|
||||
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);
|
||||
void isr_registerIRQ(uint8_t i, isr_handlerPtr handler);
|
||||
int isr_handleInterrupt(struct isr_intFrame iframe);
|
||||
void isr_register_IRQ(uint8_t i, isr_handler_ptr handler);
|
||||
int isr_handle_interrupt(struct isr_int_frame iframe);
|
||||
|
||||
// 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
|
||||
|
||||
#endif
|
||||
|
||||
@@ -43,6 +43,7 @@ typedef char* va_list;
|
||||
#define ceil(_x, _y) ((((_x) + (_y)) (_y)) * (_y))
|
||||
#define floor(_x, _y) ((_x) - ((_x) % (_y)))
|
||||
#define dceil(_x, _y) (((_x) + (_y) - 1) / (_y))
|
||||
#define fence() __asm__ volatile ("":::"memory")
|
||||
|
||||
/*
|
||||
* 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_err(_s) printk("[error] %s\n", (_s))
|
||||
#define panic(_s) do {\
|
||||
printk("[kernel] Panic! %s\n", (_s));\
|
||||
printk("[kernel] Panic! %s", (_s));\
|
||||
while (1) __asm__ volatile ("cli; hlt");\
|
||||
} while (0)
|
||||
#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)
|
||||
|
||||
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);
|
||||
void pag_registerTempFrame(uint32_t target);
|
||||
uint32_t pag_tempFrame(void);
|
||||
void pag_mapPage(uint32_t vaddr, uint32_t paddr, uint32_t flags);
|
||||
uint32_t pag_umapPage(uint32_t vaddr);
|
||||
void* pag_virtToPhys(uint32_t vaddr);
|
||||
uint32_t* pag_getPagedir();
|
||||
void pag_setPagedir(uint32_t* pagedir);
|
||||
void pag_syncPagedir();
|
||||
uint32_t* pag_allocPagedir();
|
||||
void pag_freePagedir(uint32_t* pagedir);
|
||||
void pag_register_temp_frame(uint32_t target);
|
||||
uint32_t pag_temp_frame(void);
|
||||
void pag_map(uint32_t vaddr, uint32_t paddr, uint32_t flags);
|
||||
uint32_t pag_umap(uint32_t vaddr);
|
||||
void* pag_virt_to_phys(uint32_t vaddr);
|
||||
uint32_t* pag_get_pagedir();
|
||||
void pag_set_pagedir(uint32_t* pagedir);
|
||||
void pag_sync_pagedir();
|
||||
uint32_t* pag_alloc_pagedir();
|
||||
void pag_free_pagedir(uint32_t* pagedir);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
extern bitmap_t pmm_bitmap;
|
||||
|
||||
int pmm_init(void);
|
||||
void* pmm_allocPage(void);
|
||||
void pmm_freePage(void* page);
|
||||
void* pmm_alloc(void);
|
||||
void pmm_free(void* page);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
|
||||
#include <isr.h>
|
||||
|
||||
int syscallHandler(struct isr_intFrame* iframe) { return 1; }
|
||||
int syscall_handler(struct isr_int_frame* iframe) { (void)iframe; return 1; }
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
|
||||
int tty_init(void);
|
||||
void tty_clear(void);
|
||||
void tty_setattr(uint8_t attr);
|
||||
void tty_enableCursor(uint8_t start, uint8_t end);
|
||||
void tty_disableCursor(void);
|
||||
void tty_set_attr(uint8_t attr);
|
||||
void tty_show_cursor(uint8_t start, uint8_t end);
|
||||
void tty_hide_cursor(void);
|
||||
void tty_write(char* buf, size_t len);
|
||||
void tty_putc(char c);
|
||||
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;
|
||||
}
|
||||
|
||||
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 count = dceil(len, BLOCK_SIZE);
|
||||
|
||||
while (count-- > 0) bmap_set(map, align++, val);
|
||||
}
|
||||
|
||||
void bmap_setall(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;
|
||||
}
|
||||
|
||||
size_t bmap_findarea(bitmap_t* map, size_t len, int val) {
|
||||
size_t bmap_get_area(bitmap_t* map, size_t len, int val) {
|
||||
if (len == 0) return BMAP_NOT_FOUND;
|
||||
|
||||
uint32_t found = 0;
|
||||
@@ -47,3 +40,10 @@ size_t bmap_findarea(bitmap_t* map, size_t len, int val) {
|
||||
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:
|
||||
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;
|
||||
}
|
||||
|
||||
int boot_initMB1(void* ptr, uint32_t magic) {
|
||||
int boot_init_mb1(void* ptr, uint32_t magic) {
|
||||
multiboot_info_t* mbi = ptr;
|
||||
|
||||
if (magic != MULTIBOOT_BOOTLOADER_MAGIC) return 1;
|
||||
|
||||
// mem_* fields are valid
|
||||
if (mbi->flags & MULTIBOOT_INFO_MEMORY) {
|
||||
bootloader.memLower = mbi->mem_lower;
|
||||
bootloader.memUpper = mbi->mem_upper;
|
||||
bootloader.mem_lower = mbi->mem_lower;
|
||||
bootloader.mem_upper = mbi->mem_upper;
|
||||
}
|
||||
|
||||
// boot_device is valid
|
||||
if (mbi->flags & MULTIBOOT_INFO_BOOTDEV) {
|
||||
bootloader.bootDrive = (mbi->boot_device & 0xff000000) >> 24;
|
||||
bootloader.bootPart1 = (mbi->boot_device & 0x00ff0000) >> 16;
|
||||
bootloader.bootPart2 = (mbi->boot_device & 0x0000ff00) >> 8;
|
||||
bootloader.bootPart3 = (mbi->boot_device & 0x000000ff);
|
||||
bootloader.boot_drive = (mbi->boot_device & 0xff000000) >> 24;
|
||||
bootloader.boot_part1 = (mbi->boot_device & 0x00ff0000) >> 16;
|
||||
bootloader.boot_part2 = (mbi->boot_device & 0x0000ff00) >> 8;
|
||||
bootloader.boot_part3 = (mbi->boot_device & 0x000000ff);
|
||||
}
|
||||
|
||||
// cmdline is valid
|
||||
@@ -45,9 +55,9 @@ int boot_initMB1(void* ptr, uint32_t magic) {
|
||||
|
||||
size_t i = 0;
|
||||
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].size = entry->len;
|
||||
bootloader.memmap[i].type = (uint8_t)entry->type;
|
||||
@@ -55,7 +65,7 @@ int boot_initMB1(void* ptr, uint32_t magic) {
|
||||
entry++;
|
||||
i++;
|
||||
}
|
||||
bootloader.memmapLen = i;
|
||||
bootloader.memmap_size = i;
|
||||
}
|
||||
|
||||
// TODO: drives_*
|
||||
|
||||
+3
-3
@@ -7,14 +7,14 @@ __align(16) // performace :fire:
|
||||
static struct idt_entry idt[IDT_ENTRIES];
|
||||
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;
|
||||
struct idt_entry* entry = &idt[i];
|
||||
|
||||
entry->offsetLow = (uint16_t)offset;
|
||||
entry->offset_low = (uint16_t)offset;
|
||||
entry->selector = GDT_KERNEL_CODE;
|
||||
entry->flags = flags;
|
||||
entry->offsetHigh = (uint16_t)(offset >> 16);
|
||||
entry->offset_high = (uint16_t)(offset >> 16);
|
||||
}
|
||||
|
||||
int idt_init(void) {
|
||||
|
||||
+13
-13
@@ -5,7 +5,7 @@
|
||||
#include <idt.h>
|
||||
#include <isr.h>
|
||||
|
||||
isr_handlerPtr irqHandlers[16];
|
||||
isr_handler_ptr irq_handlers[16];
|
||||
|
||||
const char* exceptions[] = {
|
||||
"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
|
||||
void isr_remapPIC(void) {
|
||||
void isr_remap_pic(void) {
|
||||
outb(0x20, 0x11); iowait();
|
||||
outb(0xa0, 0x11); iowait();
|
||||
outb(0x21, 0x20); iowait();
|
||||
@@ -58,15 +58,15 @@ void isr_remapPIC(void) {
|
||||
|
||||
int isr_init(void) {
|
||||
idt_init();
|
||||
isr_remapPIC();
|
||||
isr_remap_pic();
|
||||
|
||||
for (int i = 0; i < 48; i++) {
|
||||
// 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)
|
||||
idt_setGate(0x80, (void*)(uint32_t)isr128, IDT_FLAG_USER);
|
||||
idt_set_gate(0x80, (void*)(uint32_t)isr128, IDT_FLAG_USER);
|
||||
|
||||
// Let interrupts interrupt
|
||||
__asm__ volatile ("sti");
|
||||
@@ -75,31 +75,31 @@ int isr_init(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void isr_registerIRQ(uint8_t i, isr_handlerPtr handler) {
|
||||
irqHandlers[i] = handler;
|
||||
void isr_register_irq(uint8_t i, isr_handler_ptr handler) {
|
||||
irq_handlers[i] = handler;
|
||||
}
|
||||
|
||||
void isr_sendEOI(uint8_t irq) {
|
||||
void isr_send_eoi(uint8_t irq) {
|
||||
if (irq >= 8) {
|
||||
outb(0xa0, 0x20);
|
||||
}
|
||||
outb(0x20, 0x20);
|
||||
}
|
||||
|
||||
int isr_handleInterrupt(struct isr_intFrame iframe) {
|
||||
int isr_handle_interrupt(struct isr_int_frame iframe) {
|
||||
if (iframe.interrupt < 32) {
|
||||
// ISRs 0-31 - Exceptions
|
||||
panic(exceptions[iframe.error]);
|
||||
} else if (iframe.interrupt >= 32 && iframe.interrupt < 48) {
|
||||
// ISRs 32-47 - Hardware interrupts
|
||||
uint8_t irq = iframe.interrupt - 32;
|
||||
if (irqHandlers[irq]) {
|
||||
irqHandlers[irq](&iframe);
|
||||
isr_sendEOI(irq);
|
||||
if (irq_handlers[irq]) {
|
||||
irq_handlers[irq](&iframe);
|
||||
isr_send_eoi(irq);
|
||||
}
|
||||
} else if (iframe.interrupt == 128) {
|
||||
// ISR 128 - System call
|
||||
return syscallHandler(&iframe);
|
||||
return syscall_handler(&iframe);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
+5
-5
@@ -2,7 +2,7 @@
|
||||
[bits 32]
|
||||
|
||||
isr_common:
|
||||
;; Push registers to the intFrame_t struct
|
||||
;; Push registers to the int_frame_t struct
|
||||
push eax
|
||||
push gs
|
||||
push fs
|
||||
@@ -16,8 +16,8 @@ isr_common:
|
||||
push ebx
|
||||
push esp
|
||||
|
||||
[extern isr_handleInterrupt]
|
||||
call isr_handleInterrupt
|
||||
[extern isr_handle_interrupt]
|
||||
call isr_handle_interrupt
|
||||
isr_return:
|
||||
add esp, 4 ; Keep ESP
|
||||
pop ebx
|
||||
@@ -109,8 +109,8 @@ isr128:
|
||||
jmp isr_common
|
||||
|
||||
;; Create table of ISRs
|
||||
[global isr_redirectTable]
|
||||
isr_redirectTable:
|
||||
[global isr_redirect_table]
|
||||
isr_redirect_table:
|
||||
%assign i 0
|
||||
%rep 48
|
||||
dd isr%+i
|
||||
|
||||
+5
-2
@@ -10,7 +10,7 @@
|
||||
|
||||
__noreturn
|
||||
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
|
||||
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");
|
||||
|
||||
debugf("[kernel] Basic initialization complete!\n");
|
||||
|
||||
|
||||
// TODO: Init VFS
|
||||
// TODO:
|
||||
|
||||
panic("kmain() reached end.");
|
||||
}
|
||||
|
||||
|
||||
+39
-39
@@ -6,10 +6,10 @@
|
||||
|
||||
#define PAGE_DIR_COUNT 256
|
||||
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?
|
||||
size_t pag_pageCount = 0;
|
||||
size_t pag_page_count = 0;
|
||||
|
||||
// Invalidates the pagedir entry in the CPUs TLB cache
|
||||
static inline void invalidate(uint32_t vaddr) {
|
||||
@@ -17,11 +17,11 @@ static inline void invalidate(uint32_t vaddr) {
|
||||
}
|
||||
|
||||
// Temp paging thing
|
||||
uint32_t tempFrameStart;
|
||||
void pag_registerTempFrame(uint32_t target) { tempFrameStart = target; }
|
||||
uint32_t pag_tempFrame(void) {
|
||||
uint32_t fin = tempFrameStart;
|
||||
tempFrameStart += PAGE_SIZE;
|
||||
uint32_t temp_frame_start;
|
||||
void pag_register_temp_frame(uint32_t target) { temp_frame_start = target; }
|
||||
uint32_t pag_temp_frame(void) {
|
||||
uint32_t fin = temp_frame_start;
|
||||
temp_frame_start += PAGE_SIZE;
|
||||
return fin;
|
||||
}
|
||||
|
||||
@@ -42,21 +42,21 @@ int pag_init(void) {
|
||||
|
||||
// TODO: This sometimes causes a #PF
|
||||
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");
|
||||
|
||||
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
|
||||
uint32_t* prevpd = NULL;
|
||||
|
||||
// Switch to the init pagedir if in kernel memory
|
||||
if (vaddr >= KERNEL_BASE) {
|
||||
prevpd = pag_getPagedir();
|
||||
if (prevpd != init_pagedir) pag_setPagedir(init_pagedir);
|
||||
prevpd = pag_get_pagedir();
|
||||
if (prevpd != init_pagedir) pag_set_pagedir(init_pagedir);
|
||||
}
|
||||
|
||||
// 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
|
||||
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 |
|
||||
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
|
||||
pagetab[pti] = paddr | PAGE_FLAG_PRESENT | flags;
|
||||
pag_pageCount++;
|
||||
pag_page_count++;
|
||||
invalidate(vaddr);
|
||||
|
||||
// Do we need to return to the original pagedir?
|
||||
if (prevpd != NULL) {
|
||||
pag_syncPagedir(); // Sync it to other pagedirs
|
||||
if (prevpd != init_pagedir) pag_setPagedir(prevpd);
|
||||
pag_sync_pagedir(); // Sync it to other pagedirs
|
||||
if (prevpd != init_pagedir) pag_set_pagedir(prevpd);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t pag_umapPage(uint32_t vaddr) {
|
||||
// Same saving as in pag_mapPage()
|
||||
uint32_t pag_umap(uint32_t vaddr) {
|
||||
// Same saving as in pag_map()
|
||||
uint32_t* prevpd = NULL;
|
||||
|
||||
if (vaddr >= KERNEL_BASE) {
|
||||
prevpd = pag_getPagedir();
|
||||
if (prevpd != init_pagedir) pag_setPagedir(init_pagedir);
|
||||
prevpd = pag_get_pagedir();
|
||||
if (prevpd != init_pagedir) pag_set_pagedir(init_pagedir);
|
||||
}
|
||||
|
||||
// Extract indecies
|
||||
@@ -111,7 +111,7 @@ uint32_t pag_umapPage(uint32_t vaddr) {
|
||||
|
||||
uint32_t pte = pagetab[pti];
|
||||
pagetab[pti] = 0;
|
||||
pag_pageCount--;
|
||||
pag_page_count--;
|
||||
|
||||
// Look if we can free the pagetab
|
||||
int remove = 1;
|
||||
@@ -125,24 +125,24 @@ uint32_t pag_umapPage(uint32_t vaddr) {
|
||||
uint32_t pde = pagedir[pdi];
|
||||
if (remove && pde & PAGE_FLAG_OWNER) {
|
||||
uint32_t tabaddr = PHYS_ADDR(pde);
|
||||
pmm_freePage((void*)tabaddr);
|
||||
pmm_free((void*)tabaddr);
|
||||
pagedir[pdi] = 0;
|
||||
}
|
||||
|
||||
invalidate(vaddr);
|
||||
|
||||
// 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) {
|
||||
pag_syncPagedir(); // Sync it to other pagedirs
|
||||
if (prevpd != init_pagedir) pag_setPagedir(prevpd);
|
||||
pag_sync_pagedir(); // Sync it to other pagedirs
|
||||
if (prevpd != init_pagedir) pag_set_pagedir(prevpd);
|
||||
}
|
||||
|
||||
return pte;
|
||||
}
|
||||
|
||||
void* pag_virtToPhys(uint32_t vaddr) {
|
||||
void* pag_virt_to_phys(uint32_t vaddr) {
|
||||
uint32_t pdi = vaddr >> 22;
|
||||
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));
|
||||
}
|
||||
|
||||
uint32_t* pag_getPagedir() {
|
||||
uint32_t* pag_get_pagedir() {
|
||||
uint32_t pagedir;
|
||||
__asm__ volatile ("mov %%cr3, %0" : "=r"(pagedir));
|
||||
pagedir += KERNEL_BASE;
|
||||
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);
|
||||
__asm__ volatile (
|
||||
"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++) {
|
||||
if (!pagedirUsed[i]) continue;
|
||||
if (!pagedir_used[i]) continue;
|
||||
|
||||
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
|
||||
for (size_t i = 0; i < PAGE_DIR_COUNT; i++) {
|
||||
if (pagedirUsed[i]) continue;
|
||||
pagedirUsed[i] = 1;
|
||||
if (pagedir_used[i]) continue;
|
||||
pagedir_used[i] = 1;
|
||||
|
||||
uint32_t* pagedir = pagedirs[i];
|
||||
memset(pagedir, 0, PAGE_SIZE);
|
||||
@@ -207,9 +207,9 @@ uint32_t* pag_allocPagedir() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void pag_freePagedir(uint32_t* pagedir) {
|
||||
uint32_t* prevpd = pag_getPagedir();
|
||||
pag_setPagedir(pagedir);
|
||||
void pag_free_pagedir(uint32_t* pagedir) {
|
||||
uint32_t* prevpd = pag_get_pagedir();
|
||||
pag_set_pagedir(pagedir);
|
||||
|
||||
uint32_t pdi = (uint32_t)pagedir - (uint32_t)pagedirs;
|
||||
pdi /= PAGE_SIZE;
|
||||
@@ -224,15 +224,15 @@ void pag_freePagedir(uint32_t* pagedir) {
|
||||
for (size_t j = 0; j < 1024; 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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
pagedirUsed[pdi] = 0;
|
||||
pag_setPagedir(prevpd);
|
||||
pagedir_used[pdi] = 0;
|
||||
pag_set_pagedir(prevpd);
|
||||
}
|
||||
|
||||
|
||||
+20
-20
@@ -20,7 +20,7 @@ int pmm_init(void) {
|
||||
// Find enough space for the bitmap
|
||||
struct boot_memmap* mmap;
|
||||
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];
|
||||
|
||||
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
|
||||
|
||||
uint32_t pageFrameStart = mmap->base;
|
||||
pag_registerTempFrame(pageFrameStart);
|
||||
uint32_t page_frame_start = mmap->base;
|
||||
pag_register_temp_frame(page_frame_start);
|
||||
mmap->base += ptcount * PAGE_SIZE;
|
||||
|
||||
uint32_t bitmapStart = KERNEL_HEAP_BASE - dceil(pmm_bitmap.bytes, PAGE_SIZE) * PAGE_SIZE;
|
||||
uint32_t bitmapStartPhys = mmap->base;
|
||||
pmm_bitmap.map = (void*)bitmapStart;
|
||||
uint32_t bitmap_start = KERNEL_HEAP_BASE - dceil(pmm_bitmap.bytes, PAGE_SIZE) * PAGE_SIZE;
|
||||
uint32_t bitmap_start_phys = mmap->base;
|
||||
pmm_bitmap.map = (void*)bitmap_start;
|
||||
|
||||
size_t pagecount = dceil(pmm_bitmap.bytes, PAGE_SIZE);
|
||||
for (size_t i = 0; i < pagecount; i++) {
|
||||
// NOTE: We can't unmap this with pag_umapPage(), it's in a tempFrame
|
||||
pag_mapPage(bitmapStart + i * PAGE_SIZE, mmap->base + i * PAGE_SIZE, 0);
|
||||
size_t page_count = dceil(pmm_bitmap.bytes, PAGE_SIZE);
|
||||
for (size_t i = 0; i < page_count; i++) {
|
||||
// NOTE: We can't unmap this with pag_umap(), it's in a tempFrame
|
||||
pag_map(bitmap_start + i * PAGE_SIZE, mmap->base + i * PAGE_SIZE, 0);
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
for (size_t i = 0; i < bootloader.memmapLen; i++) {
|
||||
for (size_t i = 0; i < bootloader.memmap_size; i++) {
|
||||
mmap = &bootloader.memmap[i];
|
||||
if (mmap->size == 0) continue; // Ignore dummy entries
|
||||
|
||||
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
|
||||
@@ -63,8 +63,8 @@ int pmm_init(void) {
|
||||
(mmap->type == BOOT_MMAP_AVAILABLE) ? "AVAILABLE" : "RESERVED");
|
||||
}
|
||||
|
||||
bmap_setarea(&pmm_bitmap, bitmapStartPhys, pmm_bitmap.bytes, 1);
|
||||
bmap_setarea(&pmm_bitmap, pageFrameStart, ptcount * PAGE_SIZE, 1);
|
||||
bmap_set_area(&pmm_bitmap, bitmap_start_phys, pmm_bitmap.bytes, 1);
|
||||
bmap_set_area(&pmm_bitmap, page_frame_start, ptcount * PAGE_SIZE, 1);
|
||||
|
||||
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",
|
||||
pmm_bitmap.blocks - pmm_bitmap.used,
|
||||
(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;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* pmm_allocPage(void) {
|
||||
void* pmm_alloc(void) {
|
||||
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;
|
||||
|
||||
bmap_set(&pmm_bitmap, base, 1);
|
||||
@@ -94,9 +94,9 @@ void* pmm_allocPage(void) {
|
||||
return bmap_ptr(&pmm_bitmap, base);
|
||||
}
|
||||
|
||||
void pmm_freePage(void* page) {
|
||||
void pmm_free(void* page) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
+39
-35
@@ -4,24 +4,28 @@
|
||||
#include <tty.h>
|
||||
|
||||
struct {
|
||||
size_t row;
|
||||
size_t col;
|
||||
uint8_t attr;
|
||||
size_t row;
|
||||
size_t col;
|
||||
uint8_t attr;
|
||||
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) {
|
||||
// Map VGA Text memory to KERNEL_FRAMEBUF
|
||||
size_t pagecount = dceil(VGA_WIDTH * VGA_HEIGHT * 2, PAGE_SIZE);
|
||||
for (size_t i = 0; i < pagecount; i++) {
|
||||
pag_mapPage(KERNEL_FRAMEBUF + i * PAGE_SIZE, VGA_MEMORY + i * PAGE_SIZE, 0);
|
||||
size_t page_count = dceil(VGA_WIDTH * VGA_HEIGHT * 2, PAGE_SIZE);
|
||||
for (size_t i = 0; i < page_count; i++) {
|
||||
pag_map(KERNEL_FRAMEBUF + i * PAGE_SIZE, VGA_MEMORY + i * PAGE_SIZE, 0);
|
||||
}
|
||||
|
||||
ctx.row = 0;
|
||||
ctx.col = 0;
|
||||
ctx.attr = 0x07;
|
||||
ctx.buf = (uint8_t*)KERNEL_FRAMEBUF;
|
||||
tty_ctx.row = 0;
|
||||
tty_ctx.col = 0;
|
||||
tty_ctx.attr = 0x07;
|
||||
tty_ctx.buf = (uint8_t*)KERNEL_FRAMEBUF;
|
||||
tty_clear();
|
||||
|
||||
return 0;
|
||||
@@ -29,34 +33,34 @@ int tty_init(void) {
|
||||
|
||||
void tty_clear(void) {
|
||||
for (int i = 0; i < VGA_WIDTH * VGA_HEIGHT; i++) {
|
||||
ctx.buf[i * 2] = ' ';
|
||||
ctx.buf[i * 2 + 1] = ctx.attr;
|
||||
tty_ctx.buf[i * 2] = ' ';
|
||||
tty_ctx.buf[i * 2 + 1] = tty_ctx.attr;
|
||||
}
|
||||
}
|
||||
|
||||
void tty_setattr(uint8_t attr) {
|
||||
ctx.attr = attr;
|
||||
void tty_set_attr(uint8_t 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(0x3d5, (inb(0x3d5) & 0xc0) | start);
|
||||
outb(0x3d4, 0x0b);
|
||||
outb(0x3d5, (inb(0x3d5) & 0xe0) | end);
|
||||
}
|
||||
|
||||
void tty_disableCursor(void) {
|
||||
void tty_hide_cursor(void) {
|
||||
outb(0x3d4, 0x0a);
|
||||
outb(0x3d5, 0x20);
|
||||
}
|
||||
|
||||
void tty_updateCursor(void) {
|
||||
if (ctx.updateWait > 0) {
|
||||
ctx.updateWait--;
|
||||
void tty_update_cursor(void) {
|
||||
if (tty_ctx.update_wait > 0) {
|
||||
tty_ctx.update_wait--;
|
||||
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(0x3d5, (uint8_t)pos);
|
||||
outb(0x3d4, 0x0e);
|
||||
@@ -65,37 +69,37 @@ void tty_updateCursor(void) {
|
||||
|
||||
// TODO:
|
||||
void tty_scroll(void) {
|
||||
ctx.row = 0;
|
||||
ctx.col = 0;
|
||||
tty_ctx.row = 0;
|
||||
tty_ctx.col = 0;
|
||||
tty_clear();
|
||||
}
|
||||
|
||||
void tty_putat(char c, size_t row, size_t col) {
|
||||
size_t i = row * VGA_WIDTH + col;
|
||||
ctx.buf[i * 2] = c;
|
||||
ctx.buf[i * 2 + 1] = ctx.attr;
|
||||
tty_ctx.buf[i * 2] = c;
|
||||
tty_ctx.buf[i * 2 + 1] = tty_ctx.attr;
|
||||
}
|
||||
|
||||
void tty_putc(char c) {
|
||||
if (c == '\n') {
|
||||
ctx.col = 0;
|
||||
ctx.row++;
|
||||
tty_ctx.col = 0;
|
||||
tty_ctx.row++;
|
||||
goto scroll_check;
|
||||
}
|
||||
|
||||
tty_putat(c, ctx.row, ctx.col++);
|
||||
if (ctx.col >= VGA_WIDTH) {
|
||||
ctx.col = 0;
|
||||
ctx.row++;
|
||||
tty_putat(c, tty_ctx.row, tty_ctx.col++);
|
||||
if (tty_ctx.col >= VGA_WIDTH) {
|
||||
tty_ctx.col = 0;
|
||||
tty_ctx.row++;
|
||||
}
|
||||
|
||||
scroll_check:
|
||||
if (ctx.row >= VGA_HEIGHT) tty_scroll();
|
||||
tty_updateCursor();
|
||||
if (tty_ctx.row >= VGA_HEIGHT) tty_scroll();
|
||||
tty_update_cursor();
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
|
||||
+16
-18
@@ -5,8 +5,6 @@
|
||||
|
||||
#include <vmm.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
bitmap_t vmm_bitmap;
|
||||
|
||||
int vmm_init(void) {
|
||||
@@ -14,18 +12,18 @@ int vmm_init(void) {
|
||||
vmm_bitmap.membase = KERNEL_HEAP_BASE;
|
||||
vmm_bitmap.blocks = dceil(KERNEL_HEAP_SIZE, BLOCK_SIZE);
|
||||
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);
|
||||
for (size_t i = 0; i < pagecount; i++) {
|
||||
void* fr = pmm_allocPage();
|
||||
size_t page_count = dceil(vmm_bitmap.bytes, PAGE_SIZE);
|
||||
for (size_t i = 0; i < page_count; i++) {
|
||||
void* fr = pmm_alloc();
|
||||
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
|
||||
vmm_bitmap.map = (void*)bitmaploc;
|
||||
bmap_setall(&vmm_bitmap, 0);
|
||||
vmm_bitmap.map = (void*)bitmap_loc;
|
||||
bmap_set_all(&vmm_bitmap, 0);
|
||||
|
||||
bmap_set(&vmm_bitmap, 0, 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 %d bytes over %d pages\n",
|
||||
vmm_bitmap.blocks, vmm_bitmap.map,
|
||||
vmm_bitmap.bytes, pagecount
|
||||
vmm_bitmap.bytes, page_count
|
||||
);
|
||||
|
||||
vmm_bitmap.ready = 1;
|
||||
@@ -44,16 +42,16 @@ int vmm_init(void) {
|
||||
}
|
||||
|
||||
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;
|
||||
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++) {
|
||||
void* fr = pmm_allocPage();
|
||||
void* fr = pmm_alloc();
|
||||
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;
|
||||
@@ -62,13 +60,13 @@ void* vmm_alloc(size_t pages) {
|
||||
void vmm_free(void* ptr, size_t pages) {
|
||||
for (size_t i = 0; i < pages; i++) {
|
||||
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);
|
||||
pag_umapPage(vaddr);
|
||||
pmm_free((void*)paddr);
|
||||
pag_umap(vaddr);
|
||||
}
|
||||
|
||||
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