build: replace hosted target with static linux and add kernel target
Co-authored-by: aider (openrouter/moonshotai/kimi-k2.6) <aider@aider.chat>
This commit is contained in:
@@ -2,21 +2,22 @@ CC = clang
|
|||||||
CFLAGS = -Wall -Wextra -g -std=c11
|
CFLAGS = -Wall -Wextra -g -std=c11
|
||||||
COMMON_SRCS = forth_core.c forth_dict.c forth_words.c forth_interp.c main.c
|
COMMON_SRCS = forth_core.c forth_dict.c forth_words.c forth_interp.c main.c
|
||||||
|
|
||||||
HOSTED_SRCS = $(COMMON_SRCS) platform_hosted.c
|
LINUX_SRCS = $(COMMON_SRCS) platform_linux.c
|
||||||
FREESTANDING_SRCS = $(COMMON_SRCS) platform_freestanding.c
|
KERNEL_SRCS = $(COMMON_SRCS) platform_kernel.c kernel_entry.S
|
||||||
|
KERNEL_LD = kernel.ld
|
||||||
|
|
||||||
TARGET = forth
|
TARGET = forth
|
||||||
FREESTANDING_TARGET = forth_freestanding
|
KERNEL_TARGET = forth.kernel
|
||||||
|
|
||||||
all: $(TARGET)
|
all: $(TARGET)
|
||||||
|
|
||||||
$(TARGET): $(HOSTED_SRCS) forth.h
|
$(TARGET): $(LINUX_SRCS) forth.h
|
||||||
$(CC) $(CFLAGS) -D_POSIX_C_SOURCE=200809L -o $@ $(HOSTED_SRCS)
|
$(CC) $(CFLAGS) -static -nostdlib -ffreestanding -fno-stack-protector -o $@ $(LINUX_SRCS)
|
||||||
|
|
||||||
$(FREESTANDING_TARGET): $(FREESTANDING_SRCS) forth.h
|
$(KERNEL_TARGET): $(KERNEL_SRCS) forth.h $(KERNEL_LD)
|
||||||
$(CC) $(CFLAGS) -ffreestanding -nostdlib -fno-stack-protector -o $@ $(FREESTANDING_SRCS)
|
$(CC) $(CFLAGS) -ffreestanding -nostdlib -fno-stack-protector -mno-red-zone -o $@ $(KERNEL_SRCS) -T$(KERNEL_LD) -Wl,--build-id=none
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(TARGET) $(FREESTANDING_TARGET)
|
rm -f $(TARGET) $(KERNEL_TARGET)
|
||||||
|
|
||||||
.PHONY: all clean
|
.PHONY: all clean
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x100000;
|
||||||
|
|
||||||
|
.text : ALIGN(4K)
|
||||||
|
{
|
||||||
|
*(.multiboot2)
|
||||||
|
*(.text)
|
||||||
|
}
|
||||||
|
|
||||||
|
.rodata : ALIGN(4K)
|
||||||
|
{
|
||||||
|
*(.rodata)
|
||||||
|
}
|
||||||
|
|
||||||
|
.data : ALIGN(4K)
|
||||||
|
{
|
||||||
|
*(.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
.bss : ALIGN(4K)
|
||||||
|
{
|
||||||
|
__bss_start = .;
|
||||||
|
*(.bss)
|
||||||
|
*(COMMON)
|
||||||
|
__bss_end = .;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
# Multiboot2 header and x86_64 long-mode bootstrap
|
||||||
|
|
||||||
|
.section .multiboot2, "a"
|
||||||
|
.align 8
|
||||||
|
multiboot_header:
|
||||||
|
.long 0xe85250d6
|
||||||
|
.long 0
|
||||||
|
.long multiboot_header_end - multiboot_header
|
||||||
|
.long -(0xe85250d6 + 0 + (multiboot_header_end - multiboot_header))
|
||||||
|
|
||||||
|
.align 8
|
||||||
|
.word 0
|
||||||
|
.word 0
|
||||||
|
.long 8
|
||||||
|
multiboot_header_end:
|
||||||
|
|
||||||
|
.section .bss, "aw", @nobits
|
||||||
|
.align 4096
|
||||||
|
pml4:
|
||||||
|
.space 4096
|
||||||
|
pdpt:
|
||||||
|
.space 4096
|
||||||
|
pd:
|
||||||
|
.space 4096
|
||||||
|
|
||||||
|
.align 16
|
||||||
|
stack_bottom:
|
||||||
|
.space 16384
|
||||||
|
stack_top:
|
||||||
|
|
||||||
|
.section .text
|
||||||
|
.code32
|
||||||
|
.global _start
|
||||||
|
.type _start, @function
|
||||||
|
_start:
|
||||||
|
movl $stack_top, %esp
|
||||||
|
|
||||||
|
movl $pdpt, %eax
|
||||||
|
orl $0x03, %eax
|
||||||
|
movl %eax, pml4
|
||||||
|
|
||||||
|
movl $pd, %eax
|
||||||
|
orl $0x03, %eax
|
||||||
|
movl %eax, pdpt
|
||||||
|
|
||||||
|
movl $0x00000083, %eax
|
||||||
|
movl $pd, %edi
|
||||||
|
movl $512, %ecx
|
||||||
|
1:
|
||||||
|
movl %eax, (%edi)
|
||||||
|
addl $0x200000, %eax
|
||||||
|
addl $8, %edi
|
||||||
|
loop 1b
|
||||||
|
|
||||||
|
movl $pml4, %eax
|
||||||
|
movl %eax, %cr3
|
||||||
|
|
||||||
|
movl %cr4, %eax
|
||||||
|
orl $0x20, %eax
|
||||||
|
movl %eax, %cr4
|
||||||
|
|
||||||
|
movl $0xC0000080, %ecx
|
||||||
|
rdmsr
|
||||||
|
orl $0x100, %eax
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
movl %cr0, %eax
|
||||||
|
orl $0x80000000, %eax
|
||||||
|
movl %eax, %cr0
|
||||||
|
|
||||||
|
lgdt gdt64_pointer
|
||||||
|
ljmp $0x08, $long_mode_start
|
||||||
|
|
||||||
|
.code64
|
||||||
|
long_mode_start:
|
||||||
|
movabsq $stack_top, %rax
|
||||||
|
movq %rax, %rsp
|
||||||
|
|
||||||
|
movabsq $__bss_start, %rdi
|
||||||
|
movabsq $__bss_end, %rcx
|
||||||
|
subq %rdi, %rcx
|
||||||
|
xorq %rax, %rax
|
||||||
|
rep stosb
|
||||||
|
|
||||||
|
call kernel_main
|
||||||
|
cli
|
||||||
|
1:
|
||||||
|
hlt
|
||||||
|
jmp 1b
|
||||||
|
|
||||||
|
.section .rodata
|
||||||
|
.align 8
|
||||||
|
gdt64:
|
||||||
|
.quad 0x0000000000000000
|
||||||
|
.quad 0x00209A0000000000
|
||||||
|
gdt64_pointer:
|
||||||
|
.word gdt64_pointer - gdt64 - 1
|
||||||
|
.quad gdt64
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
#include "forth.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
// VGA text-mode buffer
|
||||||
|
static uint16_t* vga_buffer = (uint16_t*)0xB8000;
|
||||||
|
static int vga_row = 0;
|
||||||
|
static int vga_col = 0;
|
||||||
|
|
||||||
|
static void vga_putchar(char c) {
|
||||||
|
if (c == '\n') {
|
||||||
|
vga_col = 0;
|
||||||
|
vga_row++;
|
||||||
|
} else {
|
||||||
|
int idx = vga_row * 80 + vga_col;
|
||||||
|
vga_buffer[idx] = (uint16_t)((0x0F << 8) | (unsigned char)c);
|
||||||
|
vga_col++;
|
||||||
|
if (vga_col >= 80) {
|
||||||
|
vga_col = 0;
|
||||||
|
vga_row++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (vga_row >= 25) {
|
||||||
|
vga_row = 0;
|
||||||
|
vga_col = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void outb(uint16_t port, uint8_t val) {
|
||||||
|
__asm__ volatile ("outb %0, %1" : : "a"(val), "Nd"(port));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint8_t inb(uint16_t port) {
|
||||||
|
uint8_t ret;
|
||||||
|
__asm__ volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void serial_init(void) {
|
||||||
|
outb(0x3F8 + 1, 0x00);
|
||||||
|
outb(0x3F8 + 3, 0x80);
|
||||||
|
outb(0x3F8 + 0, 0x01);
|
||||||
|
outb(0x3F8 + 1, 0x00);
|
||||||
|
outb(0x3F8 + 3, 0x03);
|
||||||
|
outb(0x3F8 + 2, 0xC7);
|
||||||
|
outb(0x3F8 + 4, 0x0B);
|
||||||
|
}
|
||||||
|
|
||||||
|
void forth_putchar(char c) {
|
||||||
|
vga_putchar(c);
|
||||||
|
while ((inb(0x3F8 + 5) & 0x20) == 0) { }
|
||||||
|
outb(0x3F8, (uint8_t)c);
|
||||||
|
}
|
||||||
|
|
||||||
|
int forth_getchar(void) {
|
||||||
|
if ((inb(0x3F8 + 5) & 1) == 0) {
|
||||||
|
return FORTH_EOF;
|
||||||
|
}
|
||||||
|
return inb(0x3F8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void forth_fflush(void) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void forth_panic(void) {
|
||||||
|
__asm__ volatile ("cli; hlt");
|
||||||
|
__builtin_unreachable();
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t forth_strtoll(const char* str, char** endptr, int base) {
|
||||||
|
const char* s = str;
|
||||||
|
int neg = 0;
|
||||||
|
int64_t val = 0;
|
||||||
|
while (forth_isspace(*s)) s++;
|
||||||
|
if (*s == '-') { neg = 1; s++; }
|
||||||
|
else if (*s == '+') { s++; }
|
||||||
|
while (*s >= '0' && *s <= '9') {
|
||||||
|
val = val * base + (*s - '0');
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
if (endptr) *endptr = (char*)s;
|
||||||
|
return neg ? -val : val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_str(const char* s) {
|
||||||
|
while (*s) forth_putchar(*s++);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_int(long long v) {
|
||||||
|
char buf[32];
|
||||||
|
int i = 30;
|
||||||
|
int neg = 0;
|
||||||
|
if (v < 0) { neg = 1; v = -v; }
|
||||||
|
buf[31] = '\0';
|
||||||
|
if (v == 0) {
|
||||||
|
buf[i--] = '0';
|
||||||
|
} else {
|
||||||
|
while (v > 0 && i >= 0) {
|
||||||
|
buf[i--] = '0' + (v % 10);
|
||||||
|
v /= 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (neg) buf[i--] = '-';
|
||||||
|
print_str(&buf[i + 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void forth_printf(const char* fmt, ...) {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
while (*fmt) {
|
||||||
|
if (*fmt == '%' && *(fmt + 1)) {
|
||||||
|
fmt++;
|
||||||
|
if (*fmt == 's') {
|
||||||
|
print_str(va_arg(ap, const char*));
|
||||||
|
} else if (*fmt == 'c') {
|
||||||
|
forth_putchar((char)va_arg(ap, int));
|
||||||
|
} else if (*fmt == '%') {
|
||||||
|
forth_putchar('%');
|
||||||
|
} else if (*fmt == 'l') {
|
||||||
|
if (*(fmt + 1) == 'l' && (*(fmt + 2) == 'd' || *(fmt + 2) == 'i' || *(fmt + 2) == 'u')) {
|
||||||
|
fmt += 2;
|
||||||
|
print_int(va_arg(ap, long long));
|
||||||
|
}
|
||||||
|
} else if (*fmt == 'd' || *fmt == 'i' || *fmt == 'u') {
|
||||||
|
print_int(va_arg(ap, int));
|
||||||
|
} else {
|
||||||
|
forth_putchar('%');
|
||||||
|
forth_putchar(*fmt);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
forth_putchar(*fmt);
|
||||||
|
}
|
||||||
|
fmt++;
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void kernel_main(void) {
|
||||||
|
serial_init();
|
||||||
|
forth_run();
|
||||||
|
forth_panic();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user