Compare commits
2 commits
ef384ad9a7
...
c8c8d009f6
Author | SHA1 | Date | |
---|---|---|---|
|
c8c8d009f6 | ||
|
b5b904cfc9 |
|
@ -14,8 +14,8 @@ class Symbol:
|
||||||
name: str
|
name: str
|
||||||
|
|
||||||
readelf = subprocess.run(
|
readelf = subprocess.run(
|
||||||
["readelf", "-s", "build/kernel.bin"],
|
["readelf", "-s", "build/kernel.bin"],
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
encoding="UTF-8"
|
encoding="UTF-8"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
size_t backtrace(void **dst, size_t len);
|
size_t backtrace(void **dst, size_t len);
|
||||||
|
|
||||||
// same as backtrace but with specified instruction and base pointer
|
// same as backtrace but with specified instruction and base pointer
|
||||||
size_t backtrace_ex(void **dst, size_t len, void* ip, void *bp);
|
size_t backtrace_ex(void **dst, size_t len, void *ip, void *bp);
|
||||||
|
|
||||||
// Log a backtrace
|
// Log a backtrace
|
||||||
void log_backtrace();
|
void log_backtrace();
|
||||||
|
|
|
@ -92,25 +92,25 @@ int ctoi(char c);
|
||||||
* @param s - the string to convert
|
* @param s - the string to convert
|
||||||
* @returns the number inside s or 0 on error
|
* @returns the number inside s or 0 on error
|
||||||
*/
|
*/
|
||||||
int atoi(const char* s);
|
int atoi(const char *s);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts the initial portiion of the string pointed to by s to long.
|
* Converts the initial portiion of the string pointed to by s to long.
|
||||||
* @param s - the string to convert
|
* @param s - the string to convert
|
||||||
* @returns the number inside s or 0 on error
|
* @returns the number inside s or 0 on error
|
||||||
*/
|
*/
|
||||||
long int atol(const char* s);
|
long int atol(const char *s);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts the initial portiion of the string pointed to by s to long long.
|
* Converts the initial portiion of the string pointed to by s to long long.
|
||||||
* @param s - the string to convert
|
* @param s - the string to convert
|
||||||
* @returns the number inside s or 0 on error
|
* @returns the number inside s or 0 on error
|
||||||
*/
|
*/
|
||||||
long long int atoll(const char* s);
|
long long int atoll(const char *s);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a integer to asci inside a string with a given radix (base).
|
* Converts a integer to asci inside a string with a given radix (base).
|
||||||
* @param n - the number to conver
|
* @param n - the number to convert
|
||||||
* @param buffer - the string buffer
|
* @param buffer - the string buffer
|
||||||
* @param radix - the base to convert
|
* @param radix - the base to convert
|
||||||
*/
|
*/
|
||||||
|
@ -118,7 +118,7 @@ char *itoa(int n, char *buffer, int radix);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a long to asci inside a string with a given radix (base).
|
* Converts a long to asci inside a string with a given radix (base).
|
||||||
* @param n - the number to conver
|
* @param n - the number to convert
|
||||||
* @param buffer - the string buffer
|
* @param buffer - the string buffer
|
||||||
* @param radix - the base to convert
|
* @param radix - the base to convert
|
||||||
*/
|
*/
|
||||||
|
@ -134,7 +134,7 @@ char *lltoa(long long int n, char *buffer, int radix);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a unsigned integer to asci inside a string with a given radix (base).
|
* Converts a unsigned integer to asci inside a string with a given radix (base).
|
||||||
* @param n - the number to conver
|
* @param n - the number to convert
|
||||||
* @param buffer - the string buffer
|
* @param buffer - the string buffer
|
||||||
* @param radix - the base to convert
|
* @param radix - the base to convert
|
||||||
*/
|
*/
|
||||||
|
@ -142,7 +142,7 @@ char *utoa(unsigned int n, char *buffer, int radix);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a unsigned long to asci inside a string with a given radix (base).
|
* Converts a unsigned long to asci inside a string with a given radix (base).
|
||||||
* @param n - the number to conver
|
* @param n - the number to convert
|
||||||
* @param buffer - the string buffer
|
* @param buffer - the string buffer
|
||||||
* @param radix - the base to convert
|
* @param radix - the base to convert
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -7,46 +7,46 @@
|
||||||
/**
|
/**
|
||||||
* Initalize system memory allocator
|
* Initalize system memory allocator
|
||||||
*/
|
*/
|
||||||
extern void memory_init(struct memory_map *map);
|
void memory_init(struct memory_map *map);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disabled cpu interupts to not interfere with
|
* Disabled cpu interupts to not interfere with
|
||||||
* current memory allocations.
|
* current memory allocations.
|
||||||
*/
|
*/
|
||||||
extern void memory_lock(void);
|
void memory_lock(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reenabled cpu interupts
|
* Reenabled cpu interupts
|
||||||
*/
|
*/
|
||||||
extern void memory_unlock(void);
|
void memory_unlock(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns how much memory the system has
|
* @returns how much memory the system has
|
||||||
*/
|
*/
|
||||||
extern uint64_t memory_total(void);
|
uint64_t memory_total(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns how much memory is free
|
* @returns how much memory is free
|
||||||
*/
|
*/
|
||||||
extern uint64_t memory_free(void);
|
uint64_t memory_free(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns how much memory is used
|
* @returns how much memory is used
|
||||||
*/
|
*/
|
||||||
extern uint64_t memory_used(void);
|
uint64_t memory_used(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates a single page in memory.
|
* Allocates a single page in memory.
|
||||||
* @returns the page if allocated or NULL on failure
|
* @returns the page if allocated or NULL on failure
|
||||||
*/
|
*/
|
||||||
extern void *alloc_page(void);
|
void *alloc_page(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocats count pages in memory
|
* Allocats count pages in memory
|
||||||
* @param count - the number of continious pages to allocate
|
* @param count - the number of continious pages to allocate
|
||||||
* @returns the pages if allocated or NULL on failure
|
* @returns the pages if allocated or NULL on failure
|
||||||
*/
|
*/
|
||||||
extern void *alloc_pages(int count);
|
void *alloc_pages(int count);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees a signle page in memory.
|
* Frees a signle page in memory.
|
||||||
|
@ -54,7 +54,7 @@ extern void *alloc_pages(int count);
|
||||||
* Freeing in the middle of a block is allowed.
|
* Freeing in the middle of a block is allowed.
|
||||||
* @param page - the pointer to the page
|
* @param page - the pointer to the page
|
||||||
*/
|
*/
|
||||||
extern void free_page(void *page);
|
void free_page(void *page);
|
||||||
// TODO: implement free_page
|
// TODO: implement free_page
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,7 +64,7 @@ extern void free_page(void *page);
|
||||||
* free_pages will from *page to end of block allocated.
|
* free_pages will from *page to end of block allocated.
|
||||||
* @param page - the pointer to the page
|
* @param page - the pointer to the page
|
||||||
*/
|
*/
|
||||||
extern void free_pages(void *page);
|
void free_pages(void *page);
|
||||||
// TODO: implement freeing in middle of block
|
// TODO: implement freeing in middle of block
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -76,21 +76,21 @@ extern void free_pages(void *page);
|
||||||
* @param writable - if this memory should be writable
|
* @param writable - if this memory should be writable
|
||||||
* @param user - if this memory should be user writable
|
* @param user - if this memory should be user writable
|
||||||
*/
|
*/
|
||||||
extern void *mmap(void *addr, size_t len);
|
void *mmap(void *addr, size_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unmaps mapped address from the mmap function
|
* Unmaps mapped address from the mmap function
|
||||||
* @param addr - the address returned from mmap
|
* @param addr - the address returned from mmap
|
||||||
* @param len - the length allocated
|
* @param len - the length allocated
|
||||||
*/
|
*/
|
||||||
extern void unmap(void *addr);
|
void unmap(void *addr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates size_t bytes in memory
|
* Allocates size_t bytes in memory
|
||||||
* @param size - the amount of bytes to allocate
|
* @param size - the amount of bytes to allocate
|
||||||
* @retruns the address allocated or NULL on failure
|
* @retruns the address allocated or NULL on failure
|
||||||
*/
|
*/
|
||||||
extern void *kalloc(size_t size);
|
void *kalloc(size_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reallocates a given allocated ptr to a new size of bytes in memory.
|
* Reallocates a given allocated ptr to a new size of bytes in memory.
|
||||||
|
@ -99,10 +99,10 @@ extern void *kalloc(size_t size);
|
||||||
* @param size - the amount of bytes to set the pointer to
|
* @param size - the amount of bytes to set the pointer to
|
||||||
* @returns the address allocated or NULL on failure
|
* @returns the address allocated or NULL on failure
|
||||||
*/
|
*/
|
||||||
extern void *krealloc(void *ptr, size_t size);
|
void *krealloc(void *ptr, size_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees a allocated pointer in memory
|
* Frees a allocated pointer in memory
|
||||||
* @param ptr - the pointer to free
|
* @param ptr - the pointer to free
|
||||||
*/
|
*/
|
||||||
extern void kfree(void *ptr);
|
void kfree(void *ptr);
|
||||||
|
|
|
@ -8,23 +8,23 @@
|
||||||
* Allocates a single physical page in memory
|
* Allocates a single physical page in memory
|
||||||
* @preturns the physical address of the page
|
* @preturns the physical address of the page
|
||||||
*/
|
*/
|
||||||
extern void *alloc_phys_page(void);
|
void *alloc_phys_page(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates count physical pages in memory
|
* Allocates count physical pages in memory
|
||||||
* @returns the physical address of the first page
|
* @returns the physical address of the first page
|
||||||
*/
|
*/
|
||||||
extern void *alloc_phys_pages(int count);
|
void *alloc_phys_pages(int count);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees a single physical page in memory
|
* Frees a single physical page in memory
|
||||||
* @param ptr - the physical address of the page
|
* @param ptr - the physical address of the page
|
||||||
*/
|
*/
|
||||||
extern void free_phys_page(void *ptr);
|
void free_phys_page(void *ptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees count physical pages in memory
|
* Frees count physical pages in memory
|
||||||
* @param ptr - the physical address of the first page
|
* @param ptr - the physical address of the first page
|
||||||
* @param count - the number of pages in the list
|
* @param count - the number of pages in the list
|
||||||
*/
|
*/
|
||||||
extern void free_phys_pages(void *ptr, int count);
|
void free_phys_pages(void *ptr, int count);
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#define _PANIC_STR2(x) #x
|
#define _PANIC_STR2(x) #x
|
||||||
|
|
||||||
#define panic(msg) _panic_impl(_PANIC_STR(__LINE__), __FILE__, msg)
|
#define panic(msg) _panic_impl(_PANIC_STR(__LINE__), __FILE__, msg)
|
||||||
|
#define kassert(val, msg) do { if (!(val)) { panic(msg); } } while(0)
|
||||||
|
|
||||||
_Noreturn void _panic_impl(char *line, char *file, char *msg);
|
_Noreturn void _panic_impl(char *line, char *file, char *msg);
|
||||||
|
|
||||||
|
|
|
@ -162,13 +162,13 @@ static bool checksum(uint8_t *data, size_t len) {
|
||||||
|
|
||||||
static int read_s5_addr(struct acpi_state *state) {
|
static int read_s5_addr(struct acpi_state *state) {
|
||||||
uintptr_t ptr = state->fadt.dsdt;
|
uintptr_t ptr = state->fadt.dsdt;
|
||||||
char *s5_addr = (void*) (ptr + 36);
|
char *s5_addr = (void *) (ptr + 36);
|
||||||
|
|
||||||
int dsdt_len = *((int*) (ptr+1)) - 36;
|
int dsdt_len = *((int *) (ptr+1)) - 36;
|
||||||
while (0 < dsdt_len--) {
|
while (0 < dsdt_len--) {
|
||||||
if ( memcmp(s5_addr, "_S5_", 4) == 0)
|
if (memcmp(s5_addr, "_S5_", 4) == 0)
|
||||||
break;
|
break;
|
||||||
s5_addr++;
|
s5_addr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dsdt_len > 0) {
|
if (dsdt_len > 0) {
|
||||||
|
@ -178,12 +178,12 @@ static int read_s5_addr(struct acpi_state *state) {
|
||||||
s5_addr += ((*s5_addr &0xC0)>>6) +2; // calculate PkgLength size
|
s5_addr += ((*s5_addr &0xC0)>>6) +2; // calculate PkgLength size
|
||||||
|
|
||||||
if (*s5_addr == 0x0A)
|
if (*s5_addr == 0x0A)
|
||||||
s5_addr++; // skip byteprefix
|
s5_addr++; // skip byteprefix
|
||||||
state->SLP_TYPa = *(s5_addr)<<10;
|
state->SLP_TYPa = *(s5_addr)<<10;
|
||||||
s5_addr++;
|
s5_addr++;
|
||||||
|
|
||||||
if (*s5_addr == 0x0A)
|
if (*s5_addr == 0x0A)
|
||||||
s5_addr++; // skip byteprefix
|
s5_addr++; // skip byteprefix
|
||||||
state->SLP_TYPb = *(s5_addr)<<10;
|
state->SLP_TYPb = *(s5_addr)<<10;
|
||||||
|
|
||||||
state->SLP_EN = 1<<13;
|
state->SLP_EN = 1<<13;
|
||||||
|
|
|
@ -16,11 +16,11 @@ size_t backtrace(void **dst, size_t len) {
|
||||||
size_t backtrace_ex(void **dst, size_t len, void *ip, void *bp) {
|
size_t backtrace_ex(void **dst, size_t len, void *ip, void *bp) {
|
||||||
struct stackframe *frame = bp;
|
struct stackframe *frame = bp;
|
||||||
__asm__ volatile ("mov %%rbp, %0" : "=r"(frame));
|
__asm__ volatile ("mov %%rbp, %0" : "=r"(frame));
|
||||||
if(len > 0) {
|
if (len > 0) {
|
||||||
dst[0] = ip;
|
dst[0] = ip;
|
||||||
}
|
}
|
||||||
size_t i;
|
size_t i;
|
||||||
for(i = 1; frame && i < len; i++) {
|
for (i = 1; frame && i < len; i++) {
|
||||||
dst[i] = frame->rip;
|
dst[i] = frame->rip;
|
||||||
frame = frame->rbp;
|
frame = frame->rbp;
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ void log_backtrace_ex(void *ip, void *bp) {
|
||||||
serial_out_str(" 0x");
|
serial_out_str(" 0x");
|
||||||
serial_out_str(buf);
|
serial_out_str(buf);
|
||||||
serial_out_str("\n");
|
serial_out_str("\n");
|
||||||
while(frame) {
|
while (frame) {
|
||||||
ultoa((size_t)frame->rip, buf, 16);
|
ultoa((size_t)frame->rip, buf, 16);
|
||||||
serial_out_str(" 0x");
|
serial_out_str(" 0x");
|
||||||
serial_out_str(buf);
|
serial_out_str(buf);
|
||||||
|
|
|
@ -61,25 +61,25 @@ LONG_MODE equ 1 << 5
|
||||||
|
|
||||||
GDT:
|
GDT:
|
||||||
.Null: equ $ - GDT
|
.Null: equ $ - GDT
|
||||||
dq 0
|
dq 0
|
||||||
.Code: equ $ - GDT
|
.Code: equ $ - GDT
|
||||||
dd 0xFFFF ; Limit & Base (low, bits 0-15)
|
dd 0xFFFF ; Limit & Base (low, bits 0-15)
|
||||||
db 0 ; Base (mid, bits 16-23)
|
db 0 ; Base (mid, bits 16-23)
|
||||||
db PRESENT | NOT_SYS | EXEC | RW ; Access
|
db PRESENT | NOT_SYS | EXEC | RW ; Access
|
||||||
db GRAN_4K | LONG_MODE | 0xF ; Flags & Limit (high, bits 16-19)
|
db GRAN_4K | LONG_MODE | 0xF ; Flags & Limit (high, bits 16-19)
|
||||||
db 0 ; Base (high, bits 24-31)
|
db 0 ; Base (high, bits 24-31)
|
||||||
.Data: equ $ - GDT
|
.Data: equ $ - GDT
|
||||||
dd 0xFFFF ; Limit & Base (low, bits 0-15)
|
dd 0xFFFF ; Limit & Base (low, bits 0-15)
|
||||||
db 0 ; Base (mid, bits 16-23)
|
db 0 ; Base (mid, bits 16-23)
|
||||||
db PRESENT | NOT_SYS | RW ; Access
|
db PRESENT | NOT_SYS | RW ; Access
|
||||||
db GRAN_4K | SZ_32 | 0xF ; Flags & Limit (high, bits 16-19)
|
db GRAN_4K | SZ_32 | 0xF ; Flags & Limit (high, bits 16-19)
|
||||||
db 0 ; Base (high, bits 24-31)
|
db 0 ; Base (high, bits 24-31)
|
||||||
.TSS: equ $ - GDT
|
.TSS: equ $ - GDT
|
||||||
dd 0x00000068
|
dd 0x00000068
|
||||||
dd 0x00CF8900
|
dd 0x00CF8900
|
||||||
.Pointer:
|
.Pointer:
|
||||||
dw $ - GDT - 1
|
dw $ - GDT - 1
|
||||||
dq GDT
|
dq GDT
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
align 8
|
align 8
|
||||||
|
|
343
src/arch/amd64/debugger.c
Normal file
343
src/arch/amd64/debugger.c
Normal file
|
@ -0,0 +1,343 @@
|
||||||
|
#include <lib.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <serial.h>
|
||||||
|
#include <backtrace.h>
|
||||||
|
#include "debugger.h"
|
||||||
|
|
||||||
|
struct dr6 {
|
||||||
|
uint64_t b0 : 1,
|
||||||
|
b1 : 1,
|
||||||
|
b2 : 1,
|
||||||
|
b3 : 1,
|
||||||
|
: 7,
|
||||||
|
bld : 1,
|
||||||
|
: 1,
|
||||||
|
bd : 1,
|
||||||
|
bs : 1,
|
||||||
|
bt : 1,
|
||||||
|
rtm : 1,
|
||||||
|
: 47;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dr7 {
|
||||||
|
uint64_t l0 : 1,
|
||||||
|
g0 : 1,
|
||||||
|
l1 : 1,
|
||||||
|
g1 : 1,
|
||||||
|
l2 : 1,
|
||||||
|
g2 : 1,
|
||||||
|
l3 : 1,
|
||||||
|
g3 : 1,
|
||||||
|
: 8,
|
||||||
|
rw0 : 2,
|
||||||
|
len0 : 2,
|
||||||
|
rw1 : 2,
|
||||||
|
len1 : 2,
|
||||||
|
rw2 : 2,
|
||||||
|
len2 : 2,
|
||||||
|
rw3 : 2,
|
||||||
|
len3 : 2,
|
||||||
|
: 32;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rflags {
|
||||||
|
uint64_t cf : 1,
|
||||||
|
: 1,
|
||||||
|
pf : 1,
|
||||||
|
: 1,
|
||||||
|
af : 1,
|
||||||
|
: 1,
|
||||||
|
zf : 1,
|
||||||
|
sf : 1,
|
||||||
|
|
||||||
|
tf : 1,
|
||||||
|
if_ : 1,
|
||||||
|
df : 1,
|
||||||
|
of : 1,
|
||||||
|
iopl : 2,
|
||||||
|
nt : 1,
|
||||||
|
md : 1,
|
||||||
|
|
||||||
|
rf : 1,
|
||||||
|
vm : 1,
|
||||||
|
ac : 1,
|
||||||
|
vif : 1,
|
||||||
|
vip : 1,
|
||||||
|
id : 1,
|
||||||
|
: 42;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct breakpoint {
|
||||||
|
uint64_t addr;
|
||||||
|
uint8_t len;
|
||||||
|
uint8_t rw;
|
||||||
|
uint8_t used;
|
||||||
|
uint8_t enable;
|
||||||
|
};
|
||||||
|
|
||||||
|
static size_t dbg_steps = 0;
|
||||||
|
static int dbg_continue = 0;
|
||||||
|
static struct breakpoint bkps[4] = {{0}, {0}, {0}, {0}};
|
||||||
|
|
||||||
|
static void dbg_putc(char c) {
|
||||||
|
serial_out(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dbg_puts(char *msg) {
|
||||||
|
serial_out_str(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char dbg_getc() {
|
||||||
|
return serial_in();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void debugger_msg(int cause, struct dr6 dr6) {
|
||||||
|
char buf[24];
|
||||||
|
switch (cause) {
|
||||||
|
case DEBUG_INT3:
|
||||||
|
dbg_puts("dbg: reached int3");
|
||||||
|
break;
|
||||||
|
case DEBUG_FAULT:
|
||||||
|
dbg_puts("dbg: a fault occured");
|
||||||
|
break;
|
||||||
|
case DEBUG_DBG:
|
||||||
|
if (dr6.bs)
|
||||||
|
dbg_puts("dbg: finished steps");
|
||||||
|
else if (dr6.b0)
|
||||||
|
dbg_puts("dbg: reached breakpoint 0");
|
||||||
|
else if (dr6.b1)
|
||||||
|
dbg_puts("dbg: reached breakpoint 1");
|
||||||
|
else if (dr6.b2)
|
||||||
|
dbg_puts("dbg: reached breakpoint 2");
|
||||||
|
else if (dr6.b3)
|
||||||
|
dbg_puts("dbg: reached breakpoint 3");
|
||||||
|
}
|
||||||
|
if (dbg_steps > 0) {
|
||||||
|
ultoa(dbg_steps, buf, 10);
|
||||||
|
dbg_puts(" (");
|
||||||
|
dbg_puts(buf);
|
||||||
|
dbg_puts(" steps left)");
|
||||||
|
}
|
||||||
|
if (dbg_continue > 0) {
|
||||||
|
dbg_puts(" (paused continue)");
|
||||||
|
}
|
||||||
|
dbg_puts("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void debugger_print_reg(char *name, uint64_t val) {
|
||||||
|
char buf[24];
|
||||||
|
char *end;
|
||||||
|
dbg_puts(name);
|
||||||
|
dbg_puts(": 0x");
|
||||||
|
|
||||||
|
end = ultoa(val, buf, 16);
|
||||||
|
for (int i = 0; i < 16 - (end - buf); i++) {
|
||||||
|
dbg_putc('0');
|
||||||
|
}
|
||||||
|
dbg_puts(buf);
|
||||||
|
|
||||||
|
dbg_puts(" (");
|
||||||
|
end = ultoa(val, buf, 10);
|
||||||
|
dbg_puts(buf);
|
||||||
|
dbg_puts(")\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void debugger_print_regs(struct isr_regs *state) {
|
||||||
|
debugger_print_reg("rax", state->rax);
|
||||||
|
debugger_print_reg("rbx", state->rbx);
|
||||||
|
debugger_print_reg("rcx", state->rcx);
|
||||||
|
debugger_print_reg("rdx", state->rdx);
|
||||||
|
debugger_print_reg("rsi", state->rsi);
|
||||||
|
debugger_print_reg("rdi", state->rdi);
|
||||||
|
debugger_print_reg("rsp", state->rsp);
|
||||||
|
debugger_print_reg("rbp", state->rbp);
|
||||||
|
debugger_print_reg("r8 ", state->r8 );
|
||||||
|
debugger_print_reg("r9 ", state->r9 );
|
||||||
|
debugger_print_reg("r10", state->r10);
|
||||||
|
debugger_print_reg("r11", state->r11);
|
||||||
|
debugger_print_reg("r12", state->r12);
|
||||||
|
debugger_print_reg("r13", state->r13);
|
||||||
|
debugger_print_reg("r14", state->r14);
|
||||||
|
debugger_print_reg("r15", state->r15);
|
||||||
|
dbg_puts("---\n");
|
||||||
|
debugger_print_reg("rip", state->rip);
|
||||||
|
dbg_puts("---\n");
|
||||||
|
debugger_print_reg("rflags", state->rflags);
|
||||||
|
struct rflags *rflags = (struct rflags *)state->rflags;
|
||||||
|
dbg_puts("rflags: ");
|
||||||
|
if(rflags->cf) dbg_puts("CF ");
|
||||||
|
if(rflags->pf) dbg_puts("PF ");
|
||||||
|
if(rflags->af) dbg_puts("AF ");
|
||||||
|
if(rflags->zf) dbg_puts("ZF ");
|
||||||
|
if(rflags->sf) dbg_puts("SF ");
|
||||||
|
if(rflags->tf) dbg_puts("TF ");
|
||||||
|
if(rflags->if_) dbg_puts("IF ");
|
||||||
|
if(rflags->df) dbg_puts("DF ");
|
||||||
|
if(rflags->of) dbg_puts("OF ");
|
||||||
|
if(rflags->iopl) dbg_puts("IOPL ");
|
||||||
|
if(rflags->nt) dbg_puts("NT ");
|
||||||
|
if(rflags->md) dbg_puts("MD ");
|
||||||
|
if(rflags->rf) dbg_puts("RF ");
|
||||||
|
if(rflags->vm) dbg_puts("VM ");
|
||||||
|
if(rflags->ac) dbg_puts("AC ");
|
||||||
|
if(rflags->vif) dbg_puts("VIF ");
|
||||||
|
if(rflags->vip) dbg_puts("VIP ");
|
||||||
|
if(rflags->id) dbg_puts("ID ");
|
||||||
|
dbg_putc('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PROMPT_LEN 60
|
||||||
|
|
||||||
|
static int debugger_handle_bkp_cmd(char *buf) {
|
||||||
|
if (buf[0] == 'l') {
|
||||||
|
// list breakpoints
|
||||||
|
char buf[20];
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
dbg_puts("breakpoint ");
|
||||||
|
dbg_putc('0' + i);
|
||||||
|
dbg_puts(": ");
|
||||||
|
struct breakpoint bkp = bkps[i];
|
||||||
|
if(!bkp.used) {
|
||||||
|
dbg_puts("unset\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
dbg_puts(" 0x");
|
||||||
|
ultoa(bkp.addr, buf, 16);
|
||||||
|
dbg_puts(buf);
|
||||||
|
dbg_puts(" len=");
|
||||||
|
switch (bkp.len) {
|
||||||
|
case 0x0: dbg_putc('1'); break;
|
||||||
|
case 0x1: dbg_putc('2'); break;
|
||||||
|
case 0x2: dbg_putc('8'); break;
|
||||||
|
case 0x3: dbg_putc('4'); break;
|
||||||
|
}
|
||||||
|
dbg_puts(" trigger=");
|
||||||
|
switch (bkp.rw) {
|
||||||
|
case 0x0: dbg_puts("x "); break;
|
||||||
|
case 0x1: dbg_puts("w "); break;
|
||||||
|
case 0x2: dbg_puts("io"); break;
|
||||||
|
case 0x3: dbg_puts("rw"); break;
|
||||||
|
}
|
||||||
|
dbg_puts(bkp.enable ? " enabled" : " disabled");
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
} else if (buf[0] == 'd') {
|
||||||
|
// disable breakpoints
|
||||||
|
bkps[0].enable = 0;
|
||||||
|
bkps[1].enable = 0;
|
||||||
|
bkps[2].enable = 0;
|
||||||
|
bkps[3].enable = 0;
|
||||||
|
return 1;
|
||||||
|
} else if (buf[0] == 'c') {
|
||||||
|
// clear breakpoints
|
||||||
|
bkps[0].used = 0;
|
||||||
|
bkps[1].used = 0;
|
||||||
|
bkps[2].used = 0;
|
||||||
|
bkps[3].used = 0;
|
||||||
|
return 1;
|
||||||
|
} else if (buf[0] <= '0' && buf[0] >= '3') {
|
||||||
|
dbg_puts("invalid breakpoint command\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// TODO set breakpoints
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void debugger_load_bkps() {
|
||||||
|
struct dr7 dr7;
|
||||||
|
__asm__ volatile ("mov %%dr7, %0" : "=r"(dr7));
|
||||||
|
dr7.g0 = bkps[0].enable & bkps[0].used;
|
||||||
|
dr7.g1 = bkps[1].enable & bkps[0].used;
|
||||||
|
dr7.g2 = bkps[2].enable & bkps[0].used;
|
||||||
|
dr7.g3 = bkps[3].enable & bkps[0].used;
|
||||||
|
dr7.l0 = 0;
|
||||||
|
dr7.l1 = 0;
|
||||||
|
dr7.l2 = 0;
|
||||||
|
dr7.l3 = 0;
|
||||||
|
dr7.rw0 = bkps[0].rw;
|
||||||
|
dr7.rw1 = bkps[1].rw;
|
||||||
|
dr7.rw2 = bkps[2].rw;
|
||||||
|
dr7.rw3 = bkps[3].rw;
|
||||||
|
dr7.len0 = bkps[0].len;
|
||||||
|
dr7.len1 = bkps[1].len;
|
||||||
|
dr7.len2 = bkps[2].len;
|
||||||
|
dr7.len3 = bkps[3].len;
|
||||||
|
__asm__ volatile ("mov %0, %%dr7" : : "r"(dr7));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int debugger_prompt(struct isr_regs *state) {
|
||||||
|
char buf[PROMPT_LEN];
|
||||||
|
char *p = buf;
|
||||||
|
dbg_puts("dbg> ");
|
||||||
|
while ((*p = dbg_getc()) != '\r' && p < buf + PROMPT_LEN - 1) {
|
||||||
|
dbg_putc(*p++);
|
||||||
|
}
|
||||||
|
dbg_putc('\n');
|
||||||
|
for(; p < buf + PROMPT_LEN; p++) {
|
||||||
|
*p = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct rflags *rflags = (struct rflags *)&state->rflags;
|
||||||
|
|
||||||
|
switch (buf[0]) {
|
||||||
|
case '\0': // nothing entered
|
||||||
|
return 1;
|
||||||
|
case 'h': // help
|
||||||
|
dbg_puts("see debugger.c for help information\n");
|
||||||
|
return 1;
|
||||||
|
case 'q': // quit
|
||||||
|
return 0;
|
||||||
|
case 'c': // continue
|
||||||
|
rflags->tf = 1;
|
||||||
|
dbg_continue = 1;
|
||||||
|
return 0;
|
||||||
|
case 'r': // print registers
|
||||||
|
debugger_print_regs(state);
|
||||||
|
return 1;
|
||||||
|
case 'k': // backtrace
|
||||||
|
log_backtrace_ex((void *)state->rip, (void *)state->rbp);
|
||||||
|
return 1;
|
||||||
|
case 's': // step (n)
|
||||||
|
rflags->tf = 1;
|
||||||
|
dbg_steps = atol(buf + 1) - 1;
|
||||||
|
if (dbg_steps < 0) dbg_steps = 0;
|
||||||
|
return 0;
|
||||||
|
case 'b': // breakpoints
|
||||||
|
{
|
||||||
|
int res = debugger_handle_bkp_cmd(buf+1);
|
||||||
|
debugger_load_bkps();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
dbg_puts("unknown command\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void debugger(struct isr_regs *state, int cause) {
|
||||||
|
struct dr6 dr6;
|
||||||
|
__asm__ volatile ("mov %%dr6, %0" : "=r"(dr6));
|
||||||
|
|
||||||
|
if (dr6.b0 || dr6.b1 || dr6.b2 || dr6.b3) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (dr6.bs && dbg_steps > 0) {
|
||||||
|
dbg_steps--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dr6.bs && dbg_continue) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debugger_msg(cause, dr6);
|
||||||
|
|
||||||
|
dbg_steps = 0;
|
||||||
|
dbg_continue = 0;
|
||||||
|
|
||||||
|
struct rflags *rflags = (struct rflags *)&state->rflags;
|
||||||
|
rflags->tf = 0;
|
||||||
|
|
||||||
|
while (debugger_prompt(state));
|
||||||
|
}
|
9
src/arch/amd64/debugger.h
Normal file
9
src/arch/amd64/debugger.h
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "idt.h"
|
||||||
|
|
||||||
|
#define DEBUG_INT3 0x00
|
||||||
|
#define DEBUG_DBG 0x01
|
||||||
|
#define DEBUG_FAULT 0x02
|
||||||
|
|
||||||
|
void debugger(struct isr_regs *state, int cause);
|
|
@ -9,8 +9,8 @@
|
||||||
#define INDEX 0x1CE
|
#define INDEX 0x1CE
|
||||||
#define DATA 0x1CF
|
#define DATA 0x1CF
|
||||||
#define FB_ADDR 0xE0000000
|
#define FB_ADDR 0xE0000000
|
||||||
#define FB_MAX 0xFF000000
|
#define FB_MAX 0xFF000000
|
||||||
#define FB_LEN (FB_MAX - FB_ADDR)
|
#define FB_LEN (FB_MAX - FB_ADDR)
|
||||||
|
|
||||||
#define PREFERRED_VY 4096
|
#define PREFERRED_VY 4096
|
||||||
#define PREFERRED_B 32
|
#define PREFERRED_B 32
|
||||||
|
|
|
@ -11,9 +11,9 @@ extern idt_pic_eoi
|
||||||
push rbx
|
push rbx
|
||||||
push rcx
|
push rcx
|
||||||
push rdx
|
push rdx
|
||||||
push rbp
|
|
||||||
push rdi
|
|
||||||
push rsi
|
push rsi
|
||||||
|
push rdi
|
||||||
|
push rbp
|
||||||
push r8
|
push r8
|
||||||
push r9
|
push r9
|
||||||
push r10
|
push r10
|
||||||
|
@ -33,9 +33,9 @@ extern idt_pic_eoi
|
||||||
pop r10
|
pop r10
|
||||||
pop r9
|
pop r9
|
||||||
pop r8
|
pop r8
|
||||||
pop rsi
|
|
||||||
pop rdi
|
|
||||||
pop rbp
|
pop rbp
|
||||||
|
pop rdi
|
||||||
|
pop rsi
|
||||||
pop rdx
|
pop rdx
|
||||||
pop rcx
|
pop rcx
|
||||||
pop rbx
|
pop rbx
|
||||||
|
@ -51,8 +51,7 @@ isr_stub_%+%1:
|
||||||
cld
|
cld
|
||||||
mov rdi, %1 ; exception number
|
mov rdi, %1 ; exception number
|
||||||
mov rsi, 0 ; placeholder error code
|
mov rsi, 0 ; placeholder error code
|
||||||
mov rdx, [rsp + 15 * 8] ; instruction pointer
|
mov rdx, rsp ; top of stack
|
||||||
mov rcx, rbp ; base pointer for stack trace
|
|
||||||
call idt_exception_handler
|
call idt_exception_handler
|
||||||
POPALL
|
POPALL
|
||||||
iretq
|
iretq
|
||||||
|
@ -64,15 +63,18 @@ isr_stub_%+%1:
|
||||||
%macro ISRExceptionCode 1
|
%macro ISRExceptionCode 1
|
||||||
align 8
|
align 8
|
||||||
isr_stub_%+%1:
|
isr_stub_%+%1:
|
||||||
|
; retrieve the error code without corrupting registers
|
||||||
|
mov [isr_tmp], rax
|
||||||
|
pop rax
|
||||||
|
mov [isr_err_code], rax
|
||||||
|
mov rax, [isr_tmp]
|
||||||
PUSHALL
|
PUSHALL
|
||||||
cld
|
cld
|
||||||
mov rdi, %1 ; exception number
|
mov rdi, %1 ; exception number
|
||||||
mov rsi, [rsp + 15 * 8] ; error code
|
mov rsi, [isr_err_code] ; error code
|
||||||
mov rdx, [rsp + 16 * 8] ; instruction pointer
|
mov rdx, rsp ; top of stack
|
||||||
mov rcx, rbp ; base pointer for stack trace
|
|
||||||
call idt_exception_handler
|
call idt_exception_handler
|
||||||
POPALL
|
POPALL
|
||||||
sub rsp, 8 ; discard error code
|
|
||||||
iretq
|
iretq
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
|
@ -188,6 +190,10 @@ PICGeneric 47 ; 15
|
||||||
%assign i i+1
|
%assign i i+1
|
||||||
%endrep
|
%endrep
|
||||||
|
|
||||||
|
section .data
|
||||||
|
isr_tmp: dq 0
|
||||||
|
isr_err_code: dq 0
|
||||||
|
|
||||||
; isr stub table
|
; isr stub table
|
||||||
section .rodata
|
section .rodata
|
||||||
bits 64
|
bits 64
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <panic.h>
|
|
||||||
#include <lib.h>
|
#include <lib.h>
|
||||||
#include <serial.h>
|
#include <serial.h>
|
||||||
|
#include <panic.h>
|
||||||
|
|
||||||
#include "backtrace.h"
|
#include "debugger.h"
|
||||||
#include "idt.h"
|
#include "idt.h"
|
||||||
#include "pic.h"
|
#include "pic.h"
|
||||||
|
|
||||||
|
@ -53,8 +53,8 @@ void idt_init(void) {
|
||||||
idtr.size = (uint16_t)sizeof(struct idt_entry) * IDT_SIZE - 1;
|
idtr.size = (uint16_t)sizeof(struct idt_entry) * IDT_SIZE - 1;
|
||||||
|
|
||||||
// initialize idt
|
// initialize idt
|
||||||
for(size_t vector = 0; vector < IDT_SIZE; vector++) {
|
for (size_t vector = 0; vector < IDT_SIZE; vector++) {
|
||||||
struct idt_entry* entry = &idt[vector];
|
struct idt_entry *entry = &idt[vector];
|
||||||
|
|
||||||
uint64_t isr = (uint64_t)isr_stub_table[vector];
|
uint64_t isr = (uint64_t)isr_stub_table[vector];
|
||||||
// interrupts before 0x20 are for cpu exceptions
|
// interrupts before 0x20 are for cpu exceptions
|
||||||
|
@ -108,7 +108,16 @@ char *EXCEPTIONS[] = {
|
||||||
"0x1F Reserved",
|
"0x1F Reserved",
|
||||||
};
|
};
|
||||||
|
|
||||||
void idt_exception_handler(uint64_t exception, uint64_t code, void *rip, void *rbp) {
|
void idt_exception_handler(uint64_t exception, uint64_t code, struct isr_regs *state) {
|
||||||
|
// breakpoint interrupt
|
||||||
|
if (exception == 0x03) {
|
||||||
|
debugger(state, DEBUG_INT3);
|
||||||
|
return;
|
||||||
|
} else if (exception == 0x01) {
|
||||||
|
debugger(state, DEBUG_DBG);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO don't just panic
|
// TODO don't just panic
|
||||||
char buf[24];
|
char buf[24];
|
||||||
char msg[256] = "Exception ";
|
char msg[256] = "Exception ";
|
||||||
|
@ -120,7 +129,7 @@ void idt_exception_handler(uint64_t exception, uint64_t code, void *rip, void *r
|
||||||
strcat(msg, buf);
|
strcat(msg, buf);
|
||||||
|
|
||||||
// page faults store the offending address in cr2
|
// page faults store the offending address in cr2
|
||||||
if(exception == 0x0E) {
|
if (exception == 0x0E) {
|
||||||
strcat(msg, "\nPage fault address: 0x");
|
strcat(msg, "\nPage fault address: 0x");
|
||||||
void *addr;
|
void *addr;
|
||||||
__asm__ volatile ("mov %%cr2, %0" : "=r"(addr));
|
__asm__ volatile ("mov %%cr2, %0" : "=r"(addr));
|
||||||
|
@ -128,7 +137,7 @@ void idt_exception_handler(uint64_t exception, uint64_t code, void *rip, void *r
|
||||||
strcat(msg, buf);
|
strcat(msg, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
panic_interrupt(rip, rbp, msg);
|
panic_interrupt((void *)state->rip, (void *)state->rbp, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idt_pic_eoi(uint8_t exception) {
|
void idt_pic_eoi(uint8_t exception) {
|
||||||
|
|
|
@ -1,3 +1,29 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct isr_regs {
|
||||||
|
uint64_t r15;
|
||||||
|
uint64_t r14;
|
||||||
|
uint64_t r13;
|
||||||
|
uint64_t r12;
|
||||||
|
uint64_t r11;
|
||||||
|
uint64_t r10;
|
||||||
|
uint64_t r9;
|
||||||
|
uint64_t r8;
|
||||||
|
uint64_t rbp;
|
||||||
|
uint64_t rdi;
|
||||||
|
uint64_t rsi;
|
||||||
|
uint64_t rdx;
|
||||||
|
uint64_t rcx;
|
||||||
|
uint64_t rbx;
|
||||||
|
uint64_t rax;
|
||||||
|
|
||||||
|
uint64_t rip;
|
||||||
|
uint64_t cs;
|
||||||
|
uint64_t rflags;
|
||||||
|
uint64_t rsp;
|
||||||
|
uint64_t ss;
|
||||||
|
};
|
||||||
|
|
||||||
void idt_init();
|
void idt_init();
|
||||||
|
|
|
@ -13,81 +13,73 @@
|
||||||
#define MBOOT_OLD_RSDP 14
|
#define MBOOT_OLD_RSDP 14
|
||||||
#define MBOOT_NEW_RSDP 15
|
#define MBOOT_NEW_RSDP 15
|
||||||
|
|
||||||
extern char symtab;
|
|
||||||
#define kaddr(addr) ((uintptr_t)(&addr))
|
|
||||||
|
|
||||||
typedef uint8_t mboot_uint8_t;
|
|
||||||
typedef uint16_t mboot_uint16_t;
|
|
||||||
typedef uint32_t mboot_uint32_t;
|
|
||||||
typedef uint64_t mboot_uint64_t;
|
|
||||||
|
|
||||||
struct mboot_info {
|
struct mboot_info {
|
||||||
mboot_uint32_t total_size;
|
uint32_t total_size;
|
||||||
mboot_uint32_t reserved;
|
uint32_t reserved;
|
||||||
char tags[];
|
char tags[];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mboot_tag {
|
struct mboot_tag {
|
||||||
mboot_uint32_t type;
|
uint32_t type;
|
||||||
mboot_uint32_t size;
|
uint32_t size;
|
||||||
char data[];
|
char data[];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mboot_tag_elf_sections {
|
struct mboot_tag_elf_sections {
|
||||||
mboot_uint32_t type;
|
uint32_t type;
|
||||||
mboot_uint32_t size;
|
uint32_t size;
|
||||||
mboot_uint16_t num;
|
uint16_t num;
|
||||||
mboot_uint16_t entsize;
|
uint16_t entsize;
|
||||||
mboot_uint16_t shndx;
|
uint16_t shndx;
|
||||||
mboot_uint16_t reserved;
|
uint16_t reserved;
|
||||||
char sections[];
|
char sections[];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mboot_tag_elf_sections_entry {
|
struct mboot_tag_elf_sections_entry {
|
||||||
mboot_uint32_t sh_name;
|
uint32_t sh_name;
|
||||||
mboot_uint32_t sh_type;
|
uint32_t sh_type;
|
||||||
mboot_uint64_t sh_flags;
|
uint64_t sh_flags;
|
||||||
mboot_uint64_t sh_addr;
|
uint64_t sh_addr;
|
||||||
mboot_uint64_t sh_offset;
|
uint64_t sh_offset;
|
||||||
mboot_uint64_t sh_size;
|
uint64_t sh_size;
|
||||||
mboot_uint32_t sh_link;
|
uint32_t sh_link;
|
||||||
mboot_uint32_t sh_info;
|
uint32_t sh_info;
|
||||||
mboot_uint64_t sh_addralign;
|
uint64_t sh_addralign;
|
||||||
mboot_uint64_t sh_entsize;
|
uint64_t sh_entsize;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mboot_mmap_entry {
|
struct mboot_mmap_entry {
|
||||||
mboot_uint64_t addr;
|
uint64_t addr;
|
||||||
mboot_uint64_t len;
|
uint64_t len;
|
||||||
mboot_uint32_t type;
|
uint32_t type;
|
||||||
mboot_uint32_t zero;
|
uint32_t zero;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mboot_tag_mmap {
|
struct mboot_tag_mmap {
|
||||||
mboot_uint32_t type;
|
uint32_t type;
|
||||||
mboot_uint32_t size;
|
uint32_t size;
|
||||||
mboot_uint32_t entry_size;
|
uint32_t entry_size;
|
||||||
mboot_uint32_t entry_version;
|
uint32_t entry_version;
|
||||||
struct mboot_mmap_entry entries[];
|
struct mboot_mmap_entry entries[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct mboot_tag_old_rsdp {
|
struct mboot_tag_old_rsdp {
|
||||||
mboot_uint32_t type;
|
uint32_t type;
|
||||||
mboot_uint32_t size;
|
uint32_t size;
|
||||||
mboot_uint8_t rsdp[];
|
uint8_t rsdp[];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mboot_tag_new_rsdp {
|
struct mboot_tag_new_rsdp {
|
||||||
mboot_uint32_t type;
|
uint32_t type;
|
||||||
mboot_uint32_t size;
|
uint32_t size;
|
||||||
mboot_uint8_t rsdp[];
|
uint8_t rsdp[];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mboot_tag_cmdline {
|
struct mboot_tag_cmdline {
|
||||||
mboot_uint32_t type;
|
uint32_t type;
|
||||||
mboot_uint32_t size;
|
uint32_t size;
|
||||||
mboot_uint8_t cmdline[];
|
uint8_t cmdline[];
|
||||||
};
|
};
|
||||||
|
|
||||||
static void read_symbols(
|
static void read_symbols(
|
||||||
|
@ -100,33 +92,33 @@ static void read_symbols(
|
||||||
// struct mboot_elf_section_header *section =
|
// struct mboot_elf_section_header *section =
|
||||||
// (struct mboot_elf_section_header *) (layout->elf_section_headers);
|
// (struct mboot_elf_section_header *) (layout->elf_section_headers);
|
||||||
//
|
//
|
||||||
// for (mboot_uint32_t i = 0; i < layout->num; i++) {
|
// for (uint32_t i = 0; i < layout->num; i++) {
|
||||||
// char buf[20];
|
// char buf[20];
|
||||||
//
|
//
|
||||||
// ultoa(i, buf, 10);
|
// ultoa(i, buf, 10);
|
||||||
// serial_out_str("[");
|
// serial_out_str("[");
|
||||||
// serial_out_str(buf);
|
// serial_out_str(buf);
|
||||||
// serial_out_str("]\t");
|
// serial_out_str("]\t");
|
||||||
//
|
//
|
||||||
// serial_out_str((char *)(kaddr(symtab) + section->sh_name));
|
// serial_out_str((char *)(kaddr(symtab) + section->sh_name));
|
||||||
// serial_out('\t');
|
// serial_out('\t');
|
||||||
//
|
//
|
||||||
// ultoa(section->sh_type, buf, 16);
|
// ultoa(section->sh_type, buf, 16);
|
||||||
// serial_out_str("type: 0x");
|
// serial_out_str("type: 0x");
|
||||||
// serial_out_str(buf);
|
// serial_out_str(buf);
|
||||||
// serial_out('\t');
|
// serial_out('\t');
|
||||||
//
|
//
|
||||||
// ultoa(section->sh_addr, buf, 16);
|
// ultoa(section->sh_addr, buf, 16);
|
||||||
// serial_out_str("addr: 0x");
|
// serial_out_str("addr: 0x");
|
||||||
// serial_out_str(buf);
|
// serial_out_str(buf);
|
||||||
// serial_out('\t');
|
// serial_out('\t');
|
||||||
//
|
//
|
||||||
// ultoa(section->sh_offset, buf, 16);
|
// ultoa(section->sh_offset, buf, 16);
|
||||||
// serial_out_str("offset: 0x");
|
// serial_out_str("offset: 0x");
|
||||||
// serial_out_str(buf);
|
// serial_out_str(buf);
|
||||||
// serial_out('\n');
|
// serial_out('\n');
|
||||||
//
|
//
|
||||||
// section++;
|
// section++;
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +126,7 @@ static void read_cmdline(
|
||||||
struct boot_info *shim_info,
|
struct boot_info *shim_info,
|
||||||
struct mboot_tag_cmdline *cmdline
|
struct mboot_tag_cmdline *cmdline
|
||||||
) {
|
) {
|
||||||
mboot_uint32_t size = cmdline->size - 8;
|
uint32_t size = cmdline->size - 8;
|
||||||
if (size >= CMDLINE_MAX)
|
if (size >= CMDLINE_MAX)
|
||||||
size = CMDLINE_MAX; // truncate :(
|
size = CMDLINE_MAX; // truncate :(
|
||||||
memcpy(shim_info->cmdline, cmdline->cmdline, size);
|
memcpy(shim_info->cmdline, cmdline->cmdline, size);
|
||||||
|
|
|
@ -68,25 +68,18 @@ static struct pdpte *pdpt_mapped = (void *) (uintptr_t) 0x201000;
|
||||||
static struct pde *pd_mapped = (void *) (uintptr_t) 0x202000;
|
static struct pde *pd_mapped = (void *) (uintptr_t) 0x202000;
|
||||||
static struct pte *pt_mapped = (void *) (uintptr_t) 0x203000;
|
static struct pte *pt_mapped = (void *) (uintptr_t) 0x203000;
|
||||||
|
|
||||||
static inline void
|
static inline void invlpg(void *addr) {
|
||||||
invlpg(void *addr)
|
|
||||||
{
|
|
||||||
__asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
|
__asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void load_addr(void *phys_addr) {
|
||||||
load_addr(void *phys_addr)
|
|
||||||
{
|
|
||||||
static struct pte *pt = &paging_pt[4];
|
static struct pte *pt = &paging_pt[4];
|
||||||
pt->address = (uint64_t)phys_addr >> 12;
|
pt->address = (uint64_t)phys_addr >> 12;
|
||||||
pt->flags = F_PRESENT | F_WRITEABLE;
|
pt->flags = F_PRESENT | F_WRITEABLE;
|
||||||
invlpg(addr_mapped);
|
invlpg(addr_mapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void load_pml4(void *phys) {
|
||||||
load_pml4(
|
|
||||||
void *phys
|
|
||||||
) {
|
|
||||||
static struct pte *pt = &paging_pt[0];
|
static struct pte *pt = &paging_pt[0];
|
||||||
if ((uint64_t)phys >> 12 == pt->address)
|
if ((uint64_t)phys >> 12 == pt->address)
|
||||||
return;
|
return;
|
||||||
|
@ -95,10 +88,7 @@ load_pml4(
|
||||||
invlpg(pml4_mapped);
|
invlpg(pml4_mapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void load_pdpt(void *phys) {
|
||||||
load_pdpt(
|
|
||||||
void *phys
|
|
||||||
) {
|
|
||||||
static struct pte *pt = &paging_pt[1];
|
static struct pte *pt = &paging_pt[1];
|
||||||
if ((uint64_t)phys >> 12 == pt->address)
|
if ((uint64_t)phys >> 12 == pt->address)
|
||||||
return;
|
return;
|
||||||
|
@ -107,10 +97,7 @@ load_pdpt(
|
||||||
invlpg(pdpt_mapped);
|
invlpg(pdpt_mapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void load_pd(void *phys) {
|
||||||
load_pd(
|
|
||||||
void *phys
|
|
||||||
) {
|
|
||||||
static struct pte *pt = &paging_pt[2];
|
static struct pte *pt = &paging_pt[2];
|
||||||
if ((uint64_t)phys >> 12 == pt->address)
|
if ((uint64_t)phys >> 12 == pt->address)
|
||||||
return;
|
return;
|
||||||
|
@ -119,10 +106,7 @@ load_pd(
|
||||||
invlpg(pdpt_mapped);
|
invlpg(pdpt_mapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void load_pt(void *phys) {
|
||||||
load_pt(
|
|
||||||
void *phys
|
|
||||||
) {
|
|
||||||
static struct pte *pt = &paging_pt[3];
|
static struct pte *pt = &paging_pt[3];
|
||||||
if ((uint64_t)phys >> 12 == pt->address)
|
if ((uint64_t)phys >> 12 == pt->address)
|
||||||
return;
|
return;
|
||||||
|
@ -135,8 +119,7 @@ load_pt(
|
||||||
#define PAG_CANNOT_ALLOC 1
|
#define PAG_CANNOT_ALLOC 1
|
||||||
#define PAG_NOT_PRESENT 2
|
#define PAG_NOT_PRESENT 2
|
||||||
|
|
||||||
static int
|
static int select_pdpt(
|
||||||
select_pdpt(
|
|
||||||
void *virt,
|
void *virt,
|
||||||
unsigned int flags,
|
unsigned int flags,
|
||||||
struct pml4e *root,
|
struct pml4e *root,
|
||||||
|
@ -165,8 +148,7 @@ select_pdpt(
|
||||||
return PAG_SUCCESS;
|
return PAG_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int select_pd(
|
||||||
select_pd(
|
|
||||||
void *virt,
|
void *virt,
|
||||||
unsigned int flags,
|
unsigned int flags,
|
||||||
struct pdpte *pdpt,
|
struct pdpte *pdpt,
|
||||||
|
@ -195,8 +177,7 @@ select_pd(
|
||||||
return PAG_SUCCESS;
|
return PAG_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int select_pt(
|
||||||
select_pt(
|
|
||||||
void *virt,
|
void *virt,
|
||||||
unsigned int flags,
|
unsigned int flags,
|
||||||
struct pde *pd,
|
struct pde *pd,
|
||||||
|
@ -225,8 +206,7 @@ select_pt(
|
||||||
return PAG_SUCCESS;
|
return PAG_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void select_page(
|
||||||
select_page(
|
|
||||||
void *virt,
|
void *virt,
|
||||||
struct pte *pt,
|
struct pte *pt,
|
||||||
struct pte **res
|
struct pte **res
|
||||||
|
@ -238,8 +218,7 @@ select_page(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void try_unmap_pml4(void) {
|
||||||
try_unmap_pml4(void) {
|
|
||||||
for (int i = 0; i < 512; i++) {
|
for (int i = 0; i < 512; i++) {
|
||||||
if (pml4_mapped[i].flags & F_PRESENT)
|
if (pml4_mapped[i].flags & F_PRESENT)
|
||||||
return;
|
return;
|
||||||
|
@ -252,8 +231,7 @@ try_unmap_pml4(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void try_unmap_pdpt(void) {
|
||||||
try_unmap_pdpt(void) {
|
|
||||||
for (int i = 0; i < 512; i++) {
|
for (int i = 0; i < 512; i++) {
|
||||||
if (pdpt_mapped[i].flags & F_PRESENT)
|
if (pdpt_mapped[i].flags & F_PRESENT)
|
||||||
return;
|
return;
|
||||||
|
@ -267,8 +245,7 @@ try_unmap_pdpt(void) {
|
||||||
try_unmap_pml4();
|
try_unmap_pml4();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void try_unmap_pd(void) {
|
||||||
try_unmap_pd(void) {
|
|
||||||
for (int i = 0; i < 512; i++) {
|
for (int i = 0; i < 512; i++) {
|
||||||
if (pd_mapped[i].flags & F_PRESENT)
|
if (pd_mapped[i].flags & F_PRESENT)
|
||||||
return;
|
return;
|
||||||
|
@ -282,8 +259,7 @@ try_unmap_pd(void) {
|
||||||
try_unmap_pdpt();
|
try_unmap_pdpt();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void try_unmap_pt(void) {
|
||||||
try_unmap_pt(void) {
|
|
||||||
for (int i = 0; i < 512; i++) {
|
for (int i = 0; i < 512; i++) {
|
||||||
if (pt_mapped[i].flags & F_PRESENT)
|
if (pt_mapped[i].flags & F_PRESENT)
|
||||||
return;
|
return;
|
||||||
|
@ -297,12 +273,10 @@ try_unmap_pt(void) {
|
||||||
try_unmap_pd();
|
try_unmap_pd();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void unmap_page(
|
||||||
unmap_page(
|
|
||||||
struct pml4e *root,
|
struct pml4e *root,
|
||||||
void *virt
|
void *virt
|
||||||
) {
|
) {
|
||||||
|
|
||||||
struct pdpte *pdpt;
|
struct pdpte *pdpt;
|
||||||
struct pde *pd;
|
struct pde *pd;
|
||||||
struct pte *pt;
|
struct pte *pt;
|
||||||
|
@ -331,13 +305,11 @@ unmap_page(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void unmap_pages(
|
||||||
unmap_pages(
|
|
||||||
struct pml4e *root,
|
struct pml4e *root,
|
||||||
void *virt_start,
|
void *virt_start,
|
||||||
long page_count
|
long page_count
|
||||||
) {
|
) {
|
||||||
|
|
||||||
uint64_t pml4_o = -1,
|
uint64_t pml4_o = -1,
|
||||||
pdpt_o = -1,
|
pdpt_o = -1,
|
||||||
pd_o = -1;
|
pd_o = -1;
|
||||||
|
@ -397,14 +369,12 @@ unmap_pages(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int map_page(
|
||||||
map_page(
|
|
||||||
struct pml4e *root,
|
struct pml4e *root,
|
||||||
void *virt,
|
void *virt,
|
||||||
void *phys,
|
void *phys,
|
||||||
unsigned int flags
|
unsigned int flags
|
||||||
) {
|
) {
|
||||||
|
|
||||||
struct pdpte *pdpt;
|
struct pdpte *pdpt;
|
||||||
struct pde *pd;
|
struct pde *pd;
|
||||||
struct pte *pt;
|
struct pte *pt;
|
||||||
|
@ -430,15 +400,13 @@ map_page(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int map_pages(
|
||||||
map_pages(
|
|
||||||
struct pml4e *root,
|
struct pml4e *root,
|
||||||
void *virt_start,
|
void *virt_start,
|
||||||
void *phys_start,
|
void *phys_start,
|
||||||
unsigned int flags,
|
unsigned int flags,
|
||||||
long page_count
|
long page_count
|
||||||
) {
|
) {
|
||||||
|
|
||||||
uint64_t pml4_o = -1,
|
uint64_t pml4_o = -1,
|
||||||
pdpt_o = -1,
|
pdpt_o = -1,
|
||||||
pd_o = -1;
|
pd_o = -1;
|
||||||
|
@ -502,7 +470,6 @@ failed:
|
||||||
}
|
}
|
||||||
|
|
||||||
void paging_init(void) {
|
void paging_init(void) {
|
||||||
|
|
||||||
kernel_pml4[0].flags = F_PRESENT | F_WRITEABLE;
|
kernel_pml4[0].flags = F_PRESENT | F_WRITEABLE;
|
||||||
kernel_pml4[0].address = (uint64_t)(&kernel_pdpt_0) >> 12;
|
kernel_pml4[0].address = (uint64_t)(&kernel_pdpt_0) >> 12;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#define F_WRITEABLE 0x002
|
#define F_WRITEABLE 0x002
|
||||||
#define F_UNPRIVILEGED 0x004
|
#define F_UNPRIVILEGED 0x004
|
||||||
#define F_WRITETHROUGH 0x008
|
#define F_WRITETHROUGH 0x008
|
||||||
#define F_CACHEDISABLE 0x010
|
#define F_CACHEDISABLE 0x010
|
||||||
#define F_ACCESSED 0x020
|
#define F_ACCESSED 0x020
|
||||||
#define F_DIRTY 0x040
|
#define F_DIRTY 0x040
|
||||||
#define F_MEGABYTE 0x080
|
#define F_MEGABYTE 0x080
|
||||||
|
|
|
@ -53,7 +53,7 @@ void pic_remap(void) {
|
||||||
void pic_mask(int irq) {
|
void pic_mask(int irq) {
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
uint8_t mask;
|
uint8_t mask;
|
||||||
if(irq < 8) {
|
if (irq < 8) {
|
||||||
port = PIC1_DATA;
|
port = PIC1_DATA;
|
||||||
} else {
|
} else {
|
||||||
port = PIC2_DATA;
|
port = PIC2_DATA;
|
||||||
|
@ -66,7 +66,7 @@ void pic_mask(int irq) {
|
||||||
void pic_unmask(int irq) {
|
void pic_unmask(int irq) {
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
uint8_t mask;
|
uint8_t mask;
|
||||||
if(irq < 8) {
|
if (irq < 8) {
|
||||||
port = PIC1_DATA;
|
port = PIC1_DATA;
|
||||||
} else {
|
} else {
|
||||||
irq -= 8;
|
irq -= 8;
|
||||||
|
@ -82,7 +82,7 @@ void pic_disable(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void pic_eoi(int irq) {
|
void pic_eoi(int irq) {
|
||||||
if(irq >= 8) {
|
if (irq >= 8) {
|
||||||
outb(PIC2_COMMAND, PIC_EOI);
|
outb(PIC2_COMMAND, PIC_EOI);
|
||||||
}
|
}
|
||||||
outb(PIC1_COMMAND, PIC_EOI);
|
outb(PIC1_COMMAND, PIC_EOI);
|
||||||
|
|
|
@ -18,7 +18,7 @@ int serial_init(void) {
|
||||||
outb(PORT + 0, 0xAE); // test by sending 0xAE
|
outb(PORT + 0, 0xAE); // test by sending 0xAE
|
||||||
|
|
||||||
uint8_t response = inb(PORT + 0);
|
uint8_t response = inb(PORT + 0);
|
||||||
if(response != 0xAE) {
|
if (response != 0xAE) {
|
||||||
// TODO panic here?
|
// TODO panic here?
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -30,18 +30,18 @@ int serial_init(void) {
|
||||||
|
|
||||||
uint8_t serial_in(void) {
|
uint8_t serial_in(void) {
|
||||||
// wait for data to be available
|
// wait for data to be available
|
||||||
while((inb(PORT + 5) & 0x01) == 0);
|
while ((inb(PORT + 5) & 0x01) == 0);
|
||||||
return inb(PORT);
|
return inb(PORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void serial_out(uint8_t ch) {
|
void serial_out(uint8_t ch) {
|
||||||
// wait for output to be free
|
// wait for output to be free
|
||||||
while((inb(PORT + 5) & 0x20) == 0);
|
while ((inb(PORT + 5) & 0x20) == 0);
|
||||||
outb(PORT, ch);
|
outb(PORT, ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
void serial_out_str(const char *str) {
|
void serial_out_str(const char *str) {
|
||||||
for(; *str != '\0'; str++) {
|
for (; *str != '\0'; str++) {
|
||||||
serial_out(*str);
|
serial_out(*str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
static struct boot_info boot_info;
|
static struct boot_info boot_info;
|
||||||
|
|
||||||
void* amd64_shim(long mboot_magic, void *mboot_data_ptr) {
|
void *amd64_shim(long mboot_magic, void *mboot_data_ptr) {
|
||||||
serial_init();
|
serial_init();
|
||||||
paging_init();
|
paging_init();
|
||||||
pic_remap();
|
pic_remap();
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <serial.h>
|
#include <serial.h>
|
||||||
#include <fb.h>
|
#include <fb.h>
|
||||||
#include <shim.h>
|
#include <shim.h>
|
||||||
|
#include <panic.h>
|
||||||
|
|
||||||
void kmain(struct boot_info *info) {
|
void kmain(struct boot_info *info) {
|
||||||
memory_init(&info->map);
|
memory_init(&info->map);
|
||||||
|
@ -12,8 +13,8 @@ void kmain(struct boot_info *info) {
|
||||||
|
|
||||||
kprintf("enterd kmain\n");
|
kprintf("enterd kmain\n");
|
||||||
|
|
||||||
*(char*)(0xB8000 + 0x144) = 'h';
|
*(char *)(0xB8000 + 0x144) = 'h';
|
||||||
*(char*)(0xB8000 + 0x146) = 'i';
|
*(char *)(0xB8000 + 0x146) = 'i';
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
//kprintf("ret: 0x%p\n", kalloc(1024));
|
//kprintf("ret: 0x%p\n", kalloc(1024));
|
||||||
|
|
42
src/lib.c
42
src/lib.c
|
@ -45,19 +45,21 @@ int strncmp(const char *restrict lhs, const char *restrict rhs, unsigned long n)
|
||||||
}
|
}
|
||||||
|
|
||||||
char *strcpy(char *restrict dest, const char *restrict src) {
|
char *strcpy(char *restrict dest, const char *restrict src) {
|
||||||
for(; (*dest = *src); dest++, src++);
|
char *d = dest;
|
||||||
|
for (; (*d = *src); d++, src++);
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *strncpy(char *restrict dest, const char *restrict src, unsigned long n) {
|
char *strncpy(char *restrict dest, const char *restrict src, unsigned long n) {
|
||||||
for(; (*dest = *src) && n; dest++, src++, n--);
|
char *d = dest;
|
||||||
memset(dest, 0, n);
|
for (; (*d = *src) && n; d++, src++, n--);
|
||||||
|
memset(d, 0, n);
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t strlen(const char *str) {
|
size_t strlen(const char *str) {
|
||||||
const char *p;
|
const char *p;
|
||||||
for(p = str; *p != 0; p++) {}
|
for (p = str; *p != 0; p++) {}
|
||||||
return p - str;
|
return p - str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,8 +88,8 @@ int isdigit(int c) {
|
||||||
|
|
||||||
|
|
||||||
#define ATOX(name, type) \
|
#define ATOX(name, type) \
|
||||||
type name(const char* s) { \
|
type name(const char *s) { \
|
||||||
for(; isspace(*s); s++); \
|
for (; isspace(*s); s++); \
|
||||||
int neg = 0; \
|
int neg = 0; \
|
||||||
switch (*s) { \
|
switch (*s) { \
|
||||||
case '-': \
|
case '-': \
|
||||||
|
@ -111,7 +113,7 @@ ATOX(atol, long int)
|
||||||
ATOX(atoll, long long int)
|
ATOX(atoll, long long int)
|
||||||
|
|
||||||
char itoc(int i) {
|
char itoc(int i) {
|
||||||
if(i < 10) {
|
if (i < 10) {
|
||||||
return '0' + i;
|
return '0' + i;
|
||||||
} else {
|
} else {
|
||||||
return 'a' + (i - 10);
|
return 'a' + (i - 10);
|
||||||
|
@ -119,9 +121,9 @@ char itoc(int i) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int ctoi(char c) {
|
int ctoi(char c) {
|
||||||
if(c < 'A') {
|
if (c < 'A') {
|
||||||
return c - '0';
|
return c - '0';
|
||||||
} else if(c < 'a') {
|
} else if (c < 'a') {
|
||||||
return c - 'A' + 10;
|
return c - 'A' + 10;
|
||||||
} else {
|
} else {
|
||||||
return c - 'a' + 10;
|
return c - 'a' + 10;
|
||||||
|
@ -210,19 +212,20 @@ end:
|
||||||
if (n == 0) { \
|
if (n == 0) { \
|
||||||
buffer[0] = '0'; \
|
buffer[0] = '0'; \
|
||||||
buffer[1] = '\0'; \
|
buffer[1] = '\0'; \
|
||||||
return buffer; \
|
return buffer + 1; \
|
||||||
} \
|
} \
|
||||||
char *start = buffer; \
|
char *start = buffer; \
|
||||||
for (; n; n /= radix) { \
|
for (; n; n /= radix) { \
|
||||||
*buffer++ = itoc(n % radix); \
|
*buffer++ = itoc(n % radix); \
|
||||||
} \
|
} \
|
||||||
|
char *buf_end = buffer; \
|
||||||
*buffer-- = '\0'; \
|
*buffer-- = '\0'; \
|
||||||
while(buffer > start) { \
|
while (buffer > start) { \
|
||||||
char tmp = *start; \
|
char tmp = *start; \
|
||||||
*start++ = *buffer; \
|
*start++ = *buffer; \
|
||||||
*buffer-- = tmp; \
|
*buffer-- = tmp; \
|
||||||
} \
|
} \
|
||||||
return buffer; \
|
return buf_end; \
|
||||||
}
|
}
|
||||||
|
|
||||||
UXTOA(int, utoa)
|
UXTOA(int, utoa)
|
||||||
|
@ -230,11 +233,11 @@ UXTOA(long int, ultoa)
|
||||||
UXTOA(long long int, ulltoa)
|
UXTOA(long long int, ulltoa)
|
||||||
|
|
||||||
#define XTOA(type, name) \
|
#define XTOA(type, name) \
|
||||||
char *name(type n, char* buffer, int radix) { \
|
char *name(type n, char *buffer, int radix) { \
|
||||||
if (n == 0) { \
|
if (n == 0) { \
|
||||||
buffer[0] = '0'; \
|
buffer[0] = '0'; \
|
||||||
buffer[1] = '\0'; \
|
buffer[1] = '\0'; \
|
||||||
return buffer; \
|
return buffer + 1; \
|
||||||
} \
|
} \
|
||||||
if (n < 0) { \
|
if (n < 0) { \
|
||||||
*buffer++ = '-'; \
|
*buffer++ = '-'; \
|
||||||
|
@ -244,13 +247,14 @@ UXTOA(long long int, ulltoa)
|
||||||
for (; n; n /= radix) { \
|
for (; n; n /= radix) { \
|
||||||
*buffer++ = itoc(n % radix); \
|
*buffer++ = itoc(n % radix); \
|
||||||
} \
|
} \
|
||||||
|
char *buf_end = buffer; \
|
||||||
*buffer-- = '\0'; \
|
*buffer-- = '\0'; \
|
||||||
while(buffer > start) { \
|
while (buffer > start) { \
|
||||||
char tmp = *start; \
|
char tmp = *start; \
|
||||||
*start++ = *buffer; \
|
*start++ = *buffer; \
|
||||||
*buffer-- = tmp; \
|
*buffer-- = tmp; \
|
||||||
} \
|
} \
|
||||||
return buffer; \
|
return buf_end; \
|
||||||
}
|
}
|
||||||
|
|
||||||
XTOA(int, itoa)
|
XTOA(int, itoa)
|
||||||
|
@ -260,7 +264,7 @@ XTOA(long long int, lltoa)
|
||||||
#define STRTOX(name, type) \
|
#define STRTOX(name, type) \
|
||||||
type name(const char *s, char **endptr, int radix) { \
|
type name(const char *s, char **endptr, int radix) { \
|
||||||
*endptr = NULL; \
|
*endptr = NULL; \
|
||||||
for(; isspace(*s); s++); \
|
for (; isspace(*s); s++); \
|
||||||
int neg = 0; \
|
int neg = 0; \
|
||||||
switch (*s) { \
|
switch (*s) { \
|
||||||
case '-': \
|
case '-': \
|
||||||
|
@ -283,9 +287,9 @@ XTOA(long long int, lltoa)
|
||||||
radix = 10; \
|
radix = 10; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
for (; *s == '0'; s++, *endptr = (void*) s); \
|
for (; *s == '0'; s++, *endptr = (void *) s); \
|
||||||
type num = 0; \
|
type num = 0; \
|
||||||
for (; isdigit(*s); s++, *endptr = (void*) s) { \
|
for (; isdigit(*s); s++, *endptr = (void *) s) { \
|
||||||
num *= radix; \
|
num *= radix; \
|
||||||
num += *s - '0'; \
|
num += *s - '0'; \
|
||||||
} \
|
} \
|
||||||
|
|
|
@ -19,7 +19,7 @@ static const size_t header_len = sizeof(struct page_header);
|
||||||
static struct page_header *start_header = NULL;
|
static struct page_header *start_header = NULL;
|
||||||
static struct page_header *end_header = NULL;
|
static struct page_header *end_header = NULL;
|
||||||
|
|
||||||
struct page_header* get_header(void *ptr) {
|
struct page_header *get_header(void *ptr) {
|
||||||
struct page_header *header =
|
struct page_header *header =
|
||||||
(struct page_header *) ((uintptr_t) ptr - header_len);
|
(struct page_header *) ((uintptr_t) ptr - header_len);
|
||||||
|
|
||||||
|
|
|
@ -170,7 +170,7 @@ void memory_init(struct memory_map *map) {
|
||||||
|
|
||||||
segment_count = 0;
|
segment_count = 0;
|
||||||
|
|
||||||
for(uint32_t i = 0; i < map->entry_count; i++) {
|
for (uint32_t i = 0; i < map->entry_count; i++) {
|
||||||
struct memory_segment *segment = &map->entries[i];
|
struct memory_segment *segment = &map->entries[i];
|
||||||
|
|
||||||
if (segment_invalid(segment))
|
if (segment_invalid(segment))
|
||||||
|
@ -201,7 +201,7 @@ void memory_init(struct memory_map *map) {
|
||||||
struct memory_area *area = page_start;
|
struct memory_area *area = page_start;
|
||||||
|
|
||||||
kprintf("MEMORY MAP\n");
|
kprintf("MEMORY MAP\n");
|
||||||
for(uint32_t i = 0; i < map->entry_count; i++) {
|
for (uint32_t i = 0; i < map->entry_count; i++) {
|
||||||
struct memory_segment *segment = &map->entries[i];
|
struct memory_segment *segment = &map->entries[i];
|
||||||
|
|
||||||
if (segment_invalid(segment))
|
if (segment_invalid(segment))
|
||||||
|
|
|
@ -118,7 +118,7 @@ void *virtaddr_alloc(int n_pages) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void merge_back(struct addr_node *node) {
|
static void merge_back(struct addr_node *node) {
|
||||||
while(node->prev && !node->is_alloc) {
|
while (node->prev && !node->is_alloc) {
|
||||||
struct addr_node *temp = node->prev;
|
struct addr_node *temp = node->prev;
|
||||||
node->start = node->prev->start;
|
node->start = node->prev->start;
|
||||||
node->prev = node->prev->prev;
|
node->prev = node->prev->prev;
|
||||||
|
@ -130,7 +130,7 @@ static void merge_back(struct addr_node *node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void merge_forward(struct addr_node *node) {
|
static void merge_forward(struct addr_node *node) {
|
||||||
while(node->next && !node->is_alloc) {
|
while (node->next && !node->is_alloc) {
|
||||||
struct addr_node *temp = node->next;
|
struct addr_node *temp = node->next;
|
||||||
node->end = node->next->end;
|
node->end = node->next->end;
|
||||||
node->next = node->next->next;
|
node->next = node->next->next;
|
||||||
|
|
Loading…
Reference in a new issue