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
|
||||
COMMON_SRCS = forth_core.c forth_dict.c forth_words.c forth_interp.c main.c
|
||||
|
||||
HOSTED_SRCS = $(COMMON_SRCS) platform_hosted.c
|
||||
FREESTANDING_SRCS = $(COMMON_SRCS) platform_freestanding.c
|
||||
LINUX_SRCS = $(COMMON_SRCS) platform_linux.c
|
||||
KERNEL_SRCS = $(COMMON_SRCS) platform_kernel.c kernel_entry.S
|
||||
KERNEL_LD = kernel.ld
|
||||
|
||||
TARGET = forth
|
||||
FREESTANDING_TARGET = forth_freestanding
|
||||
KERNEL_TARGET = forth.kernel
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(HOSTED_SRCS) forth.h
|
||||
$(CC) $(CFLAGS) -D_POSIX_C_SOURCE=200809L -o $@ $(HOSTED_SRCS)
|
||||
$(TARGET): $(LINUX_SRCS) forth.h
|
||||
$(CC) $(CFLAGS) -static -nostdlib -ffreestanding -fno-stack-protector -o $@ $(LINUX_SRCS)
|
||||
|
||||
$(FREESTANDING_TARGET): $(FREESTANDING_SRCS) forth.h
|
||||
$(CC) $(CFLAGS) -ffreestanding -nostdlib -fno-stack-protector -o $@ $(FREESTANDING_SRCS)
|
||||
$(KERNEL_TARGET): $(KERNEL_SRCS) forth.h $(KERNEL_LD)
|
||||
$(CC) $(CFLAGS) -ffreestanding -nostdlib -fno-stack-protector -mno-red-zone -o $@ $(KERNEL_SRCS) -T$(KERNEL_LD) -Wl,--build-id=none
|
||||
|
||||
clean:
|
||||
rm -f $(TARGET) $(FREESTANDING_TARGET)
|
||||
rm -f $(TARGET) $(KERNEL_TARGET)
|
||||
|
||||
.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