ELF support; printf impl; replacing kprint with printf

This commit is contained in:
Luke Street
2018-09-30 14:56:07 -04:00
parent ce7518bb15
commit b063797bc4
35 changed files with 1552 additions and 247 deletions
+7 -3
View File
@@ -1,8 +1,12 @@
qemu-system-i386 -kernel kernel.bin -device isa-debug-exit,iobase=0xf4,iosize=0x04
# directly
qemu-system-i386 -kernel kernel.bin
# via Grub:
./mkiso.sh kernel.bin
qemu-system-i386 -cdrom os.iso -device isa-debug-exit,iobase=0xf4,iosize=0x04
qemu-system-i386 -cdrom os.iso
# support exit
-device isa-debug-exit,iobase=0xf4,iosize=0x04
# remote gdb (port 1234):
-s
@@ -11,4 +15,4 @@ qemu-system-i386 -cdrom os.iso -device isa-debug-exit,iobase=0xf4,iosize=0x04
-serial stdio
# IDE drive:
-drive file=fat.img,if=ide
-drive file=hd.img,if=ide
+1
View File
@@ -32,6 +32,7 @@ set(SOURCE_FILES
drivers/ata
drivers/pci
drivers/pci_registry
# drivers/i825xx
fatfs/diskio
fatfs/ff
fatfs/ffconf.h
+82 -26
View File
@@ -2,6 +2,9 @@
#include "drivers/vga.h"
#include "drivers/serial.h"
#include <stdio.h>
#include <string.h>
static bool vga_enabled = false;
static bool serial_enabled = false;
@@ -25,29 +28,30 @@ void console_set_serial_enabled(bool enabled) {
* Print a message on the specified location
* If col, row, are negative, we will use the current offset
*/
void kprint(const char *message) {
static void knprint(const char *str, size_t len, uint8_t vga_color) {
if (vga_enabled) {
int offset = vga_get_cursor_offset();
int row = vga_get_offset_row(offset);
int col = vga_get_offset_col(offset);
int i = 0;
while (message[i] != 0) {
offset = vga_print_char(message[i++], col, row, vga_entry_color(VGA_COLOR_WHITE, VGA_COLOR_BLACK));
for (size_t i = 0; i < len; ++i) {
offset = vga_print_char(str[i], col, row, vga_color);
row = vga_get_offset_row(offset);
col = vga_get_offset_col(offset);
}
}
if (serial_enabled) {
int i = 0;
while (message[i] != 0) {
serial_write(message[i++]);
for (size_t i = 0; i < len; ++i) {
serial_write(str[i]);
}
}
}
void kprint(const char *message) {
knprint(message, strlen(message), WHITE_ON_BLACK);
}
void kprint_char(char c) {
if (vga_enabled) {
int offset = vga_get_cursor_offset();
@@ -59,20 +63,6 @@ void kprint_char(char c) {
}
}
void kprint_backspace() {
if (vga_enabled) {
int offset = vga_get_cursor_offset() - 1;
vga_print_char(' ', vga_get_offset_col(offset), vga_get_offset_row(offset), WHITE_ON_BLACK);
vga_set_cursor_offset(offset);
}
if (serial_enabled) {
serial_write(0x8);
serial_write(' ');
serial_write(0x8);
}
}
void clear_screen() {
if (vga_enabled) {
vga_clear_screen();
@@ -135,8 +125,13 @@ void kprint_uint8(uint8_t val) {
}
_noreturn
void panic(char *str) {
if (str != NULL) kprint(str);
void panic(char *str, ...) {
va_list args;
va_start(args, str);
if (str != NULL) vfprintf(stderr, str, args);
va_end(args);
fflush(stderr);
__asm__("cli");
while (1) __asm__("hlt");
}
@@ -148,9 +143,70 @@ void panic(char *str) {
#endif
_unused
uintptr_t __stack_chk_guard = STACK_CHK_GUARD;
uintptr_t __stack_chk_guard = STACK_CHK_GUARD;
_noreturn _unused
void __stack_chk_fail() {
panic("Stack smashing detected");
}
}
// --- stdio
int errno;
size_t __stdout_write(FILE *f, const char *str, size_t len) {
size_t rem = f->wpos - f->wbase;
if (rem) knprint(f->wbase, rem, WHITE_ON_BLACK);
if (len) knprint(str, len, WHITE_ON_BLACK);
f->wend = f->buf + f->buf_size;
f->wpos = f->wbase = f->buf;
return len;
}
size_t __stderr_write(FILE *f, const char *str, size_t len) {
size_t rem = f->wpos - f->wbase;
if (rem) knprint(f->wbase, rem, RED_ON_WHITE);
if (len) knprint(str, len, RED_ON_WHITE);
f->wend = f->buf + f->buf_size;
f->wpos = f->wbase = f->buf;
return len;
}
off_t __stdio_seek(FILE *file, const off_t offset, int origin) {
return 0; // TODO
}
int __stdio_close(FILE *file) {
return 0; // TODO
}
#define BUFSIZ 1024
#define UNGET 8
static char __stdout_buf[BUFSIZ + UNGET];
FILE *stdout = &(FILE) {
.buf = __stdout_buf + UNGET,
.buf_size = BUFSIZ,
.fd = 1,
.flags = F_PERM | F_NORD,
.lbf = '\n',
.write = __stdout_write,
.seek = __stdio_seek,
.close = __stdio_close,
.lock = -1,
};
static char __stderr_buf[BUFSIZ + UNGET];
FILE *stderr = &(FILE) {
.buf = __stderr_buf + UNGET,
.buf_size = BUFSIZ,
.fd = 1,
.flags = F_PERM | F_NORD,
.lbf = '\n',
.write = __stderr_write,
.seek = __stdio_seek,
.close = __stdio_close,
.lock = -1,
};
+7 -8
View File
@@ -10,13 +10,12 @@ void console_set_serial_enabled(bool enabled);
void clear_screen();
void kprint(const char *message);
void kprint_char(char c);
void kprint_uint64(uint64_t val);
void kprint_uint32(uint32_t val);
void kprint_uint16(uint16_t val);
void kprint_uint8(uint8_t val);
void kprint_backspace();
//void kprint(const char *message);
//void kprint_char(char c);
//void kprint_uint64(uint64_t val);
//void kprint_uint32(uint32_t val);
//void kprint_uint16(uint16_t val);
//void kprint_uint8(uint8_t val);
_noreturn
void panic(char *str);
void panic(char *str, ...);
+55 -2
View File
@@ -1,5 +1,7 @@
#include <malloc.h>
#include <byteswap.h>
#include <string.h>
#include <stdio.h>
#include "dwarf.h"
#include "../elf.h"
#include "../console.h"
@@ -7,12 +9,18 @@
#define KERNEL_BASE 0xC0100000
void dwarf_find_file(uintptr_t address) {
FILE *file;
}
void *dwarf_find_debug_info(FATFS *fs) {
FRESULT ret;
FILINFO f_info;
FIL file;
void *header_ptr = NULL;
void *sh_table_ptr = NULL;
void *sh_table_str_ptr = NULL;
void *debug_line_ptr = NULL;
uint32_t read = 0;
ret = f_stat("kernel.bin", &f_info);
@@ -23,6 +31,8 @@ void *dwarf_find_debug_info(FATFS *fs) {
size_t header_size = sizeof(elf_header_t);
header_ptr = malloc(header_size);
if (header_ptr == NULL) goto fail;
ret = f_read(&file, header_ptr, header_size, &read);
if (ret != FR_OK || read != header_size) goto fail;
@@ -36,11 +46,52 @@ void *dwarf_find_debug_info(FATFS *fs) {
header->section_header_num_entries;
kprint("sh_table_size = "); kprint_uint16(sh_table_size); kprint_char('\n');
sh_table_ptr = malloc(sh_table_size);
if (sh_table_ptr == NULL) goto fail;
ret = f_read(&file, sh_table_ptr, sh_table_size, &read);
if (ret != FR_OK || read != sh_table_size) goto fail;
elf_section_header_t *section = elf_find_section(header, sh_table_ptr, ELF_SHT_STRTAB);
kprint_uint32((uintptr_t) section);
elf_section_header_t *sh_table_str_section = elf_get_section(header, sh_table_ptr, header->section_header_section_names_idx);
if (sh_table_str_section == NULL || sh_table_str_section->size > UINT16_MAX) goto fail;
ret = f_lseek(&file, sh_table_str_section->offset);
if (ret != FR_OK) goto fail;
uint16_t sh_table_str_size = (uint16_t) sh_table_str_section->size;
kprint("sh_table_str_size = "); kprint_uint16(sh_table_str_size); kprint_char('\n');
sh_table_str_ptr = malloc(sh_table_str_size);
if (sh_table_str_ptr == NULL) goto fail;
ret = f_read(&file, sh_table_str_ptr, sh_table_str_size, &read);
if (ret != FR_OK || read != sh_table_str_size) goto fail;
// elf_print_sections(header, sh_table_ptr, sh_table_str_ptr);
elf_section_header_t *debug_line_section = NULL;
for (uint16_t i = 0; i < header->section_header_num_entries; ++i) {
elf_section_header_t *section_header = sh_table_ptr + header->section_header_entry_size * i;
char *name = sh_table_str_ptr + section_header->name;
if (strcmp(name, ".debug_line") == 0) {
debug_line_section = section_header;
break;
}
}
if (debug_line_section == NULL || debug_line_section->size > UINT16_MAX) goto fail;
ret = f_lseek(&file, debug_line_section->offset);
if (ret != FR_OK) goto fail;
uint16_t debug_line_section_size = (uint16_t) debug_line_section->size;
kprint("debug_line_section_size = "); kprint_uint16(debug_line_section_size); kprint_char('\n');
debug_line_ptr = malloc(debug_line_section_size);
if (debug_line_ptr == NULL) goto fail;
ret = f_read(&file, debug_line_ptr, debug_line_section_size, &read);
if (ret != FR_OK || read != debug_line_section_size) goto fail;
dwarf_debug_line_header_t *debug_line_header = debug_line_ptr;
kprint_uint32(debug_line_header->length);
kprint_char('\n');
goto end;
@@ -55,5 +106,7 @@ void *dwarf_find_debug_info(FATFS *fs) {
f_close(&file);
free(header_ptr);
free(sh_table_ptr);
free(sh_table_str_ptr);
free(debug_line_ptr);
return NULL;
}
+3 -2
View File
@@ -2,7 +2,7 @@
#include <common.h>
typedef struct _packed {
struct _packed dwarf_debug_line_header {
uint32_t length;
uint16_t version;
uint32_t header_length;
@@ -12,4 +12,5 @@ typedef struct _packed {
uint8_t line_range;
uint8_t opcode_base;
uint8_t std_opcode_lengths[12];
} dwarf_debug_line_header;
};
typedef struct dwarf_debug_line_header dwarf_debug_line_header_t;
+3 -1
View File
@@ -30,7 +30,9 @@ int vga_print_char(char c, int col, int row, char attr) {
if (col >= 0 && row >= 0) offset = vga_get_offset(col, row);
else offset = vga_get_cursor_offset();
if (c == '\n') {
if (c == '\b') {
offset--;
} else if (c == '\n') {
row = vga_get_offset_row(offset);
offset = vga_get_offset(0, row + 1);
} else {
+43 -4
View File
@@ -1,7 +1,8 @@
#include "elf.h"
#include "console.h"
#include <byteswap.h>
#include <string.h>
#include <stdio.h>
#define ELF_DEBUG
@@ -68,12 +69,50 @@ elf_section_header_t *elf_find_section(elf_header_t *header,
elf_section_header_t *sht_start,
elf_section_header_type_t type) {
uint16_t num_entries = header->section_header_num_entries;
kprint("starting scan @ "); kprint_uint32((uintptr_t) sht_start); kprint_char('\n');
for (uint16_t i = 0; i < num_entries; ++i) {
elf_section_header_t *section_header = (void *) sht_start + header->section_header_entry_size * i;
kprint("scanning sect @ "); kprint_uint32((uintptr_t) section_header);
kprint(", type "); kprint_uint32(section_header->type); kprint_char('\n');
if (section_header->type == type) return section_header;
}
return NULL;
}
elf_section_header_t *elf_get_section(elf_header_t *header,
elf_section_header_t *sht_start,
uint16_t index) {
uint16_t num_entries = header->section_header_num_entries;
if (index > num_entries - 1) return NULL;
return (void *) sht_start + header->section_header_entry_size * index;
}
static const char* elf_section_type(elf_section_header_type_t type) {
switch (type) {
case ELF_SHT_NULL: return "SHT_NULL";
case ELF_SHT_PROGBITS: return "SHT_PROGBITS";
case ELF_SHT_SYMTAB: return "SHT_SYMTAB";
case ELF_SHT_STRTAB: return "SHT_STRTAB";
case ELF_SHT_RELA: return "SHT_RELA";
case ELF_SHT_HASH: return "SHT_HASH";
case ELF_SHT_DYNAMIC: return "SHT_DYNAMIC";
case ELF_SHT_NOTE: return "SHT_NOTE";
case ELF_SHT_NOBITS: return "SHT_NOBITS";
case ELF_SHT_REL: return "SHT_REL";
case ELF_SHT_SHLIB: return "SHT_SHLIB";
case ELF_SHT_DYNSYM: return "SHT_DYNSYM";
case ELF_SHT_LOPROC: return "SHT_LOPROC";
case ELF_SHT_HIPROC: return "SHT_HIPROC";
case ELF_SHT_LOUSER: return "SHT_LOUSER";
case ELF_SHT_HIUSER: return "SHT_HIUSER";
default: return "UNKNOWN";
}
}
void elf_print_sections(elf_header_t *header, elf_section_header_t *sht_start, void *shstrtab_ptr) {
uint16_t num_entries = header->section_header_num_entries;
for (uint16_t i = 0; i < num_entries; ++i) {
elf_section_header_t *section_header = (void *) sht_start + header->section_header_entry_size * i;
if (section_header->type == ELF_SHT_NULL) continue; // Skip null header
printf("Section %d %s: offset "PRIx32", size "PRIx32", type %s\n",
i, (char *) shstrtab_ptr + section_header->name, section_header->offset,
section_header->size, elf_section_type(section_header->type));
}
}
+31 -2
View File
@@ -1,6 +1,7 @@
#pragma once
#include <common.h>
#include <stdio.h>
#define ELF_HEADER_MAGIC_LE ((uint32_t) 0x7F | 'E' << 8 | 'L' << 16 | 'F' << 24)
@@ -42,14 +43,29 @@ typedef enum elf_machine_type elf_machine_type_t;
_Static_assert(sizeof(elf_machine_type_t) == sizeof(uint16_t),
"elf_machine_type incorrect size");
enum elf_obj_type {
ELF_ET_NONE = 0,
ELF_ET_REL = 1,
ELF_ET_EXEC = 2,
ELF_ET_DYN = 3,
ELF_ET_CORE = 4,
ELF_ET_LOPROC = 0xFF00,
ELF_ET_HIPROC = 0xFFFF
};
typedef enum elf_obj_type elf_obj_type_t;
_Static_assert(sizeof(elf_obj_type_t) == sizeof(uint16_t),
"elf_obj_type incorrect size");
struct _packed elf_header {
uint32_t magic;
elf_header_arch_bits_t arch_bits;
elf_header_endianness_t endianness;
uint8_t elf_version;
uint8_t __padding[9];
uint16_t elf_type; // 1 = relocatable, 2 = executable, 3 = shared, 4 = core
elf_obj_type_t obj_type;
elf_machine_type_t machine_type;
uint32_t version; // ?????
uint32_t program_entry_offset;
uint32_t program_header_offset;
uint32_t section_header_offset;
@@ -63,7 +79,7 @@ struct _packed elf_header {
};
typedef struct elf_header elf_header_t;
_Static_assert(sizeof(elf_header_t) == 48,
_Static_assert(sizeof(elf_header_t) == 52,
"elf_header incorrect size");
enum elf_section_header_type {
@@ -103,6 +119,13 @@ struct _packed elf_section_header {
};
typedef struct elf_section_header elf_section_header_t;
struct elf_file {
FILE fd;
elf_header_t *header;
elf_section_header_t *sht_start;
};
typedef struct elf_file elf_file_t;
//_Static_assert(sizeof(elf_section_header_t) == 32,
// "elf_section_header incorrect size");
@@ -113,3 +136,9 @@ elf_header_t *read_elf_header(void *ptr);
elf_section_header_t *elf_find_section(elf_header_t *header,
elf_section_header_t *sht_start,
elf_section_header_type_t type);
elf_section_header_t *elf_get_section(elf_header_t *header,
elf_section_header_t *sht_start,
uint16_t index);
void elf_print_sections(elf_header_t *header, elf_section_header_t *sht_start, void *shstrtab_ptr);
+10 -8
View File
@@ -5,6 +5,8 @@
#ifndef FF_INTEGER
#define FF_INTEGER
#include <stdint.h>
#ifdef _WIN32 /* FatFs development platform */
#include <windows.h>
@@ -13,20 +15,20 @@ typedef unsigned __int64 QWORD;
#else /* Embedded platform */
/* These types MUST be 16-bit or 32-bit */
typedef int INT;
typedef unsigned int UINT;
typedef int32_t INT;
typedef uint32_t UINT;
/* This type MUST be 8-bit */
typedef unsigned char BYTE;
typedef uint8_t BYTE;
/* These types MUST be 16-bit */
typedef short SHORT;
typedef unsigned short WORD;
typedef unsigned short WCHAR;
typedef int16_t SHORT;
typedef uint16_t WORD;
typedef uint16_t WCHAR;
/* These types MUST be 32-bit */
typedef long LONG;
typedef unsigned long DWORD;
typedef int32_t LONG;
typedef uint32_t DWORD;
/* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */
typedef unsigned long long QWORD;
+2 -8
View File
@@ -1,3 +1,4 @@
#include <stdio.h>
#include "isr.h"
#include "console.h"
#include "drivers/ports.h"
@@ -10,14 +11,7 @@ void register_interrupt_handler(uint8_t n, isr_t handler) {
_unused
void isr_handler(registers_t regs) {
kprint("Received interrupt: ");
kprint_uint32(regs.int_no);
kprint(" (err: ");
kprint_uint32(regs.err_code);
kprint(") @ ");
kprint_uint32(regs.eip);
kprint_char('\n');
panic(NULL);
panic("Received interrupt: %lu (err: %lu) @ %p\n", regs.int_no, regs.err_code, (void *) regs.eip);
}
_unused
+7 -7
View File
@@ -10,7 +10,7 @@
#include "fatfs/ff.h"
#include <common.h>
#include <lzma.h>
#include <stdio.h>
// #define KDEBUG
@@ -25,16 +25,16 @@ void kernel_main(uint32_t multiboot_magic, void *multiboot_info) {
pci_init();
ata_init();
uint32_t i = UINT32_MAX / 2;
uint32_t i = UINT32_MAX / 16;
while(i--); // stall
kprint("Mounting drive 0... ");
printf("Mounting drive 0... ");
FATFS fs;
FRESULT ret = f_mount(&fs, "", 1);
if (ret == FR_OK) {
kprint("OK\n");
printf("OK\n");
} else {
kprint("fail\n");
printf("fail %d\n", ret);
}
#ifdef ENABLE_DWARF
@@ -42,7 +42,7 @@ void kernel_main(uint32_t multiboot_magic, void *multiboot_info) {
dwarf_find_debug_info(&fs);
#endif
clear_screen();
// clear_screen();
#ifdef KDEBUG
kprint("Initializing timer...\n");
@@ -70,4 +70,4 @@ void kernel_main(uint32_t multiboot_magic, void *multiboot_info) {
shell_read();
key_buffer_print();
}
}
}
+23 -67
View File
@@ -1,3 +1,4 @@
#include <stdio.h>
#include "multiboot.h"
#include "console.h"
@@ -7,94 +8,56 @@
extern void *malloc_memory_start;
extern void *malloc_memory_end;
struct multiboot_color
{
uint8_t red;
uint8_t green;
uint8_t blue;
};
void multiboot_init(uint32_t magic, void *info_ptr) {
if (magic != MULTIBOOT_MAGIC) {
panic("multiboot_magic: Invalid magic.\n");
panic("multiboot_magic: Invalid magic "PRIX32"\n", magic);
}
struct multiboot_info *info = (struct multiboot_info *) (info_ptr + PAGE_OFFSET);
kprint("multiboot_info = "); kprint_uint32((uintptr_t) info);
kprint("\nflags = "); kprint_uint32(info->flags); kprint_char('\n');
printf("multiboot_info = "PRIXPTR", flags = "PRIx32"\n", info, info->flags);
if (CHECK_FLAG(info->flags, MULTIBOOT_INFO_MEMORY)) {
malloc_memory_start = (void *) 0x100000 + PAGE_OFFSET + KERNEL_OFFSET;
// 1 MiB + (info->mem_upper * 1 KiB)
malloc_memory_end = malloc_memory_start + (info->mem_upper * 0x400) - KERNEL_OFFSET;
kprint("upper_memory_end = "); kprint_uint32((uintptr_t) malloc_memory_end);
kprint_char('\n');
printf("upper_memory_end = "PRIXPTR"\n", malloc_memory_end);
} else {
panic("multiboot: Memory information required");
}
if (CHECK_FLAG(info->flags, MULTIBOOT_INFO_BOOTDEV)) {
kprint("boot_device = "); kprint_uint32(info->boot_device);
kprint_char('\n');
printf("boot_device = "PRIx32"h\n", info->boot_device);
}
if (CHECK_FLAG(info->flags, MULTIBOOT_INFO_CMDLINE)) {
kprint("cmdline = "); kprint((char *) (info->cmdline + PAGE_OFFSET));
kprint_char('\n');
printf("cmdline = %s\n", (char *) (info->cmdline + PAGE_OFFSET));
}
if (CHECK_FLAG(info->flags, MULTIBOOT_INFO_MODS)) {
struct multiboot_mod_list *mod;
int i;
kprint("mods_count = "); kprint_uint32(info->mods_count);
kprint(", mods_addr = "); kprint_uint32(info->mods_addr);
kprint_char('\n');
printf("mods_count = "PRIu32", mods_addr = "PRIXUPTR"\n", info->mods_count, info->mods_addr);
for (i = 0, mod = (struct multiboot_mod_list *) (info->mods_addr + PAGE_OFFSET);
i < info->mods_count;
i++, mod++) {
kprint(" mod_start = "); kprint_uint32(mod->mod_start);
kprint(", mod_end = "); kprint_uint32(mod->mod_end);
kprint(", cmdline = "); kprint((char *) (mod->cmdline + PAGE_OFFSET));
kprint_char('\n');
printf(" mod_start = "PRIXUPTR", mod_end = "PRIXUPTR", cmdline = %s\n",
mod->mod_start, mod->mod_end, (char *) (mod->cmdline + PAGE_OFFSET));
}
}
/* Bits 4 and 5 are mutually exclusive! */
if (CHECK_FLAG(info->flags, MULTIBOOT_INFO_AOUT_SYMS) &&
CHECK_FLAG(info->flags, MULTIBOOT_INFO_ELF_SHDR)) {
panic("multiboot_info->flags: Both bits 4 and 5 are set.\n");
}
/* Is the symbol table of a.out valid? */
if (CHECK_FLAG(info->flags, MULTIBOOT_INFO_AOUT_SYMS)) {
struct multiboot_aout_symbol_table *aout_sym = &info->u.aout_sym;
kprint("multiboot_aout_symbol_table: tabsize = "); kprint_uint32(aout_sym->tabsize);
kprint(", strsize = "); kprint_uint32(aout_sym->strsize);
kprint(", addr = "); kprint_uint32(aout_sym->addr);
kprint_char('\n');
}
/* Is the section header table of ELF valid? */
if (CHECK_FLAG(info->flags, MULTIBOOT_INFO_ELF_SHDR)) {
struct multiboot_elf_section_header_table *elf_sec = &info->u.elf_sec;
kprint("multiboot_elf_sec: num = "); kprint_uint32(elf_sec->num);
kprint(", size = "); kprint_uint32(elf_sec->size);
kprint(", addr = "); kprint_uint32(elf_sec->addr);
kprint(", shndx = "); kprint_uint32(elf_sec->shndx);
kprint_char('\n');
printf("multiboot_elf_sec: num = "PRIu32", size = "PRIu32", addr = "PRIXUPTR", shndx = "PRIu32"\n",
elf_sec->num, elf_sec->size, elf_sec->addr, elf_sec->shndx);
}
/* Are mmap_* valid? */
if (CHECK_FLAG(info->flags, MULTIBOOT_INFO_MEM_MAP)) {
printf("mmap_addr = "PRIXUPTR", mmap_length = "PRIx32"\n", info->mmap_addr, info->mmap_length);
struct multiboot_mmap_entry *mmap;
kprint("mmap_addr = "); kprint_uint32(info->mmap_addr);
kprint(", mmap_length = "); kprint_uint32(info->mmap_length);
kprint_char('\n');
struct multiboot_mmap_entry *largest_available_entry = NULL;
for (mmap = (struct multiboot_mmap_entry *) (info->mmap_addr + PAGE_OFFSET);
(unsigned long) mmap < info->mmap_addr + PAGE_OFFSET + info->mmap_length;
@@ -105,28 +68,21 @@ void multiboot_init(uint32_t magic, void *info_ptr) {
largest_available_entry = mmap;
}
kprint(" size = "); kprint_uint32(mmap->size);
kprint(", base_addr = "); kprint_uint64(mmap->addr);
kprint(", length = "); kprint_uint64(mmap->len);
kprint(", type = "); kprint_uint32(mmap->type);
kprint_char('\n');
printf(" size = "PRIx32", base_addr = "PRIXUPTR64S", length = "PRIX64S", type = "PRIu32"\n",
mmap->size, mmap->addr, mmap->len, mmap->type);
}
if (largest_available_entry != NULL) {
// malloc_memory_start = (void *) (uint32_t) largest_available_entry->addr + PAGE_OFFSET + KERNEL_OFFSET;
// malloc_memory_end = malloc_memory_start + largest_available_entry->len - KERNEL_OFFSET;
kprint("malloc_memory_start = "); kprint_uint32((uintptr_t) malloc_memory_start);
kprint(", end = "); kprint_uint32((uintptr_t) malloc_memory_end);
kprint_char('\n');
malloc_memory_start = (void *) (uint32_t) largest_available_entry->addr + PAGE_OFFSET + KERNEL_OFFSET;
malloc_memory_end = malloc_memory_start + largest_available_entry->len - KERNEL_OFFSET;
printf("malloc_memory_start = "PRIXPTR", end = "PRIXPTR"\n", malloc_memory_start, malloc_memory_end);
}
}
/* Check VGA framebuffer. */
if (CHECK_FLAG (info->flags, MULTIBOOT_INFO_FRAMEBUFFER_INFO)) {
kprint("framebuffer addr = "); kprint_uint64(info->framebuffer_addr);
kprint(", type = "); kprint_uint8(info->framebuffer_type);
kprint(", bpp = "); kprint_uint8(info->framebuffer_bpp);
kprint_char('\n');
printf("framebuffer_addr = "PRIXUPTR64", type = %d, bpp = %d\n",
info->framebuffer_addr, info->framebuffer_type, info->framebuffer_bpp);
switch (info->framebuffer_type) {
case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT:
@@ -134,11 +90,11 @@ void multiboot_init(uint32_t magic, void *info_ptr) {
break;
default:
break;
}
break;
}
} else {
console_set_vga_enabled(true); // FIXME
}
kprint("Multiboot info loaded.\n");
printf("Multiboot info loaded.\n");
}
+33 -79
View File
@@ -13,6 +13,7 @@
#include <malloc.h>
#include <vector.h>
#include <math.h>
#include <stdio.h>
#define KEY_BUFFER_INITIAL_SIZE 0x100
static char *key_buffer;
@@ -28,80 +29,34 @@ void command_lspci() {
for (pci_device_t *device = vc_vector_begin(pci_devices);
device != vc_vector_end(pci_devices);
device = vc_vector_next(pci_devices, device)) {
kprint_uint8(device->loc.bus);
kprint_char(':');
kprint_uint8(device->loc.device);
kprint_char('.');
kprint_uint8(device->loc.function);
kprint_char(' ');
kprint_uint16(device->class);
kprint_char('.');
kprint_uint8(device->prog_if);
kprint(": ");
kprint_uint16(device->vendor_id);
kprint_char(':');
kprint_uint16(device->device_id);
kprint_char(' ');
kprint(pci_class_name(device->class, device->revision_id));
if (device->revision_id) {
kprint(" (rev ");
kprint_uint8(device->revision_id);
kprint_char(')');
}
kprint_char('\n');
printf("%d:%d.%d %04X.%02X: %04X:%04X | %s",
device->loc.bus, device->loc.device, device->loc.function,
device->class, device->prog_if, device->vendor_id, device->device_id,
pci_class_name(device->class, device->revision_id));
if (device->revision_id) printf(" (rev %d)\n", device->revision_id);
else printf("\n");
if (device->bar0) {
kprint(" BAR0 = ");
kprint_uint32(device->bar0);
kprint_char('\n');
}
if (device->bar1) {
kprint(" BAR1 = ");
kprint_uint32(device->bar1);
kprint_char('\n');
}
if (device->bar2) {
kprint(" BAR2 = ");
kprint_uint32(device->bar2);
kprint_char('\n');
}
if (device->bar3) {
kprint(" BAR3 = ");
kprint_uint32(device->bar3);
kprint_char('\n');
}
if (device->bar4) {
kprint(" BAR4 = ");
kprint_uint32(device->bar4);
kprint_char('\n');
}
if (device->bar5) {
kprint(" BAR5 = ");
kprint_uint32(device->bar5);
kprint_char('\n');
}
if (device->bar0) printf(" BAR0 = "PRIXUPTR"\n", device->bar0);
if (device->bar1) printf(" BAR1 = "PRIXUPTR"\n", device->bar1);
if (device->bar2) printf(" BAR2 = "PRIXUPTR"\n", device->bar2);
if (device->bar3) printf(" BAR3 = "PRIXUPTR"\n", device->bar3);
if (device->bar4) printf(" BAR4 = "PRIXUPTR"\n", device->bar4);
if (device->bar5) printf(" BAR5 = "PRIXUPTR"\n", device->bar5);
}
kprint_char('\n');
}
void command_lsata() {
for (uint8_t i = 0; i < 4; i++) {
if (ide_devices[i].reserved == 1) {
kprint_uint8(i);
kprint(": ");
kprint((const char *[]) {"ATA", "ATAPI"}[ide_devices[i].type]);
kprint(" Drive ");
kprint_uint32(ide_devices[i].size / 1024 / 1024 / 2);
kprint("GB - ");
kprint(ide_devices[i].model);
kprint_char('\n');
const char *type_str = ((const char *[]) {"ATA ", "ATAPI"}[ide_devices[i].type]);
printf("%d: %s | %016lu sectors | %s\n", i, type_str, ide_devices[i].size, ide_devices[i].model);
}
}
kprint_char('\n');
}
static void shell_callback(char *input) {
kprint_char('\n');
printf("\n");
unsigned char ret = 1;
bool save = true;
if (strcmp(input, "exit") == 0 ||
@@ -112,11 +67,10 @@ static void shell_callback(char *input) {
reboot();
} else if (strcmp(input, "clear") == 0) {
clear_screen();
kprint("# ");
printf("# ");
return;
} else if (strncmp(input, "echo ", 5) == 0) {
kprint(input + 5);
kprint_char('\n');
printf("%s\n", input + 5);
ret = 0;
} else if (strcmp(input, "memdbg") == 0) {
print_chunk_debug(NULL, true);
@@ -132,8 +86,7 @@ static void shell_callback(char *input) {
for (char **i = vc_vector_begin(shell_history);
i != vc_vector_end(shell_history);
i = vc_vector_next(shell_history, i)) {
kprint(*i);
kprint_char('\n');
printf("%s\n", *i);
}
ret = 0;
} else if (strcmp(input, "test vector") == 0) {
@@ -142,9 +95,7 @@ static void shell_callback(char *input) {
ret = (unsigned char) !fatfs_test();
} else if (strcmp(input, "test") == 0 ||
strncmp(input, "test ", 5) == 0) {
kprint("Available tests:\n");
kprint(" vector\n");
kprint(" fatfs\n");
printf("Available tests:\n vector\n fatfs\n");
} else if (strcmp(input, "lspci") == 0) {
command_lspci();
ret = 0;
@@ -152,9 +103,8 @@ static void shell_callback(char *input) {
command_lsata();
ret = 0;
}
(void) (ret);
// kprint_uint32(ret);
kprint("# ");
printf("%d # ", ret);
fflush(stdout);
if (save && input[0] != '\0') {
char *value = strdup(input);
@@ -169,7 +119,8 @@ static void shell_history_free_func(void *data) {
void shell_init() {
shell_history = vc_vector_create(0x100, sizeof(char *), shell_history_free_func);
init_keyboard();
kprint("# ");
printf("# ");
fflush(stdout);
}
void shell_read() {
@@ -241,23 +192,26 @@ void key_buffer_clear() {
void key_buffer_set(char *input) {
while (key_buffer_used--) {
kprint_backspace();
printf("\b \b");
}
key_buffer_used = strlen(input);
key_buffer = realloc(key_buffer, max(key_buffer_used + 1, KEY_BUFFER_INITIAL_SIZE));
key_buffer = realloc(key_buffer, MAX(key_buffer_used + 1, KEY_BUFFER_INITIAL_SIZE));
if (key_buffer == NULL) return; // return error of some sort?
strncpy(key_buffer, input, key_buffer_used + 1);
key_buffer_printed = 0;
key_buffer_print();
}
void key_buffer_print() {
while (key_buffer_printed < key_buffer_used) {
kprint_char(key_buffer[key_buffer_printed++]);
if (key_buffer_printed < key_buffer_used) {
fwrite(key_buffer + key_buffer_printed, key_buffer_used - key_buffer_printed, 1, stdout);
key_buffer_printed = key_buffer_used;
}
while (key_buffer_printed > key_buffer_used) {
kprint_backspace();
printf("\b \b");
key_buffer_printed--;
}
fflush(stdout);
}
void key_buffer_return() {
+1 -1
View File
@@ -46,7 +46,7 @@ bool fatfs_test() {
kprint_char('\n');
end:
if (buff != NULL) free(buff);
free(buff);
f_close(&file);
f_unmount("");
return ret == FR_OK;
+2 -1
View File
@@ -11,4 +11,5 @@ if (CMAKE_HOST_APPLE)
endif ()
include_directories(${CMAKE_SOURCE_DIR}/libc)
add_library(c STATIC string malloc math vector byteswap)
add_library(c STATIC string malloc math vector byteswap ctype.h errno wchar stdio.c stdio.h
stdio/printf stdio/fprintf stdio/snprintf stdio/vfprintf stdio/vsnprintf)
+3 -1
View File
@@ -9,4 +9,6 @@
#ifdef __GNUC__
#define _unused __attribute__((unused))
#define _packed __attribute__((packed))
#endif
#endif
#define off_t uint64_t
+29
View File
@@ -0,0 +1,29 @@
#pragma once
int isalnum(int);
int isalpha(int);
int isblank(int);
int iscntrl(int);
int isdigit(int);
int isgraph(int);
int islower(int);
int isprint(int);
int ispunct(int);
int isspace(int);
int isupper(int);
int isxdigit(int);
int tolower(int);
int toupper(int);
static __inline int __isspace(int _c)
{
return _c == ' ' || (unsigned)_c-'\t' < 5;
}
#define isalpha(a) (0 ? isalpha(a) : (((unsigned)(a)|32)-'a') < 26)
#define isdigit(a) (0 ? isdigit(a) : ((unsigned)(a)-'0') < 10)
#define islower(a) (0 ? islower(a) : ((unsigned)(a)-'a') < 26)
#define isupper(a) (0 ? isupper(a) : ((unsigned)(a)-'A') < 26)
#define isprint(a) (0 ? isprint(a) : ((unsigned)(a)-0x20) < 0x5f)
#define isgraph(a) (0 ? isgraph(a) : ((unsigned)(a)-0x21) < 0x5e)
#define isspace(a) __isspace(a)
+5
View File
@@ -0,0 +1,5 @@
#include "errno.h"
char *strerror(int errno) {
return "ERROR"; // FIXME
}
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#define EINVAL 22
#define EOVERFLOW 75
#define EILSEQ 84
extern int errno; // FIXME for threading
char *strerror(int errno);

Some files were not shown because too many files have changed in this diff Show More