Mathieu Serandour 1 year ago
parent
commit
578920dcf0
  1. 1
      .gitignore
  2. 5
      Makefile
  3. 28
      kernel/Makefile
  4. 13
      kernel/acpi/acpi.c
  5. 3
      kernel/acpi/acpi.h
  6. 71
      kernel/acpi/lai.c
  7. 2
      kernel/drivers/nvme.h
  8. 93
      kernel/drivers/pcie.c
  9. 7
      kernel/drivers/pcie.h
  10. 28
      kernel/drivers/terminal/terminal.c
  11. 20
      kernel/entry.c
  12. 24
      kernel/memory/heap.c
  13. 1
      lai

1
.gitignore

@ -6,3 +6,4 @@ limine-bootloader/
include_cp
*.elf
qemu.log
lai/

5
Makefile

@ -10,7 +10,7 @@ USED_LOOPBACK := /dev/loop2
LIMINE_INSTALL := ./limine-bootloader/limine-install-linux-x86_64
QEMU_PATH := qemu-system-x86_64
QEMU_PATH := qemu-system-x86_64 -accel kvm
QEMU_ARGS := -monitor stdio \
-bios /usr/share/ovmf/OVMF.fd \
@ -19,7 +19,8 @@ QEMU_ARGS := -monitor stdio \
-vga virtio \
-no-reboot \
-D qemu.log \
-drive format=raw,file=
-device nvme,drive=NVME1,serial=nvme-1 \
-drive format=raw,if=none,id=NVME1,file=
# -usb \
# -device usb-host \

28
kernel/Makefile

@ -7,25 +7,30 @@ CFLAGS = -Wall -Wextra -O3 -pipe
INTERNALLDFLAGS := -Tlinker.ld \
-nostdlib \
-Wl,--export-dynamic \
-Wl,--export-dynamic \
-zmax-page-size=0x1000 \
-static \
-pie \
-ztext
# ,--dynamic-linker
INTERNALCFLAGS := -mgeneral-regs-only \
-ffreestanding \
-mno-red-zone \
-mno-80387 \
-fno-omit-frame-pointer \
-std=gnu11 \
-Wall -Wextra \
INTERNALCFLAGS := -mgeneral-regs-only \
-ffreestanding \
-mno-red-zone \
-mno-80387 \
-fno-omit-frame-pointer\
-std=gnu11 \
-Wall -Wextra \
-fcompare-debug-second \
-I/opt/cross/include/ \
-I../lai/include \
-fpie \
# -D BIGGER_FONT
-D BIGGER_FONT
LAI_FILE := ../lai/lai.elf
CFILES := $(shell find ./ -type f -name '*.c')
SFILES := $(shell find ./ -type f -name '*.s')
OBJ := $(SFILES:.s=.s.o) $(CFILES:.c=.c.o)
@ -39,9 +44,10 @@ all: $(KERNEL)
$(KERNEL): $(OBJ) $(LDSCRIPT)
$(CC) $(INTERNALLDFLAGS) $(OBJ) -o $@
$(CC) $(INTERNALLDFLAGS) $(OBJ) $(LAI_FILE) -o $@
%.c.o: %.c

13
kernel/acpi/acpi.c

@ -2,6 +2,7 @@
#include <stdint.h>
#include <stdbool.h>
#include "acpi.h"
#include "../lib/common.h"
#include "../lib/assert.h"
@ -20,6 +21,8 @@ static void* apic_config_base, *hpet_config_space;
// defined in pcie.c
extern struct PCIE_Descriptor pcie_descriptor;
static const struct XSDT* xsdt;
static bool __ATTR_PURE__ checksum(const void* table, size_t size) {
uint8_t sum = 0;
@ -36,11 +39,14 @@ static void parse_hpet(const struct HPET* table);
static void parse_fadt(const struct ACPISDTHeader* table);
static void parse_pcie(const struct PCIETable* table);
const struct XSDT* get_xsdt_location(void) {
return xsdt;
}
void read_acpi_tables(const void* rsdp_location) {
const struct RSDPDescriptor20* rsdpd = rsdp_location;
assert(rsdpd->firstPart.revision >= 2);
// checksum for xsdt
@ -49,7 +55,7 @@ void read_acpi_tables(const void* rsdp_location) {
// lets parse it!!
const struct XSDT* xsdt = (void *)rsdpd->xsdtAddress;
xsdt = (void *)rsdpd->xsdtAddress;
size_t n_entries = (xsdt->header.length - sizeof(xsdt->header)) / sizeof(void*);
@ -141,7 +147,6 @@ static void parse_madt(const struct MADT* table) {
break;
case APIC_TYPE_IO_INTERRUPT_SOURCE_OVERRIDE:
{
log_debug("ISSOU");
// const struct MADT_ioapic_interrupt_source_override_entry* entry = ptr;
}
break;
@ -180,7 +185,7 @@ static void parse_madt(const struct MADT* table) {
static void parse_pcie(const struct PCIETable* table) {
// fill the pcie driver's descriptor
size_t size = (table->header.length-sizeof(table->header));
size_t size = (table->header.length-sizeof(struct ACPISDTHeader)-8);
pcie_descriptor.size = size / sizeof(struct PCIE_segment_group_descriptor);

3
kernel/acpi/acpi.h

@ -5,5 +5,6 @@
read RSDP, XSDP, MADT, FADT
*/
void read_acpi_tables(const void* rsdp_location);
const struct XSDT* get_xsdt_location(void);
void map_acpi_mmios(void);
void map_acpi_mmios(void);

71
kernel/acpi/lai.c

@ -0,0 +1,71 @@
#include <lai/host.h>
// this file impelments the functions needed
// by the LAI library
#include "../lib/panic.h"
#include "../lib/logging.h"
#include "../memory/heap.h"
#include "acpitables.h"
// OS-specific functions.
void *laihost_malloc(size_t s) {
return malloc(s);
}
void *laihost_realloc(void* p, size_t s) {
return realloc(p, s);
}
void laihost_free(void* p) {
free(p);
}
void laihost_log(int level, const char * msg) {
if(level == LAI_DEBUG_LOG)
log_debug("LAI: %s", msg);
else
log_warn ("LAI: %s", msg);
}
void laihost_panic(const char* msg) {
char buff[1024];
sprintf(buff, "LAI: %s", msg);
panic(buff);
}
// only called early:
void *laihost_scan(char * name, size_t c) {
const struct XSDT* xsdt = get_xsdt_location();
size_t n_entries = (xsdt->header.length - sizeof(xsdt->header)) / sizeof(void*);
const uint32_t* raw = (uint32_t*)name;
for(size_t i = 0; i < n_entries; i++) {
const struct ACPISDTHeader* table = xsdt->entries[i];
if(*raw == table->signature.raw)
return table;
}
// no such table
return NULL;
}
void *laihost_map(size_t, size_t);
void laihost_outb(uint16_t, uint8_t);
void laihost_outw(uint16_t, uint16_t);
void laihost_outd(uint16_t, uint32_t);
uint8_t laihost_inb(uint16_t);
uint16_t laihost_inw(uint16_t);
uint32_t laihost_ind(uint16_t);
void laihost_pci_writeb(uint16_t, uint8_t, uint8_t, uint8_t, uint16_t, uint8_t);
uint8_t laihost_pci_readb(uint16_t, uint8_t, uint8_t, uint8_t, uint16_t);
void laihost_pci_writew(uint16_t, uint8_t, uint8_t, uint8_t, uint16_t, uint16_t);
uint16_t laihost_pci_readw(uint16_t, uint8_t, uint8_t, uint8_t, uint16_t);
void laihost_pci_writed(uint16_t, uint8_t, uint8_t, uint8_t, uint16_t, uint32_t);
uint32_t laihost_pci_readd(uint16_t, uint8_t, uint8_t, uint8_t, uint16_t);
void laihost_sleep(uint64_t);
void laihost_handle_amldebug(lai_variable_t *);

2
kernel/drivers/nvme.h

@ -0,0 +1,2 @@
#pragma once

93
kernel/drivers/pcie.c

@ -12,7 +12,10 @@ struct PCIE_configuration_space {
volatile uint16_t deviceID;
uint16_t unused0;
uint16_t unused1;
volatile uint32_t class_code_revID;
volatile uint8_t revID;
volatile uint8_t progIF;
volatile uint8_t subclasscode;
volatile uint8_t classcode;
volatile uint32_t infos;
volatile uint64_t bar[3];
volatile uint32_t cardbud_cis_ptr;
@ -71,10 +74,10 @@ static struct PCIE_configuration_space* __attribute__((pure)) get_config_space_b
}
static int __attribute__((pure)) check_function(unsigned bus, unsigned device, unsigned func) {
static int __attribute__((pure)) get_vendorID(unsigned bus, unsigned device, unsigned func) {
struct PCIE_configuration_space* config_space = get_config_space_base(bus,device,func);
return config_space->vendorID != 0xffff;
return config_space->vendorID;
}
@ -84,12 +87,12 @@ struct pcie_device_descriptor {
};
// array of all installed devices' functions
static struct pcie_device_descriptor* installed_devices = NULL;
static size_t n_installed_devices = 0;
static struct pcie_device_descriptor* found_devices = NULL;
static size_t n_found_devices = 0;
/**
* constructs the installed_devices array
* constructs the found_devices array
*/
static void scan_devices(void) {
@ -106,17 +109,13 @@ static void scan_devices(void) {
// count the number of devices
void insert(
unsigned bus,
unsigned device,
unsigned func,
struct PCIE_configuration_space* config_space
) {
current->next = malloc(
sizeof(struct device_desc_node)
);
log_debug("device %u:%u - %u", bus, device, func);
unsigned bus,
unsigned device,
unsigned func,
struct PCIE_configuration_space* config_space
)
{
current->next = malloc(sizeof(struct device_desc_node));
current = current->next;
current->next = NULL;
@ -127,7 +126,7 @@ static void scan_devices(void) {
current->e.function = func;
current->e.config_space = config_space;
n_installed_devices++;
n_found_devices++;
}
@ -136,27 +135,39 @@ static void scan_devices(void) {
// if the first function doesn't exist, so does
// the device
if(!check_function(bus,device, 0))
uint16_t vendorID = get_vendorID(bus,device, 0);
if(vendorID == 0xFFFF)
continue;
insert(bus, device, 0, get_config_space_base(bus,device,0));
insert(bus,
device,
0,
get_config_space_base(bus,device,0)
);
for(unsigned func = 1; func < 8; func++)
if(check_function(bus,device, func))
insert(bus, device, func, get_config_space_base(bus,device,func));
for(unsigned func = 1; func < 8; func++) {
if(get_vendorID(bus,device, func) != vendorID)
continue;
insert(bus,
device,
func,
get_config_space_base(bus,device,func)
);
}
}
}
// now create the final array
installed_devices = malloc(
n_installed_devices
found_devices = malloc(
n_found_devices
* sizeof(struct pcie_device_descriptor));
// now fill it and free the devices structure
struct pcie_device_descriptor* ptr = installed_devices;
struct pcie_device_descriptor* ptr = found_devices;
for(struct device_desc_node* device = ghost_node.next;
device != NULL;
@ -189,7 +200,7 @@ static void identity_map_possible_config_spaces(void) {
static void identity_unmap_possible_config_spaces(void) {
for(unsigned i = 0; i < pcie_descriptor.size; i++)
;// unmap_pages((uint64_t)pcie_descriptor.array[i].address, 256 * 32 * 8);
unmap_pages((uint64_t)pcie_descriptor.array[i].address, 256 * 32 * 8);
}
/**
@ -209,13 +220,33 @@ void pcie_init(void) {
max_bus = pcie_descriptor.array[i].end_bus;
}
log_debug("%u PCIE bus groups found", pcie_descriptor.size);
identity_map_possible_config_spaces();
scan_devices();
identity_unmap_possible_config_spaces();
for(unsigned i = 0; i < n_found_devices; i++) {
log_warn("%2x:%2x:%2x: %2x:%2x:%2x, rev %2x, "
"vendor 0x%4x",
found_devices[i].bus,
found_devices[i].device,
found_devices[i].function,
found_devices[i].config_space->classcode,
found_devices[i].config_space->subclasscode,
found_devices[i].config_space->progIF,
found_devices[i].config_space->revID,
found_devices[i].config_space->vendorID
);
}
identity_unmap_possible_config_spaces();
log_info("found %u PCI Express devices", n_found_devices);
}
log_info("found %u PCI Express devices", n_installed_devices);
void pcie_init_devices(void) {
}

7
kernel/drivers/pcie.h

@ -2,6 +2,7 @@
#include <stdint.h>
#include <stddef.h>
#include "../lib/assert.h"
struct PCIE_segment_group_descriptor {
void* address; // Base address
@ -12,7 +13,9 @@ struct PCIE_segment_group_descriptor {
uint8_t end_bus; // End PCI bus number
// decoded by this host bridge
uint32_t reserved;
};
} __attribute__((packed));
static_assert(sizeof(struct PCIE_segment_group_descriptor) == 16);
#define PCIE_SUPPORTED_SEGMENT_GROUPS 2
@ -29,6 +32,8 @@ extern struct PCIE_Descriptor pcie_descriptor;
void pcie_init(void);
void pcie_scan(void);
void pcie_init_devices(void);
typedef void (*driver_init_fun)(void* config_space);

28
kernel/drivers/terminal/terminal.c

@ -73,19 +73,19 @@ static unsigned timerID = INVALID_TIMER_ID;
static char* stream_buffer = NULL;
//static char* stream_buffer = NULL;
static unsigned stream_buffer_size = 0;
static volatile unsigned stream_buffer_content_size = 0;
//static unsigned stream_buffer_size = 0;
//static volatile unsigned stream_buffer_content_size = 0;
// should be called every UPDATE_PERIOD ms
// should execute in an IRQ
void terminal_update(void) {
return;
static unsigned update_cur_line = 0;
stream_buffer_content_size = 0;
if(need_refresh) {
@ -137,7 +137,7 @@ void terminal_install_early(void) {
margin_top = (screenImage->h - term_nlines * TERMINAL_FONTHEIGHT) / 2;
#endif
stream_buffer = malloc(ncols * term_nlines);
// stream_buffer = NULL;//malloc(ncols * term_nlines);
set_terminal_handler(empty_terminal_handler);
}
@ -145,7 +145,7 @@ void terminal_install_early(void) {
// finish intallation when memory
// is well initialized
void terminal_install_late(void) {
timerID = apic_create_timer(terminal_update, UPDATE_PERIOD_MS);
//timerID = apic_create_timer(terminal_update, UPDATE_PERIOD_MS);
charmap = loadBMP_24b_1b(&_binary_charmap_bmp);
@ -231,6 +231,7 @@ static void emplace_normal_char(char c) {
char_buffer[ncols * cur_line + cur_col] = make_Char(c);
struct Char* ch = &char_buffer[ncols * cur_line + cur_col];
cur_col += 1;
if(cur_col >= ncols)
@ -240,7 +241,6 @@ static void emplace_normal_char(char c) {
print_char(ch, cur_line - first_line, cur_col);
cur_col += 1;
}
@ -321,10 +321,6 @@ static void print_char(const struct Char* restrict c, int line, int col) {
margin_top + line * TERMINAL_LINE_HEIGHT);
#endif
//imageDraw(charmap, NULL, NULL);
//imageFillRect(c->bg_color, &interlineRect);
}
static void flush_screen(void) {
@ -339,7 +335,7 @@ static void flush_screen(void) {
}
/*
// add the string to the buffer
static void append_string(const char *string, size_t length) {
// atomic operation
@ -353,11 +349,11 @@ static void append_string(const char *string, size_t length) {
_sti();
}
*/
static void write_string(const char *string, size_t length) {
//need_refresh = false;
need_refresh = false;
for(;length>0;--length) {
char c = *string++;
@ -367,8 +363,8 @@ static void write_string(const char *string, size_t length) {
emplace_char(c);
}
//if(need_refresh)
// flush_screen();
if(need_refresh)
flush_screen();
}

20
kernel/entry.c

@ -6,6 +6,7 @@
#include "drivers/terminal/video.h"
#include "drivers/terminal/terminal.h"
#include "acpi/acpi.h"
#include "acpi/power.h"
#include "int/apic.h"
#include "int/idt.h"
#include "int/pic.h"
@ -193,22 +194,25 @@ void _start(struct stivale2_struct *stivale2_struct) {
puts(&_binary_bootmessage_txt);
asm volatile("hlt");
printf("boot logs:\n");
puts(log_get());
log_flush();
dump(boot_volume_tag, sizeof(struct stivale2_struct_tag_boot_volume), 8, DUMP_HEX8);
//log_info("boot volume: %x:%x:%x:%lx",
// boot_volume_tag->guid.a,
// boot_volume_tag->guid.b,
// boot_volume_tag->guid.c,
// *(uint64_t*)boot_volume_tag->guid.d);
//
//pcie_init();
pcie_init();
pcie_init_devices();
pic_init();
ps2kb_init();
void kbhandler(const struct kbevent* ev) {
if(ev->type == KEYRELEASED && ev->scancode == PS2KB_ESCAPE) {
shutdown();
}
};
ps2kb_set_event_callback(kbhandler);
hpet_init();
apic_setup_clock();

24
kernel/memory/heap.c

@ -257,7 +257,7 @@ void heap_init(void) {
}
void* malloc(size_t size) {
void* __attribute__((noinline)) malloc(size_t size) {
// align the size to assure that
// the whole structure is alligned
size = ((size + 7 ) / 8) * 8;
@ -274,7 +274,9 @@ void* malloc(size_t size) {
break;
}
else if(!seg->free || seg->size < size) {
assert(is_kernel_memory(seg));
if(!seg->free || seg->size < size) {
// this segment is not right, check the next one
pred = seg;
@ -287,7 +289,6 @@ void* malloc(size_t size) {
}
// we found a satisfying segment!
if(seg->size >= size + sizeof(seg_header) + MIN_SEGMENT_SIZE) {
// we don't take the whole space
@ -323,7 +324,6 @@ void* malloc(size_t size) {
// let's expand
expand_heap(MAX(size+sizeof(seg_header), MIN_EXPAND_SIZE));
// retrty now that we are sure that the memory is avaiable
return malloc(size);
}
@ -391,7 +391,7 @@ void* realloc(void* ptr, size_t size) {
// O(1) free
void free(void *ptr) {
void __attribute__((noinline)) free(void *ptr) {
seg_header* header = ptr - sizeof(seg_header);
assert(header->free == 0);
@ -407,17 +407,27 @@ void free(void *ptr) {
#ifndef NDEBUG
void print_heap(void) {
for(seg_header* seg = current_segment;
seg != NULL;
seg = seg->next) {
log_debug("%lx size=%x,free=%u", seg,seg->size, seg->free);
}
}
void malloc_test(void) {
void* arr[128];
uint64_t size = 5;
for(int j = 0; j < 100; j++) {
for(int i = 0; i < 128; i++) {
arr[i] = malloc(size % 1024);
size = (16807 * size) % ((1lu << 31) - 1);
}
for(int i = 0; i < 128; i++)
free(arr[i]);
}

1
lai

@ -0,0 +1 @@
Subproject commit bef3f0c6b2f72f82f573440bfdf73ebf7fc7b141
Loading…
Cancel
Save