backup 8.29.21

This commit is contained in:
Brett Weiland 2021-08-29 02:52:48 -05:00
parent dc0e84d577
commit 1f71b9576d
25 changed files with 507 additions and 378 deletions

View File

@ -1,205 +1,3 @@
thread 1
next
thread 1
step
print core_stacks
print core_stacks[0]
print core_stacks[1]
print core_stacks[2]
print core_stacks[3]
quit
c
c
quit
hb debug
c
c
next
info reg rax
thread 1
thread 2
info reg rax
print smp_bootstrap_stackarray
print *smp_bootstrap_stackarray
print/x *smp_bootstrap_stackarray
inf ore g rax
print smp_bootstrap_array
quit
hb debug
c
c
quit
hb debug
c
c
nexti
info reg ebx
info reg ebx
quit
hb debug
c
c
quit
hb debug
c
c
stepi
info reg ebx
stepi
stepi
info reg rsp
stepi
info reg esp
info reg rsp
x rbx
info reg rbx
print smp_bootstrap_stackarray
print/x *smp_bootstrap_stackarray
info reg ebx
quit
quit
stepi
info reg cl
info reg ecx
quit
next
quit
nexti
info reg ecx
stepi
info reg ebx
quit
c
quit
stepi
info reg ebx
stepi
info reg bl
print smp_bootstrap_bsp
info reg bl
stepi
info reg bl
info reg ebx
x 0x80f0
print (uint64_t *)0x80f0
print (uint64_t*)0x80f0
x 0x80f9
stepi
stepi
info reg rsp
print smp_bootstrap_stackarray
print/x *smp_bootstrap_stackarray
quit
info reg rax
info reg rax
x 0xbffde058
print smp_bootstrap_bsp
print &smp_bootstrap_bsp
print smp_bootstrap_bsp
x 0x80f1
print (uint64_t)*0x80f1
x smp_bootstrap_bsp
smp_bootstrap_bsp
print smp_bootstrap_bsp
smp_bootstrap_stackarray
print smp_bootstrap_stackarray
print *smp_bootstrap_stackarray
print smp_bootstrap_stackarray[0]
print/x smp_bootstrap_stackarray[0]
print/x smp_bootstrap_stackarray[1]
print/x smp_bootstrap_stackarray[0]
info reg rax
print smp_bootstrap_stackarray
quit
info reg rax
quit
next
stepi
quit
c
quit
c
stepi
quit
hb smp_trampoline
c
next
hb debug
c
quit
c
quit
c
quit
c
stepi
quit
c
quit
c
next
info reg rsp
thread 2
context
quit
quit
c
info reg cl
info reg ecx
quit
c
next
quit
info reg rax
c
info reg rax
stepi
info rax
inf oreg rax
info reg rax
info reg rbx
x 0xffff8000bffde058
x *0xffff8000bffde058
print *0xffff8000bffde058
print/x *0xffff8000bffde058
print/x (uint64_t)*0xffff8000bffde058
print/x (uint64_t)0xffff8000bffde058
print/x (uint64_t)*0xffff8000bffde058
print/x (uint64_t)0xffff8000bffde058
print/x (uint64_t)0xffff8000bffde058[1]
print ((uint64_t)0xffff8000bffde058)[1]
print ((uint64_t *)0xffff8000bffde058)[1]
print ((uint64_t *)0xffff8000bffde058)[0]
print ((uint64_t *)0xffff8000bffde058)[1]
print/x ((uint64_t *)0xffff8000bffde058)[1]
quit
c
nexti
quit
c
stepi
stepi
info thread 0
thread 1
c
quit
next
print cores_active
print cores.corecount
next
print cores.corecount
print cores_active
next
c
print cores_active
thread 0
print cores_active
thread 1
print cores_active
quit
c
stepi
info reg rax
thread 0 thread 0
thread 2 thread 2
print cores_active print cores_active
@ -254,3 +52,205 @@ c
c c
c c
quit quit
quit
print final_gdt_descriptor
print gdt
quit
quit
quit
nexti
thread 1
thread 23
thread 2
print final_gdt_descriptor.offset
qut
quit
context
disassemble
x/i 0x80dd
quit
c
c
c
quit
next
print gdt
print gdtr
next
print gdtr
print/x (void *)&gdtr
print/x *(void *)&gdtr
hexdump &gdtr
print/x gdtr
quit
c
quit
next
stepi
info reg rax
info reg rdx
print final_gdt_descriptor
print &final_gdt_descriptor
quit
quit
c
quit
c
thread 2
next
quit
c
thread
threads
info threads
thread 1
c
c
quit
c
quit
c
quit
hb klog.c
hb klog
hb klog_init
c
quit
hb init_klog
c
print sizeof(serial_ports)
print sizeof(serial_ports) / sizeof(uint16_t)
quit
c
quit
c
quit
c
quit
hb smp_trampoline.asm:163
c
print smp_kinit
x smp_kinit
next
info reg rax
x smp_kinit
nexti
x smp_kinit
info reg rax
quit
c
quit
c
quit
c
quit
c
quit
nexti
stepi
stepi
next
quit
b _putchar
c
stepi
next
c
c
quit
hb _putchar
c
c
next
step
print screen_buffer
x 0xffff8000000b80a0
0xffff800000000000
x 0xffff800000000000
quit
c
quit
b _putchar
c
c
step
print screen_buffer
stepi
c
d
c
quit
next
quit
b init_klog
c
next
print serial_ports[0]
print/x serial_ports[0]
next
quit
quit
c
quit
c
quit
c
quit
c
quit
c
quit
b init_klog
c
print sizeof(serial_ports) / sizeof(uint16_t)
next
print p
next
make
quit
b init_klog
c
next
step
b _putchar
c
step
step
print (char *)((uint64_t)VIDEO_BUFFER + ((on_line * 160) + (on_char * 2)))
print (char *)((uint64_t)0xb8000 + ((on_line * 160) + (on_char * 2)))
quit
c
quit
hb test_shit
c
c
c
c
c
c
c
c
c
c
c
c
quit
c
quit
quit
next
quit
quit
quit
info reg edx
nexti
info reg edx
quit
next
info reg ebx
quit
hb fuckyou
quit
c
info reg ebx
quit

View File

@ -1,7 +1,6 @@
[bits 16] [bits 16]
[extern _kernel_sector_size] [extern _kernel_sector_size]
[extern _bootloader_stage1_size] [extern _bootloader_stage1_size]
[extern _kernel_s1_loc]
jmp stage0 jmp stage0
times 3-($-$$) db 0x90 times 3-($-$$) db 0x90

View File

@ -1,4 +1,4 @@
[extern main] [extern kernel_init]
[extern _kernel_stack_loc] [extern _kernel_stack_loc]
[extern _kernel_page_size] [extern _kernel_page_size]
enter_longmode: enter_longmode:
@ -68,13 +68,14 @@ mov cr4, eax
;If it's not and we enable it, it will cause pagefaults on read ;If it's not and we enable it, it will cause pagefaults on read
mov eax, 0x80000001 mov eax, 0x80000001
cpuid cpuid
and edx, 1 << 20 mov ebx, edx
shr edx, 9 and ebx, 1 << 20
shr ebx, 9
mov ecx, 0xc0000080 mov ecx, 0xc0000080
rdmsr rdmsr
or eax, 1 << 8 | 1 << 11 or eax, 1 << 8
or eax, edx or eax, ebx
wrmsr wrmsr
mov eax, cr0 mov eax, cr0
@ -90,7 +91,7 @@ enter_kernel:
bits 64 bits 64
mov rbp, 0 mov rbp, 0
mov rsp, _kernel_stack_loc mov rsp, _kernel_stack_loc
mov rax, QWORD main mov rax, QWORD kernel_init
;push QWORD 0 ;push QWORD 0
jmp rax jmp rax
jmp $ jmp $

View File

@ -1,8 +1,8 @@
target remote localhost:1234 target remote localhost:1234
symbol-file debug/debug_syms.o symbol-file debug/debug_syms.o
hb debug
hb smp_boot
hb fuckyou
hb kernel_init
define cs2bs define cs2bs

11
src/include/addr.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef ADDR_INCLUDED
#define ADDR_INCLUDED
#include <stdint.h>
//couldn't get symbols working, fix later
#define PA_OFFSET 0xffff800000000000
#define TXT_OFFSET 0xffffffff80000000
#define PHYS_TO_VIRT(addr) ((void *)((uintptr_t)(addr) | PA_OFFSET))
#endif

View File

@ -7,7 +7,7 @@
void usleep(unsigned int us); void usleep(unsigned int us);
void init_interrupts(); void init_interrupts_bsp();
typedef uint32_t *lapic_t; typedef uint32_t *lapic_t;

View File

@ -2,14 +2,10 @@
#define KERNEL #define KERNEL
#define PA_OFFSET 0xffff800000000000
#define TXT_OFFSET 0xffffffff80000000
#define PHYS_TO_VIRT(addr) ((void *)(addr) + PA_OFFSET) void smp_kinit();
void kernel_init();
#define DEV_EMAIL "brett_weiland@bpcspace.com" void kmain();
void multicore_main();
#endif #endif

View File

@ -1,26 +1,19 @@
//these com values are just guesses! Figure out how to find em later if you want
#ifndef _SERIAL_H_ #ifndef _SERIAL_H_
#define _SERIAL_H_ #define _SERIAL_H_
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#define COM1 0x3f8
#define COM2 0x2f8
#define COM3 0x3e8
#define COM4 0x2e8
bool init_serial(uint16_t port);
void init_klog();
void serial_out(uint16_t port, char *string); void serial_out(uint16_t port, char *string);
void _putchar_serial(uint16_t port, char character); void _putchar_serial(uint16_t port, char character);
void move_cursor(unsigned int x, unsigned int y); void move_cursor(unsigned int x, unsigned int y);
//TODO fix shitty header
void _putchar_screen(char character);
void clear_screen(); void clear_screen();

View File

@ -52,6 +52,9 @@ void panic(int reason, void *frame_p, struct registers *regs);
#define KERNEL_PANIC_INVALID_RSDT 35 #define KERNEL_PANIC_INVALID_RSDT 35
#define KERNEL_PANIC_INVALID_IOAPIC_VEC 36 #define KERNEL_PANIC_INVALID_IOAPIC_VEC 36
#define KERNEL_PANIC_HPET_REQUIRED 37 #define KERNEL_PANIC_HPET_REQUIRED 37
#define KERNEL_PANIC_SMP_FAILED 38
#define DEV_EMAIL "brett_weiland@bpcspace.com"

View File

@ -61,6 +61,7 @@ void _putchar(char character);
int printf_(const char* format, ...); int printf_(const char* format, ...);
/** /**
* Tiny sprintf implementation * Tiny sprintf implementation
* Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING (V)SNPRINTF INSTEAD! * Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING (V)SNPRINTF INSTEAD!

17
src/include/smp_sync.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef SMP_SYNC_INCLUDED
#define SMP_SYNC_INCLUDED
static inline void lock(uint8_t *lock) {
asm("mov al, 1\n"
"spinlock:\n"
"lock xchgb [%0], al\n"
"test al, al\n"
"jnz spinlock\n"
::"r"(lock):"al");
}
static inline void unlock(uint8_t *lock) {
asm("lock andb [%0], 0"::"r"(lock));
}
#endif

Binary file not shown.

View File

@ -1,13 +1,13 @@
#include <acpi.h> #include <acpi.h>
#include <stdint.h> #include <stdint.h>
#include <printf.h> #include <printf.h>
#include <kernel.h>
#include <stdbool.h> #include <stdbool.h>
#include <kernel.h> #include <addr.h>
#include <io.h> #include <io.h>
#include <int.h> #include <int.h>
#include <libc.h> #include <libc.h>
#include <panic.h> #include <panic.h>
#include <addr.h>
//finding rsdp //finding rsdp

View File

@ -4,7 +4,7 @@
#include <paging.h> #include <paging.h>
#include <printf.h> #include <printf.h>
#include <isv.h> #include <isv.h>
#include <kernel.h> #include <addr.h>
#include <libc.h> #include <libc.h>
#include <madt.h> #include <madt.h>
#include <timer.h> #include <timer.h>
@ -44,7 +44,6 @@
.present = 1 \ .present = 1 \
}) })
#define GDT_ADDR (uint64_t)PHYS_TO_VIRT(0x7e22)
#define IOAPICR_VER 1 #define IOAPICR_VER 1
@ -74,18 +73,10 @@ struct idt_reg {
uint64_t offset; uint64_t offset;
} __attribute__((packed)); } __attribute__((packed));
struct gdt_reg {
uint16_t size;
uint64_t offset;
} __attribute__((packed));
struct idt_descriptor *idt; struct idt_descriptor *idt;
static struct idt_reg idtr; static struct idt_reg idtr;
struct gdt_reg gdtr = {
.size = 0x17,
.offset = GDT_ADDR
};
lapic_t lapic; //would make this static but it's needed by timer.c lapic_t lapic; //would make this static but it's needed by timer.c
@ -211,7 +202,7 @@ void init_exceptions() {
//void new_idt //void new_idt
void init_interrupts() { void init_interrupts_bsp() {
init_madt(); init_madt();
debug_madt(); debug_madt();
lapic = get_lapic(); lapic = get_lapic();
@ -232,9 +223,7 @@ void init_interrupts() {
bzero(&isr_bitmap, sizeof(isr_bitmap)); bzero(&isr_bitmap, sizeof(isr_bitmap));
isr_bitmap[0] = (((uint64_t)1 << 32) - 1); isr_bitmap[0] = (((uint64_t)1 << 32) - 1);
//set idt and new gdt asm("lidt [%0]\n"::"m"(idtr));
asm("lgdt [%0]\n"
"lidt [%1]\n":: "m"(gdtr), "m"(idtr));
//Spurrious Interrupt (permanent, required for APIC) //Spurrious Interrupt (permanent, required for APIC)
@ -251,3 +240,6 @@ void init_interrupts() {
init_timer(); init_timer();
asm("sti\n"); asm("sti\n");
} }
void smp_init_interrupts() {
}

View File

@ -1,12 +1,12 @@
#include <stdbool.h> #include <stdbool.h>
#include <smp.h> #include <smp.h>
#include <serial.h> #include <klog.h>
#include <printf.h> #include <printf.h>
#include <paging.h> #include <paging.h>
#include <video.h> #include <video.h>
#include <acpi.h> #include <acpi.h>
#include <panic.h> #include <panic.h>
#include <kernel.h> #include <addr.h>
#include <stdbool.h> #include <stdbool.h>
#include <int.h> #include <int.h>
#include <io.h> #include <io.h>
@ -19,31 +19,36 @@
//testing headers //testing headers
#include <testmalloc.h> #include <testmalloc.h>
void kmain() {
void multicore_main() { PANIC(KERNEL_PANIC_KERNEL_RETURNED);
printf("\nKernal started\n");
asm("cli\nhlt");
} }
void main() { void smp_kinit() {
#ifndef SCREEN_OUTPUT printf("\nKernal started on core\n"); //TODO get lapic working, then print core number
if(init_serial(COM1)) printf("\nKernal started on CPU 1!\n"); kmain();
#endif }
//TODO move to global constructors
void kernel_init() {
size_t pmap_size;
get_mem_capabilities(); get_mem_capabilities();
init_pmap(map_complete_physical()); pmap_size = map_complete_physical();
init_klog();
init_pmap(pmap_size);
printf("\nKernal started on CPU 1!\n");
find_root_sdp(); find_root_sdp();
debug_acpi(); debug_acpi();
init_interrupts(); init_interrupts_bsp();
randinit(); randinit();
smp_boot(); smp_boot();
fix_stack(); fix_stack();
unmap_lowmem(); //unmap_lowmem();
kmain();
PANIC(KERNEL_PANIC_KERNEL_RETURNED);
} }

View File

@ -1,57 +1,104 @@
#include <stdint.h> #include <stdint.h>
#include <serial.h>
#include <io.h> #include <io.h>
#include <printf.h> #include <printf.h>
#include <kernel.h> #include <addr.h>
#include <stdbool.h> #include <stdbool.h>
#include <libc.h> #include <libc.h>
#include <klog.h>
//README //right now, this program is simply for debuging.
//this file has some temporary workarounds until I get further into development //Later in development, we will hook it up to a TTY, impliment FCS, etc
//this isn't going to be the serial driver I end up keeping
#define VIDEO_BUFFER PHYS_TO_VIRT(0xb8000) #define VIDEO_BUFFER PHYS_TO_VIRT(0xb8000)
#define MAX_LOOPBACK_ATTEMPTS 20 #define MAX_LOOPBACK_ATTEMPTS 20
//later we'll set it up for interrupting instead of polling #define KLOG_COM1 0
bool init_serial(uint16_t port) { #define KLOG_COM2 1
outb_wait(port + 1, 0x00); #define KLOG_COM3 2
outb_wait(port + 2, 0x00); #define KLOG_COM4 3
outb_wait(port + 3, 0x80); #define KLOG_SCREEN 4
outb_wait(port + 0, 0x01); //here
outb_wait(port + 1, 0x00); static int debug_output = KLOG_SCREEN;
outb_wait(port + 3, 0x03);
outb_wait(port + 2, 0xc7); #define SERIAL_THR 0 //transmitter holding buffer
outb_wait(port + 4, 0x0b); #define SERIAL_RBR 1 //receiving holding buffer
outb_wait(port + 4, 0x1e); #define SERIAL_DLL 0 //divisor latch low byte
#define SERIAL_DLH 1 //divisor latch high byte
#define SERIAL_FCR 2
#define SERIAL_IIR 2
#define SERIAL_LCR 3
#define SERIAL_MCR 4
#define SERIAL_LSR 5
#define SERIAL_MSR 6
#define SERIAL_SR 7
#define COM1 0x3f8
#define COM2 0x2f8
#define COM3 0x3e8
#define COM4 0x2e8
uint16_t serial_ports[4] = {COM1, COM2, COM3, COM4};
/**
enum com_ports {
COM1 = 0x3f8,
COM2 = 0x2f8,
COM3 = 0x3e8,
COM4 = 0x2e8
};
**/
//we shouldn't accept this as a loopback success. static bool detect_serial(uint16_t port) {
//I'm making an exception because my dell desktop has a faulty serial port outb(port + SERIAL_FCR, 0xe7);
//that requires some extra effort. outb(port + SERIAL_SR, 0xba);
if((inb(port + SERIAL_IIR) & (1 << 6)) && (inb(port + SERIAL_SR) == 0xba)) {
outb_wait(port + 1, 0x00);
outb_wait(port + 2, 0x00);
outb_wait(port + 3, 0x80);
outb_wait(port + 0, 0x01);
outb_wait(port + 1, 0x00);
outb_wait(port + 3, 0x03);
outb_wait(port + 2, 0xc7);
outb_wait(port + 4, 0x0b);
outb_wait(port + 4, 0x1e);
uint8_t loopback_byte;
for(int attempts = 0; attempts < MAX_LOOPBACK_ATTEMPTS; attempts++) {
outb_wait(port + 0, 0xae); // test char
loopback_byte = inb(port);
if(loopback_byte == 0xae) break;
}
if(loopback_byte != 0xae) { uint8_t loopback_byte;
//I'm sorry if these next few lines give you a stroke. They gave me one. for(int attempts = 0; attempts < MAX_LOOPBACK_ATTEMPTS; attempts++) {
outb_wait(port + 0, 0xae);
loopback_byte = inb(port);
if(loopback_byte == 0xae) break;
}
if(loopback_byte != 0xae) {
//you better delete this once you get tty drivers working...
int a = 0 / 0;
}
//My old Dell test desktop has disfunctional serial hardware that only works after a reboot. outb_wait(port + 4, 0x0f);
//Seeing we don't have ACPI set up yet, we can't reboot without crashing. return true;
//IM GOING TO REMOVE THIS ONCE I DEVELOP THE "REAL" SERIAL DRIVER!!!!
asm("mov rax, 0\n"
"div rax\n");
return false;
} }
return false;
outb_wait(port + 4, 0x0f);
return true;
} }
//this function is going to be teleted after ttys work.
//but, for now, if a serial port is detected, it'll set debug_output to 0-3 (com port #).
//debug_output == 4 is for screen output.
void init_klog() {
for(unsigned int p = 0; p < (sizeof(serial_ports) / sizeof(uint16_t)); p++) {
if(detect_serial(serial_ports[p])) {
debug_output = p;
return;
}
}
debug_output = KLOG_SCREEN;
_putchar('\n');
}
void _putchar_serial(uint16_t port, char msg) { void _putchar_serial(uint16_t port, char msg) {
while(!(inb(port + 5) & 0x20)); //wait for transmit to be done while(!(inb(port + 5) & 0x20)); //wait for transmit to be done
outb_wait(port, msg); outb_wait(port, msg);
@ -80,13 +127,10 @@ void next_line() {
} }
void move_cursor(unsigned int x, unsigned int y) { void move_cursor(unsigned int x, unsigned int y) {
//yeah yeah yeah, it doens't test for overflows... I'm gonna delete this once i get serial working
//on my second desktop
on_char = x; on_char = x;
on_line = y; on_line = y;
} }
//until we get serial working on hp
void _putchar_screen(char msg) { void _putchar_screen(char msg) {
if(on_char >= 80) { if(on_char >= 80) {
next_line(); next_line();
@ -94,7 +138,55 @@ void _putchar_screen(char msg) {
next_line(); next_line();
return; return;
} }
char *screen_buffer = (void *)((uint64_t)VIDEO_BUFFER + ((on_line * 160) + (on_char * 2))); *(char *)((uint64_t)VIDEO_BUFFER + ((on_line * 160) + (on_char * 2))) = msg;
*screen_buffer = msg;
on_char++; on_char++;
} }
void _putchar(char character) {
if(debug_output < (sizeof(serial_ports) / sizeof(uint16_t))) {
_putchar_serial(serial_ports[debug_output], character);
}
else {
_putchar_screen(character);
}
}
/**
* Set the value "0xE7" to the FCR to test the status of the FIFO flags.
Read the value of the IIR to test for what flags actually got set.
If Bit 6 is set Then
If Bit 7 is set Then
If Bit 5 is set Then
UART is 16750 (64 bit fifo)
Else
UART is 16550A (idk why this matters, 16 bit fifo)
End If
Else
UART is 16550 (16 bit fifo)
End If
Else you know the chip doesn't use FIFO, so we need to check the scratch register
Set some arbitrary value like 0x2A to the Scratch Register.
If the arbitrary value comes back identical
UART is 16450 (idk why this matters, 1 byte at a time)
Else
UART is 8250 (one byte at a time)
End If
End If
#define UART_16750 0
#define UART_16550A 1
#define UART_16550 2
#define UART_16450 3
#define UART_8250 4
#define KLOG_COM1 0
#define KLOG_COM2 1
#define KLOG_COM3 2
#define KLOG_COM4 3
#define KLOG_SCREEN 4 * 5 // 5 leaves enough space for com ports
**/

View File

@ -2,7 +2,7 @@
#include <libc.h> #include <libc.h>
#include <acpi.h> #include <acpi.h>
#include <int.h> #include <int.h>
#include <kernel.h> #include <addr.h>
#include <stddef.h> #include <stddef.h>
#include <heap.h> #include <heap.h>
#include <printf.h> #include <printf.h>

View File

@ -4,7 +4,7 @@
#include <limits.h> #include <limits.h>
#include <panic.h> #include <panic.h>
#include <math.h> #include <math.h>
#include <kernel.h> #include <addr.h>
#include <stdbool.h> #include <stdbool.h>
#include <cpuid.h> #include <cpuid.h>

View File

@ -1,12 +1,15 @@
#include <panic.h> #include <panic.h>
#include <stdint.h> #include <stdint.h>
#include <printf.h> #include <printf.h>
#include <kernel.h> #include <addr.h>
#include <serial.h> #include <klog.h>
#include <isv.h> #include <isv.h>
#include <smp_sync.h>
static uint8_t panic_lock = 0;
void panic(int reason, void *eframe_p, struct registers *regs) { // will fill with debugging info latter void panic(int reason, void *eframe_p, struct registers *regs) { // will fill with debugging info latter
lock(&panic_lock);
#ifdef EASTEREGG_BLOATWARE #ifdef EASTEREGG_BLOATWARE
printf("\nKernel PANIC!!!!!!!\n"); printf("\nKernel PANIC!!!!!!!\n");
@ -49,6 +52,9 @@ void panic(int reason, void *eframe_p, struct registers *regs) { // will fill wi
break; break;
case KERNEL_PANIC_HPET_REQUIRED: case KERNEL_PANIC_HPET_REQUIRED:
printf("\nHPET is required. \nIf you get this error, let know;\nif enough people share this issue, I'll impliment PIT usage.\n"); printf("\nHPET is required. \nIf you get this error, let know;\nif enough people share this issue, I'll impliment PIT usage.\n");
case KERNEL_PANIC_SMP_FAILED:
printf("\nNot all cores booted successfully (see text before panic).\n");
break;
default: default:
printf("\nUnknown panic code %i\n.", reason); printf("\nUnknown panic code %i\n.", reason);
break; break;

View File

@ -33,10 +33,11 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "printf.h" #include "printf.h"
//this is my own ugly library //this is my own ugly library
#include <serial.h> #include <klog.h>
//and my options //and my options
/** /**
@ -161,12 +162,7 @@ static inline void _out_char(char character, void* buffer, size_t idx, size_t ma
{ {
(void)buffer; (void)idx; (void)maxlen; (void)buffer; (void)idx; (void)maxlen;
if (character) { if (character) {
#ifdef SCREEN_OUTPUT _putchar(character);
_putchar_screen(character);
#else
_putchar_serial(COM1, character); // later we should figure out a way to not specifify exclusively com1
#endif
} }
} }
@ -874,17 +870,24 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#include <smp_sync.h>
static uint8_t printf_lock = 0;
int printf_(const char* format, ...) int printf_(const char* format, ...)
{ {
//BRETT modification
lock(&printf_lock);
va_list va; va_list va;
va_start(va, format); va_start(va, format);
char buffer[1]; char buffer[1];
const int ret = _vsnprintf(_out_char, buffer, (size_t)-1, format, va); const int ret = _vsnprintf(_out_char, buffer, (size_t)-1, format, va);
va_end(va); va_end(va);
unlock(&printf_lock);
return ret; return ret;
} }
///////////////////////////////////////////////////////////////////////////////
int sprintf_(char* buffer, const char* format, ...) int sprintf_(char* buffer, const char* format, ...)
{ {

View File

@ -1,4 +1,4 @@
#include <kernel.h> #include <addr.h>
#include <printf.h> #include <printf.h>
#include <madt.h> #include <madt.h>
#include <timer.h> #include <timer.h>
@ -7,6 +7,7 @@
#include <libc.h> #include <libc.h>
#include <paging.h> #include <paging.h>
#include <heap.h> #include <heap.h>
#include <panic.h>
#define LAPIC_ICR_LOW 192 #define LAPIC_ICR_LOW 192
#define LAPIC_ICR_HIGH 196 #define LAPIC_ICR_HIGH 196
@ -16,6 +17,7 @@ extern char __load_start_smp_bootloader, __load_stop_smp_bootloader;
extern uint8_t *smp_bootstrap_corecount; extern uint8_t *smp_bootstrap_corecount;
extern uint8_t smp_bootstrap_bsp; extern uint8_t smp_bootstrap_bsp;
extern uint64_t *smp_bootstrap_stackarray; extern uint64_t *smp_bootstrap_stackarray;
extern char final_gdt_descriptor;
struct icr_reg { struct icr_reg {
uint8_t vector; uint8_t vector;
@ -30,22 +32,30 @@ struct icr_reg {
unsigned int reserved_2:12; unsigned int reserved_2:12;
}__attribute__((packed)); }__attribute__((packed));
//1: get bsp number 2
//2: get list of lapics 3
//3: copy code 1
//4:
static inline void write_icr(uint8_t dest, uint32_t message) { static inline void write_icr(uint8_t dest, uint32_t message) {
lapic[LAPIC_ICR_HIGH] = (uint32_t)dest << 24; lapic[LAPIC_ICR_HIGH] = (uint32_t)dest << 24;
lapic[LAPIC_ICR_LOW] = message; lapic[LAPIC_ICR_LOW] = message;
} }
struct gdt_descriptor {
uint16_t size;
void *offset;
} __attribute__((packed));
static struct gdt_descriptor gdtr;
void smp_boot() { void smp_boot() {
uint8_t cores_active = 1; //TODO change in asm uint8_t cores_active = 1;
struct cores_info cores; struct cores_info cores;
struct icr_reg icr; struct icr_reg icr;
get_coreinfo(&cores); get_coreinfo(&cores);
if(cores.corecount == 1) {
asm("sgdt [%0]"::"m"(gdtr));
gdtr.offset = PHYS_TO_VIRT(gdtr.offset);
asm("lgdt [%0]"::"m"(gdtr));
return;
}
bzero(&icr, sizeof(icr)); bzero(&icr, sizeof(icr));
void **core_stacks = malloc(sizeof(void *) * (cores.corecount - 1)); void **core_stacks = malloc(sizeof(void *) * (cores.corecount - 1));
@ -57,9 +67,7 @@ void smp_boot() {
&__load_stop_smp_bootloader - &__load_start_smp_bootloader); &__load_stop_smp_bootloader - &__load_start_smp_bootloader);
smp_bootstrap_corecount = &cores_active; smp_bootstrap_corecount = &cores_active;
smp_bootstrap_bsp = cores.bsp; smp_bootstrap_bsp = cores.bsp;
smp_bootstrap_stackarray = (uint64_t)core_stacks; smp_bootstrap_stackarray = (void *)core_stacks;
icr.deliv_mode = 0b101; icr.deliv_mode = 0b101;
icr.dest_shorthand = 0b11; icr.dest_shorthand = 0b11;
@ -74,10 +82,9 @@ void smp_boot() {
if(cores_active != cores.corecount) write_icr(0, *(uint32_t *)&icr); if(cores_active != cores.corecount) write_icr(0, *(uint32_t *)&icr);
usleep(200); usleep(200);
if(cores_active != cores.corecount) { if(cores_active != cores.corecount) {
printf("NOT ALL CORES ONLINE\n"); printf("Only %i cores online (expected %i)\n", cores_active, cores.corecount); //maybe add a panic
asm("cli\nhlt"); PANIC(KERNEL_PANIC_SMP_FAILED);
}
else {
printf("%i!!!!!!\n", cores_active);
} }
printf("%i \n", cores_active);
//asm("lgdt [%0]\n"::"r"(PHYS_TO_VIRT(&final_gdt_descriptor))); TODO NOW
} }

View File

@ -1,13 +1,19 @@
global smp_bootstrap_stackarray global smp_bootstrap_stackarray
global smp_bootstrap_bsp global smp_bootstrap_bsp
global smp_bootstrap_corecount global smp_bootstrap_corecount
global final_gdt_descriptor
extern multicore_main extern smp_kinit
extern _pmem_vaddr
[bits 16] [bits 16]
smp_trampoline: smp_trampoline:
cli cli
in al, 0x92
or al, 2
out 0x92, al
xor ax, ax xor ax, ax
mov ds, ax mov ds, ax
lgdt [.gdt_descriptor_p] lgdt [.gdt_descriptor_p]
@ -15,12 +21,11 @@ mov eax, cr0
or eax, 0x1 or eax, 0x1
mov cr0, eax ; now in long mode mov cr0, eax ; now in long mode
jmp 0x8:.smp_protected jmp 0x8:smp_protected
;________________________________________________________________________________________ ;________________________________________________________________________________________
;TODO find how to use old gdt
.gdt_start_p: ; we need to start with a null gdt .gdt_start_p: ; we need to start with a null gdt
dd 0 dd 0
dd 0 dd 0
@ -52,9 +57,9 @@ SMP_PROTECTED_DATA_SEGMENT equ .gdt_data_p - .gdt_start_p
;________________________________________________________________________________________ ;________________________________________________________________________________________
.smp_protected: smp_protected:
[bits 32] bits 32
mov ax, SMP_PROTECTED_DATA_SEGMENT mov ax, SMP_PROTECTED_DATA_SEGMENT
mov ds, ax mov ds, ax
mov ss, ax mov ss, ax
@ -62,10 +67,8 @@ mov es, ax
mov fs, ax mov fs, ax
mov gs, ax mov gs, ax
lgdt [.gdt_descriptor_l]
mov eax, 0x10000
mov eax, 0x10000 ;TODO clarify _why_ this is a thing
mov cr3, eax mov cr3, eax
;setting up misc features ;setting up misc features
@ -78,13 +81,15 @@ mov cr4, eax
;set NX and LME ;set NX and LME
mov eax, 0x80000001 mov eax, 0x80000001
cpuid cpuid
and edx, 1 << 20 mov ebx, edx
shr edx, 9 and ebx, 1 << 20
shr ebx, 9
mov ecx, 0xc0000080 mov ecx, 0xc0000080
rdmsr rdmsr
or eax, 1 << 8 | 1 << 11 or eax, 1 << 8
or eax, edx fuckyou:
or eax, ebx
wrmsr wrmsr
@ -94,14 +99,16 @@ or eax, 1 << 31 | 1 << 0;
and ax, ~(1 << 2) and ax, ~(1 << 2)
mov cr0, eax mov cr0, eax
lgdt [final_gdt_descriptor]
jmp SMP_LONG_CODE_SEGMENT:.counter
jmp SMP_LONG_CODE_SEGMENT:smp_longsetup
;________________________________________________________________________________________ ;________________________________________________________________________________________
[bits 64] bits 64
;TODO do we really need all this? final_gdt:
.gdt_start_l: .start:
;and now we set up a temporary GDT creating a 1:1 mapping ;and now we set up a temporary GDT creating a 1:1 mapping
dw 0xffff dw 0xffff
dw 0 dw 0
@ -111,7 +118,7 @@ db 1
db 0 db 0
;now for the code GDT: ;now for the code GDT:
.gdt_code_l: .code:
dw 0 ; segment limit 15:00 (I don't think this matters in 64 bit mode!) dw 0 ; segment limit 15:00 (I don't think this matters in 64 bit mode!)
dw 0 ; base address 15:00 dw 0 ; base address 15:00
db 0 ; base address 23:16 db 0 ; base address 23:16
@ -119,7 +126,7 @@ db 10011010b
db 00100000b db 00100000b
db 0 db 0
.gdt_data_l: .data:
dw 0 dw 0
dw 0 dw 0
db 0 db 0
@ -127,17 +134,18 @@ db 10010010b
db 00100000b db 00100000b
db 0 db 0
.gdt_end_l: ; later calculates offset in defs below .end: ; later calculates offset in defs below
.gdt_descriptor_l: final_gdt_descriptor:
dw .gdt_end_l - .gdt_start_l - 1 dw final_gdt.end - final_gdt.start - 1
dq .gdt_start_l .offset:
dq final_gdt.start
SMP_LONG_CODE_SEGMENT equ .gdt_code_l - .gdt_start_l SMP_LONG_CODE_SEGMENT equ final_gdt.code - final_gdt.start
SMP_LONG_DATA_SEGMENT equ .gdt_data_l - .gdt_start_l SMP_LONG_DATA_SEGMENT equ final_gdt.data - final_gdt.start
.counter: smp_longsetup:
mov eax, 1 mov eax, 1
cpuid cpuid
shr ebx, 24 shr ebx, 24
@ -146,19 +154,29 @@ jl .apic_below_bsp
sub bl, 1 sub bl, 1
.apic_below_bsp: .apic_below_bsp:
mov rax, QWORD [smp_bootstrap_stackarray] mov rax, QWORD [smp_bootstrap_stackarray]
debug:
mov rsp, QWORD [rax + rbx * 8] mov rsp, QWORD [rax + rbx * 8]
mov rax, [smp_bootstrap_corecount] mov rax, 0xffff800000000000
inc BYTE [rax] ;or QWORD [final_gdt_descriptor.offset], rax
;lgdt [final_gdt_descriptor]
mov rax, multicore_main .inc_corecounter:
mov rax, [smp_bootstrap_corecount]
lock inc BYTE [rax]
smp_enter_kernel:
mov rax, smp_kinit
jmp rax jmp rax
align 8 align 8
smp_bootstrap_stackarray: dq 0 smp_bootstrap_stackarray: dq 0
smp_lock: dq 0
smp_bootstrap_bsp: db 0 smp_bootstrap_bsp: db 0
smp_bootstrap_corecount: db 0 smp_bootstrap_corecount: db 0
times 512 - ($ - $$) db 0 times 512 - ($ - $$) db 0

View File

@ -3,7 +3,7 @@
#include <io.h> #include <io.h>
#include <printf.h> #include <printf.h>
#include <libc.h> #include <libc.h>
#include <kernel.h> #include <addr.h>
#include <cpuid.h> #include <cpuid.h>
#include <panic.h> #include <panic.h>
#include <int.h> #include <int.h>
@ -204,10 +204,8 @@ void init_timer() {
uint32_t unused, cpuid_reg; uint32_t unused, cpuid_reg;
__get_cpuid(0x80000007, &unused, &unused, &unused, &cpuid_reg); __get_cpuid(0x80000007, &unused, &unused, &unused, &cpuid_reg);
//goto debug_tsc;
if((cpuid_reg >> 8) & 1) { if((cpuid_reg >> 8) & 1) {
printf("Detected invariant TSC\n"); printf("Detected invariant TSC\n");
//.1 second to calibrate, TODO do we need to check if the register is big enough?
uint64_t hpet_ticks = (100000000000000 * (1 / (double)hpet_info.hpet_period)) + 0.5; uint64_t hpet_ticks = (100000000000000 * (1 / (double)hpet_info.hpet_period)) + 0.5;
printf("Starting TSC calibration...\n"); printf("Starting TSC calibration...\n");
uint64_t volatile start_tsc, end_tsc; uint64_t volatile start_tsc, end_tsc;
@ -274,7 +272,7 @@ void init_timer() {
apic_div = (((apic_div & 0b100) << 1) | (apic_div * 0b1011)); apic_div = (((apic_div & 0b100) << 1) | (apic_div * 0b1011));
} }
lapic_timer_lvt.vector = SPURRIOUS_VECTOR; //TODO CHANGE ME lapic_timer_lvt.vector = SPURRIOUS_VECTOR;
lapic_timer_lvt.timer_mode = LAPIC_TIMER_MODE_PERIODIC; lapic_timer_lvt.timer_mode = LAPIC_TIMER_MODE_PERIODIC;
lapic_timer_lvt.delivery_status = 0; lapic_timer_lvt.delivery_status = 0;
lapic_timer_lvt.mask = 1; lapic_timer_lvt.mask = 1;

View File

@ -1,6 +1,7 @@
SEARCH_DIR(objects) SEARCH_DIR(objects)
_kernel_s1_loc = 0xffffffff80000000; _txt_vaddr = 0xffffffff80000000;
_pmem_vaddr = 0xffff800000000000;
_meminfo = 0x7000; _meminfo = 0x7000;
_vbe_infoblock = 0x500; _vbe_infoblock = 0x500;
@ -15,7 +16,7 @@ SECTIONS
{ {
smp_trampoline.o(.text) smp_trampoline.o(.text)
} }
kernel _kernel_s1_loc : kernel _txt_vaddr :
AT (0 + SIZEOF(smp_bootloader) + SIZEOF(bootloader)) AT (0 + SIZEOF(smp_bootloader) + SIZEOF(bootloader))
{ {
EXCLUDE_FILE (*bootloader.o *smp_trampoline.o) *(.text .data .bss .rodata .comment .eh_frame) EXCLUDE_FILE (*bootloader.o *smp_trampoline.o) *(.text .data .bss .rodata .comment .eh_frame)

View File

@ -44,20 +44,6 @@ all: $(ASM_OBJFILES) $(C_OBJFILES) $(MISC_OBJFILES) bootloader.o smp_trampoline.
isv.o: kernel/isv.c isv.o: kernel/isv.c
$(CC) $(CFLAGS) $(INC) -mgeneral-regs-only -MMD -MP -c kernel/isv.c -o objects/$@ $(CC) $(CFLAGS) $(INC) -mgeneral-regs-only -MMD -MP -c kernel/isv.c -o objects/$@
printf.o: kernel/printf.c
ifdef screen
$(CC) $(CFLAGS) $(INC) -MMD -MP -DSCREEN_OUTPUT -c kernel/printf.c -o objects/$@
else
$(CC) $(CFLAGS) $(INC) -MMD -MP -c kernel/printf.c -o objects/$@
endif
kernel.o: kernel/kernel.c
ifdef screen
$(CC) $(CFLAGS) $(INC) -MMD -MP -DSCREEN_OUTPUT -c kernel/kernel.c -o objects/$@
else
$(CC) $(CFLAGS) $(INC) -MMD -MP -c kernel/kernel.c -o objects/$@
endif
%.o: kernel/%.c makefile %.o: kernel/%.c makefile
$(CC) $(CFLAGS) $(INC) -MMD -MP -c $< -o objects/$@ $(CC) $(CFLAGS) $(INC) -MMD -MP -c $< -o objects/$@