Merge branch 'hardware-deploy'

This commit is contained in:
Thomas Oltmann 2025-03-15 20:50:34 +01:00
commit ee4d584790
7 changed files with 203 additions and 20 deletions

View file

@ -9,6 +9,7 @@ CFLAGS += -ggdb
# preferentially in alphabetical order. # preferentially in alphabetical order.
KERNEL_SOURCES_x86_64 := \ KERNEL_SOURCES_x86_64 := \
src/x86_64/apic.c \ src/x86_64/apic.c \
src/x86_64/loadcs.S \
src/x86_64/uart.c \ src/x86_64/uart.c \
src/x86_64/mem.c \ src/x86_64/mem.c \
src/x86_64/asm.c \ src/x86_64/asm.c \

34
bochsrc Normal file
View file

@ -0,0 +1,34 @@
cpu: count=1, reset_on_triple_fault=1
cpuid: x86_64=1, mmx=1, sep=1, simd=sse4_2, apic=xapic, aes=1, movbe=1, xsave=1
cpuid: family=6, model=0x1a, stepping=5
memory: guest=512, host=256
romimage: file=$BXSHARE/BIOS-bochs-latest, options=fastboot
vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest
mouse: enabled=0
pci: enabled=1, chipset=i440fx
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15
ata2: enabled=0, ioaddr1=0x1e8, ioaddr2=0x3e0, irq=11
ata3: enabled=0, ioaddr1=0x168, ioaddr2=0x360, irq=9
# hard-coded 16MB disk size
ata0-master: type=disk, mode=flat, path="build/disk.img", cylinders=64, heads=16, spt=32
boot: disk
panic: action=ask
error: action=report
info: action=report
debug: action=ignore, pci=report # report BX_DEBUG from module 'pci'
debugger_log: -
com1: enabled=1, mode=socket-server, dev=localhost:1111
port_e9_hack: enabled=1

View file

@ -3,6 +3,6 @@
"initrd": { "type": "tar", "directory": "build/boot" }, "initrd": { "type": "tar", "directory": "build/boot" },
"config": "bootboot.cfg", "config": "bootboot.cfg",
"partitions": [ "partitions": [
{ "type": "fat16", "size": 16 } { "type": "boot", "size": 16 }
] ]
} }

View file

@ -28,6 +28,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <cpuid.h>
#include "x86_64/apic.h" #include "x86_64/apic.h"
#include "x86_64/mem.h" #include "x86_64/mem.h"
@ -71,11 +72,25 @@ void check_initrd() {
putln(); putln();
} }
void console_init(void);
/****************************************** /******************************************
* Entry point, called by BOOTBOOT Loader * * Entry point, called by BOOTBOOT Loader *
******************************************/ ******************************************/
void _start() { void _start() {
/*** NOTE: this code runs on all cores in parallel ***/ /*** NOTE: this code runs on all cores in parallel ***/
unsigned info[4];
__get_cpuid(0x1, &info[0], &info[1], &info[2], &info[3]);
unsigned procid = info[1] >> 24;
if (procid != bootboot.bspid) {
while (1) {
__asm__ ("hlt");
}
}
console_init();
int x, y, s = bootboot.fb_scanline, w = bootboot.fb_width, h = bootboot.fb_height; int x, y, s = bootboot.fb_scanline, w = bootboot.fb_width, h = bootboot.fb_height;
if (s) { if (s) {
@ -125,11 +140,19 @@ void _start() {
} }
putln(); putln();
// hang for now #if 0
for (int l = 0; l < 100; l++) {
for (int i = 0; i < 300; i++) {
printf("line %d ", l);
}
printf("\n");
}
#endif
__asm__("sti"); __asm__("sti");
lapic_set_timer(); lapic_set_timer();
// hang for now
PANIC("end of kernel"); PANIC("end of kernel");
} }
@ -149,3 +172,105 @@ typedef struct {
} __attribute__((packed)) psf2_t; } __attribute__((packed)) psf2_t;
extern volatile unsigned char _binary_font_psf_start; extern volatile unsigned char _binary_font_psf_start;
uint32_t console_output[200 * 100];
int console_max_rows;
int console_max_cols;
int text_cursor_x;
int text_cursor_y;
static unsigned char *font_get_glyph(char c)
{
psf2_t *font = (psf2_t*)&_binary_font_psf_start;
unsigned char *glyphArray = (unsigned char *)&_binary_font_psf_start + font->headersize;
if (c == 0) return NULL;
if (c >= font->numglyph) return NULL;
return glyphArray + c * font->bytesperglyph;
}
void console_init(void)
{
psf2_t *font = (psf2_t*)&_binary_font_psf_start;
console_max_cols = bootboot.fb_width / (font->width+1);
if (console_max_cols > 200) console_max_cols = 200;
console_max_rows = bootboot.fb_height / (font->height+1);
if (console_max_rows > 100) console_max_rows = 100;
}
void console_draw(int col, int row)
{
psf2_t *font = (psf2_t*)&_binary_font_psf_start;
int line, mask, offs;
int bpl = (font->width + 7)/8;
int cx = col * (font->width + 1);
int cy = row * (font->height + 1);
uint32_t chr = console_output[col + row * console_max_cols];
if (chr == 0) chr = ' ';
unsigned char *glyph = font_get_glyph(chr);
offs = 4 * cx + cy * bootboot.fb_scanline;
for (int y = 0; y < font->height; y++) {
line = offs;
mask = 1 << (font->width - 1);
for (int x = 0; x < font->width; x++) {
*((uint32_t*)((uint64_t)&fb+line)) = ((int)*glyph) & (mask)?0xFFFFFF:0;
mask >>= 1;
line += 4;
}
*((uint32_t*)((uint64_t)&fb+line))=0;
glyph+=bpl;
offs+=bootboot.fb_scanline;
}
}
void console_scroll(void)
{
for (int i = 0; i+1 < console_max_rows; i++) {
memcpy(&console_output[i * console_max_cols],
&console_output[(i+1) * console_max_cols],
console_max_cols * sizeof *console_output);
}
memset(&console_output[(console_max_rows-1) * console_max_cols], 0,
console_max_cols * sizeof *console_output);
text_cursor_y--;
for (int r = 0; r < console_max_rows; r++) {
for (int c = 0; c < console_max_cols; c++) {
console_draw(c, r);
}
}
}
void visual_putc(char c)
{
int col = text_cursor_x;
int row = text_cursor_y;
if (c == '\r') {
text_cursor_x = 0;
return;
}
if (c == '\n') {
text_cursor_y++;
if (text_cursor_y >= console_max_rows) {
console_scroll();
}
return;
}
text_cursor_x++;
if (col >= console_max_cols) return;
if (row >= console_max_rows) return;
console_output[col + row * console_max_cols] = c;
console_draw(col, row);
}

View file

@ -89,6 +89,8 @@ static unsigned int current_buffer_position = 0;
static void linebuf_flush(void) { static void linebuf_flush(void) {
for (unsigned int i = 0; i < current_buffer_position; i++) { for (unsigned int i = 0; i < current_buffer_position; i++) {
uart_write_char(linebuf[i]); uart_write_char(linebuf[i]);
extern void visual_putc(char c);
visual_putc(linebuf[i]);
} }
current_buffer_position = 0; current_buffer_position = 0;
} }
@ -290,15 +292,15 @@ void printf(const char *format, ...) {
sign = false; sign = false;
break; break;
case 'c': { case 'c': {
char ch = (char)va_arg(args, int); char ch = (char)va_arg(args, int);
putc(ch); putc(ch);
break; break;
} }
case 's': { case 's': {
char *str = va_arg(args, char *); char *str = va_arg(args, char *);
puts(str); puts(str);
break; break;
} }
case 'p': { case 'p': {
void *ptr = va_arg(args, void *); void *ptr = va_arg(args, void *);
putu64x((uint64_t)(intptr_t)ptr); putu64x((uint64_t)(intptr_t)ptr);
@ -331,13 +333,13 @@ void printf(const char *format, ...) {
} }
} }
case '%': { case '%': {
putc('%'); putc('%');
break; break;
} }
default: { default: {
PANIC("printf: unsupported format specifier"); PANIC("printf: unsupported format specifier");
break; break;
} }
} }
if (do_number) { if (do_number) {
if (number_size_bits == 64) { if (number_size_bits == 64) {

17
src/x86_64/loadcs.S Normal file
View file

@ -0,0 +1,17 @@
.section .note.GNU-stack
.text
.global loadcs
// void loadcs(uint16_t ss, uint16_t cs)
// Loads new values into the SS and CS segment selector registers.
loadcs:
mov (%rsp), %rdx // return address
leaq 0x8(%rsp), %rax // old stack pointer from before call
push %rdi // ss
push %rax // rsp
pushf // rflags
push %rsi // cs
push %rdx // rip
iretq

View file

@ -2,6 +2,8 @@
#include "std.h" // remove later, this is only for interrupt handler #include "std.h" // remove later, this is only for interrupt handler
#include "x86_64/apic.h" #include "x86_64/apic.h"
extern void loadcs(uint16_t ss, uint16_t cs);
uint64_t gdt[3]; uint64_t gdt[3];
void write_segment_descriptor(uint64_t *entry, uint8_t dpl, uint8_t executable) { void write_segment_descriptor(uint64_t *entry, uint8_t dpl, uint8_t executable) {
@ -40,13 +42,15 @@ void init_gdt() {
__asm__("lgdt (%0)" ::"r"(gdtr)); __asm__("lgdt (%0)" ::"r"(gdtr));
__asm__("mov %0, %%es" ::"r"(DATA_SEGMENT << 3));
__asm__("mov %0, %%ds" ::"r"(DATA_SEGMENT << 3)); __asm__("mov %0, %%ds" ::"r"(DATA_SEGMENT << 3));
__asm__("mov %0, %%fs" ::"r"(DATA_SEGMENT << 3));
// TODO set code segment -> iret? __asm__("mov %0, %%gs" ::"r"(DATA_SEGMENT << 3));
loadcs(DATA_SEGMENT << 3, CODE_SEGMENT << 3);
} }
struct __attribute__((packed)) __attribute__ ((packed))
int_desc_entry { struct int_desc_entry {
uint16_t offset1; uint16_t offset1;
uint16_t selector; uint16_t selector;
uint8_t ist; uint8_t ist;