mirror of
https://github.com/limine-bootloader/limine
synced 2024-12-25 23:36:50 +03:00
Merge pull request #40 from streaksu/master
Add a unified test image for stivale1 and stivale2 for both x86_64 and i386
This commit is contained in:
commit
53eb16b835
5
Makefile
5
Makefile
@ -8,7 +8,7 @@ all: stage2 decompressor
|
|||||||
gzip -n -9 < stage2/stage2.bin > stage2/stage2.bin.gz
|
gzip -n -9 < stage2/stage2.bin > stage2/stage2.bin.gz
|
||||||
cd bootsect && nasm bootsect.asm -fbin -o ../limine.bin
|
cd bootsect && nasm bootsect.asm -fbin -o ../limine.bin
|
||||||
|
|
||||||
clean: stage2-clean decompressor-clean
|
clean: stage2-clean decompressor-clean test-clean
|
||||||
rm -f stage2/stage2.bin.gz
|
rm -f stage2/stage2.bin.gz
|
||||||
|
|
||||||
stage2:
|
stage2:
|
||||||
@ -23,6 +23,9 @@ decompressor:
|
|||||||
decompressor-clean:
|
decompressor-clean:
|
||||||
$(MAKE) -C decompressor clean
|
$(MAKE) -C decompressor clean
|
||||||
|
|
||||||
|
test-clean:
|
||||||
|
$(MAKE) -C test clean
|
||||||
|
|
||||||
toolchain:
|
toolchain:
|
||||||
cd toolchain && ./make_toolchain.sh -j`nproc`
|
cd toolchain && ./make_toolchain.sh -j`nproc`
|
||||||
|
|
||||||
|
@ -1,3 +1,22 @@
|
|||||||
test.elf: test.asm linker.ld
|
TARGET := test.elf
|
||||||
nasm test.asm -felf64 -o test.o
|
|
||||||
ld test.o -no-pie -nostdlib -T ./linker.ld -o test.elf
|
CC = cc
|
||||||
|
CFLAGS = -O2
|
||||||
|
LD = ld
|
||||||
|
QEMU = qemu-system-x86_64
|
||||||
|
QEMUFLAGS = -m 1G -enable-kvm -cpu host
|
||||||
|
LDINTERNALFLAGS := -Tlinker.ld -static -nostdlib -no-pie
|
||||||
|
INTERNALCFLAGS := -I../stivale -I. -ffreestanding -fno-stack-protector \
|
||||||
|
-fno-pic -fomit-frame-pointer -mno-80387 -mno-mmx -mno-3dnow -mno-sse \
|
||||||
|
-mno-sse2 -masm=intel
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
$(TARGET): stivale.o stivale2.o e9print.o
|
||||||
|
$(LD) $(LDINTERNALFLAGS) stivale.o stivale2.o e9print.o -o $@
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(CC) $(CFLAGS) $(INTERNALCFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(TARGET) stivale.o stivale2.o e9print.o
|
||||||
|
82
test/e9print.c
Normal file
82
test/e9print.c
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
#include <e9print.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
static const char CONVERSION_TABLE[] = "0123456789abcdef";
|
||||||
|
|
||||||
|
void e9_putc(char c) {
|
||||||
|
asm volatile ("out dx, al" :: "a" (c), "d" (0xE9) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
void e9_print(const char *msg) {
|
||||||
|
for (size_t i = 0; msg[i]; i++) {
|
||||||
|
e9_putc(msg[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void e9_puts(const char *msg) {
|
||||||
|
e9_print(msg);
|
||||||
|
e9_putc('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
static void e9_printhex(size_t num) {
|
||||||
|
int i;
|
||||||
|
char buf[17];
|
||||||
|
|
||||||
|
if (!num) {
|
||||||
|
e9_print("0x0");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[16] = 0;
|
||||||
|
|
||||||
|
for (i = 15; num; i--) {
|
||||||
|
buf[i] = CONVERSION_TABLE[num % 16];
|
||||||
|
num /= 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
e9_print("0x");
|
||||||
|
e9_print(&buf[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void e9_printdec(size_t num) {
|
||||||
|
int i;
|
||||||
|
char buf[21] = {0};
|
||||||
|
|
||||||
|
if (!num) {
|
||||||
|
e9_putc('0');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 19; num; i--) {
|
||||||
|
buf[i] = (num % 10) + 0x30;
|
||||||
|
num = num / 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
e9_print(buf + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void e9_printf(const char *format, ...) {
|
||||||
|
va_list argp;
|
||||||
|
va_start(argp, format);
|
||||||
|
|
||||||
|
while (*format != '\0') {
|
||||||
|
if (*format == '%') {
|
||||||
|
format++;
|
||||||
|
if (*format == 'x') {
|
||||||
|
e9_printhex(va_arg(argp, size_t));
|
||||||
|
} else if (*format == 'd') {
|
||||||
|
e9_printdec(va_arg(argp, size_t));
|
||||||
|
} else if (*format == 's') {
|
||||||
|
e9_print(va_arg(argp, char*));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
e9_putc(*format);
|
||||||
|
}
|
||||||
|
format++;
|
||||||
|
}
|
||||||
|
|
||||||
|
e9_putc('\n');
|
||||||
|
va_end(argp);
|
||||||
|
}
|
8
test/e9print.h
Normal file
8
test/e9print.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
void e9_putc(char c);
|
||||||
|
void e9_print(const char *msg);
|
||||||
|
void e9_puts(const char *msg);
|
||||||
|
void e9_printf(const char *format, ...);
|
@ -1,4 +1,4 @@
|
|||||||
DEFAULT_ENTRY=2
|
DEFAULT_ENTRY=0
|
||||||
TIMEOUT=3
|
TIMEOUT=3
|
||||||
GRAPHICS=yes
|
GRAPHICS=yes
|
||||||
|
|
||||||
@ -16,26 +16,16 @@ THEME_MARGIN=64
|
|||||||
BACKGROUND_PARTITION=0
|
BACKGROUND_PARTITION=0
|
||||||
BACKGROUND_PATH=bg.bmp
|
BACKGROUND_PATH=bg.bmp
|
||||||
|
|
||||||
:MyOS 0
|
:Stivale Test
|
||||||
|
|
||||||
PROTOCOL=stivale2
|
|
||||||
|
|
||||||
|
PROTOCOL=stivale
|
||||||
KERNEL_PARTITION=0
|
KERNEL_PARTITION=0
|
||||||
KERNEL_PATH=boot/test.elf
|
KERNEL_PATH=boot/test.elf
|
||||||
KERNEL_CMDLINE=something
|
KERNEL_CMDLINE=Hi! This is an example!
|
||||||
|
|
||||||
:MyOS 1
|
:Stivale2 Test
|
||||||
|
|
||||||
PROTOCOL=stivale2
|
PROTOCOL=stivale2
|
||||||
|
|
||||||
KERNEL_PARTITION=0
|
KERNEL_PARTITION=0
|
||||||
KERNEL_PATH=boot/test.elf
|
KERNEL_PATH=boot/test.elf
|
||||||
KERNEL_CMDLINE=something
|
KERNEL_CMDLINE=Woah! Another example!
|
||||||
|
|
||||||
:MyOS 2
|
|
||||||
|
|
||||||
PROTOCOL=stivale2
|
|
||||||
|
|
||||||
KERNEL_PARTITION=0
|
|
||||||
KERNEL_PATH=boot/test.elf
|
|
||||||
KERNEL_CMDLINE=something
|
|
||||||
|
@ -1,26 +1,37 @@
|
|||||||
ENTRY(_start)
|
ENTRY(stivale_main)
|
||||||
|
|
||||||
SECTIONS {
|
SECTIONS
|
||||||
. = 0xffffffff80100000;
|
{
|
||||||
|
. = 0x100000;
|
||||||
|
|
||||||
.stivalehdr : ALIGN(4K) {
|
.stivalehdr ALIGN(4K) :
|
||||||
*(.stivalehdr)
|
{
|
||||||
|
KEEP(*(.stivalehdr))
|
||||||
}
|
}
|
||||||
|
|
||||||
.text : ALIGN(4K) {
|
.stivale2hdr ALIGN(4K) :
|
||||||
*(.text*)
|
{
|
||||||
|
KEEP(*(.stivale2hdr))
|
||||||
}
|
}
|
||||||
|
|
||||||
.rodata : ALIGN(4K) {
|
.text ALIGN(4K) :
|
||||||
*(.rodata*)
|
{
|
||||||
|
KEEP(*(.text*))
|
||||||
}
|
}
|
||||||
|
|
||||||
.data : ALIGN(4K) {
|
.rodata ALIGN(4K) :
|
||||||
*(.data*)
|
{
|
||||||
|
KEEP(*(.rodata*))
|
||||||
}
|
}
|
||||||
|
|
||||||
.bss : ALIGN(4K) {
|
.data ALIGN(4K) :
|
||||||
*(.bss*)
|
{
|
||||||
*(COMMON)
|
KEEP(*(.data*))
|
||||||
|
}
|
||||||
|
|
||||||
|
.bss ALIGN(4K) :
|
||||||
|
{
|
||||||
|
KEEP(*(COMMON))
|
||||||
|
KEEP(*(.bss*))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
51
test/stivale.c
Normal file
51
test/stivale.c
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#include <stivale.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <e9print.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
static uint8_t stack[4096] = {0};
|
||||||
|
void stivale_main(struct stivale_struct *info);
|
||||||
|
|
||||||
|
__attribute__((section(".stivalehdr"), used))
|
||||||
|
struct stivale_header header = {
|
||||||
|
.stack = (uint64_t)(uintptr_t)stack + sizeof(stack),
|
||||||
|
.framebuffer_bpp = 0,
|
||||||
|
.framebuffer_width = 0,
|
||||||
|
.framebuffer_height = 0,
|
||||||
|
.flags = 1,
|
||||||
|
.entry_point = (uint64_t)(uintptr_t)stivale_main
|
||||||
|
};
|
||||||
|
|
||||||
|
void stivale_main(struct stivale_struct *info) {
|
||||||
|
// Print some info.
|
||||||
|
e9_puts("Stivale information passed to the kernel:");
|
||||||
|
e9_printf("Cmdline: %s", (char*)info->cmdline);
|
||||||
|
e9_printf("Memory map at %x with contents:", info->memory_map_addr);
|
||||||
|
|
||||||
|
struct stivale_mmap_entry *memmap = ((struct stivale_mmap_entry *)(info->memory_map_addr));
|
||||||
|
for (size_t i = 0; i < info->memory_map_entries; i++) {
|
||||||
|
struct stivale_mmap_entry e = memmap[i];
|
||||||
|
e9_printf("\tEntry %d: [%x+%x] %x", i, e.base, e.length, e.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
e9_printf("Framebuffer at %x with specifics:", info->framebuffer_addr);
|
||||||
|
e9_printf("\tPitch: %d", info->framebuffer_pitch);
|
||||||
|
e9_printf("\tWidth: %d", info->framebuffer_width);
|
||||||
|
e9_printf("\tHeight: %d", info->framebuffer_height);
|
||||||
|
e9_printf("\tBPP: %d", info->framebuffer_bpp);
|
||||||
|
e9_printf("RSDP at %x", info->rsdp);
|
||||||
|
|
||||||
|
e9_printf("Module map at %x with modules:", info->modules);
|
||||||
|
struct stivale_module *modules = ((struct stivale_module *)(info->modules));
|
||||||
|
for (size_t i = 0; i < info->module_count; i++) {
|
||||||
|
struct stivale_module e = *modules;
|
||||||
|
e9_printf("\tModule %d: [%x+%x] %s", i, e.begin, e.end, e.string);
|
||||||
|
modules = (struct stivale_module *)e.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
e9_printf("Epoch is %x", info->epoch);
|
||||||
|
e9_printf("Flags are %x", info->flags);
|
||||||
|
|
||||||
|
// Guru meditation.
|
||||||
|
for (;;);
|
||||||
|
}
|
124
test/stivale2.c
Normal file
124
test/stivale2.c
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
#include <stivale2.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <e9print.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
static uint8_t stack[4096] = {0};
|
||||||
|
void stivale2_main(struct stivale2_struct *info);
|
||||||
|
|
||||||
|
struct stivale2_header_tag_smp smp_request = {
|
||||||
|
.tag = {
|
||||||
|
.identifier = STIVALE2_HEADER_TAG_SMP_ID,
|
||||||
|
.next = 0
|
||||||
|
},
|
||||||
|
.flags = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
struct stivale2_header_tag_framebuffer framebuffer_request = {
|
||||||
|
.tag = {
|
||||||
|
.identifier = STIVALE2_HEADER_TAG_FRAMEBUFFER_ID,
|
||||||
|
.next = (uint64_t)&smp_request
|
||||||
|
},
|
||||||
|
.framebuffer_width = 0,
|
||||||
|
.framebuffer_height = 0,
|
||||||
|
.framebuffer_bpp = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
__attribute__((section(".stivale2hdr"), used))
|
||||||
|
struct stivale2_header header2 = {
|
||||||
|
.entry_point = (uint64_t)stivale2_main,
|
||||||
|
.stack = (uintptr_t)stack + sizeof(stack),
|
||||||
|
.flags = 0,
|
||||||
|
.tags = (uint64_t)&framebuffer_request
|
||||||
|
};
|
||||||
|
|
||||||
|
void stivale2_main(struct stivale2_struct *info) {
|
||||||
|
// Print stuff.
|
||||||
|
e9_puts("Stivale2 info passed to the kernel:");
|
||||||
|
e9_printf("Bootloader brand: %s", info->bootloader_brand);
|
||||||
|
e9_printf("Bootloader version: %s", info->bootloader_version);
|
||||||
|
|
||||||
|
// Print the tags.
|
||||||
|
struct stivale2_tag *tag = (struct stivale2_tag *)info->tags;
|
||||||
|
|
||||||
|
while (tag != NULL) {
|
||||||
|
switch (tag->identifier) {
|
||||||
|
case STIVALE2_STRUCT_TAG_CMDLINE_ID: {
|
||||||
|
struct stivale2_struct_tag_cmdline *c = (struct stivale2_struct_tag_cmdline *)tag;
|
||||||
|
e9_puts("Commandline tag:");
|
||||||
|
e9_printf("\tCmdline: %s", (char*)(c->cmdline));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case STIVALE2_STRUCT_TAG_MEMMAP_ID: {
|
||||||
|
struct stivale2_struct_tag_memmap *m = (struct stivale2_struct_tag_memmap *)tag;
|
||||||
|
e9_puts("Memmap tag:");
|
||||||
|
e9_printf("\tEntries: %d", m->entries);
|
||||||
|
for (size_t i = 0; i < m->entries; i++) {
|
||||||
|
struct stivale2_mmap_entry me = m->memmap[i];
|
||||||
|
e9_printf("\t\t[%x+%x] %x", me.base, me.length, me.type);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case STIVALE2_STRUCT_TAG_FRAMEBUFFER_ID: {
|
||||||
|
struct stivale2_struct_tag_framebuffer *f = (struct stivale2_struct_tag_framebuffer *)tag;
|
||||||
|
e9_puts("Framebuffer tag:");
|
||||||
|
e9_printf("\tAddress: %x", f->framebuffer_addr);
|
||||||
|
e9_printf("\tWidth: %d", f->framebuffer_width);
|
||||||
|
e9_printf("\tHeight: %d", f->framebuffer_height);
|
||||||
|
e9_printf("\tPitch: %d", f->framebuffer_pitch);
|
||||||
|
e9_printf("\tBPP: %d", f->framebuffer_bpp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case STIVALE2_STRUCT_TAG_MODULES_ID: {
|
||||||
|
struct stivale2_struct_tag_modules *m = (struct stivale2_struct_tag_modules *)tag;
|
||||||
|
e9_puts("Modules tag:");
|
||||||
|
e9_printf("\tCount: %d", m->module_count);
|
||||||
|
for (size_t i = 0; i < m->module_count; i++) {
|
||||||
|
struct stivale2_module me = m->modules[i];
|
||||||
|
e9_printf("\t\t[%x+%x] %s", me.begin, me.end, me.string);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case STIVALE2_STRUCT_TAG_RSDP_ID: {
|
||||||
|
struct stivale2_struct_tag_rsdp *r = (struct stivale2_struct_tag_rsdp *)tag;
|
||||||
|
e9_puts("RSDP tag:");
|
||||||
|
e9_printf("\tRSDP: %x", r->rsdp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case STIVALE2_STRUCT_TAG_EPOCH_ID: {
|
||||||
|
struct stivale2_struct_tag_epoch *e = (struct stivale2_struct_tag_epoch *)tag;
|
||||||
|
e9_puts("Epoch tag:");
|
||||||
|
e9_printf("\tEpoch: %x", e->epoch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case STIVALE2_STRUCT_TAG_FIRMWARE_ID: {
|
||||||
|
struct stivale2_struct_tag_firmware *f = (struct stivale2_struct_tag_firmware *)tag;
|
||||||
|
e9_puts("Firmware tag:");
|
||||||
|
e9_printf("\tFlags: %x", f->flags);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case STIVALE2_STRUCT_TAG_SMP_ID: {
|
||||||
|
struct stivale2_struct_tag_smp *s = (struct stivale2_struct_tag_smp *)tag;
|
||||||
|
e9_puts("SMP tag:");
|
||||||
|
e9_printf("\tFlags: %x", s->flags);
|
||||||
|
e9_printf("\tCPU Count: %d", s->cpu_count);
|
||||||
|
for (size_t i = 0; i < s->cpu_count; i++) {
|
||||||
|
struct stivale2_smp_info in = s->smp_info[i];
|
||||||
|
e9_printf("\t\tProcessor ID: %d", in.processor_id);
|
||||||
|
e9_printf("\t\tLAPIC ID: %d", in.lapic_id);
|
||||||
|
e9_printf("\t\tTarget Stack: %x", in.target_stack);
|
||||||
|
e9_printf("\t\tGOTO Address: %x", in.goto_address);
|
||||||
|
e9_printf("\t\tExtra Argument: %x", in.extra_argument);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
e9_printf("BUG: Unidentifier tag %x", tag->identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
tag = (struct stivale2_tag *)tag->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enter our sublime pale slumber.
|
||||||
|
for (;;);
|
||||||
|
}
|
@ -1,42 +0,0 @@
|
|||||||
; This is a compliant "kernel" meant for testing purposes.
|
|
||||||
|
|
||||||
; Header
|
|
||||||
section .stivale2hdr
|
|
||||||
|
|
||||||
stivale_header:
|
|
||||||
dq 0 ; entry point
|
|
||||||
dq stack.top ; rsp
|
|
||||||
dq 0 ; flags
|
|
||||||
dq lv5 ; tags
|
|
||||||
|
|
||||||
section .rodata
|
|
||||||
|
|
||||||
lv5:
|
|
||||||
dq 0x932f477032007e8f
|
|
||||||
dq smp
|
|
||||||
|
|
||||||
smp:
|
|
||||||
dq 0x1ab015085f3273df
|
|
||||||
dq 0
|
|
||||||
dq 1
|
|
||||||
|
|
||||||
section .bss
|
|
||||||
|
|
||||||
stack:
|
|
||||||
resb 4096
|
|
||||||
.top:
|
|
||||||
|
|
||||||
section .text
|
|
||||||
|
|
||||||
; Entry point
|
|
||||||
|
|
||||||
global _start
|
|
||||||
_start:
|
|
||||||
mov rax, 'h e l l '
|
|
||||||
mov rbx, 'o w o '
|
|
||||||
mov rcx, 'r l d '
|
|
||||||
mov rdx, 0xb8000
|
|
||||||
mov [rdx], rax
|
|
||||||
mov [rdx+8], rbx
|
|
||||||
mov [rdx+16], rcx
|
|
||||||
jmp $
|
|
Loading…
Reference in New Issue
Block a user