misc: Initial 3-stage bootloader work
This commit is contained in:
parent
5d75f5213c
commit
524829370d
12
Makefile
12
Makefile
|
@ -10,12 +10,15 @@ PATH := $(shell pwd)/toolchain/bin:$(PATH)
|
||||||
|
|
||||||
all: limine-install
|
all: limine-install
|
||||||
|
|
||||||
limine-install: limine-install.c limine.o
|
limine-install: limine-install.c limine.o limine_sys.o
|
||||||
$(CC) $(CFLAGS) -std=c11 limine.o limine-install.c -o limine-install
|
$(CC) $(CFLAGS) -std=c11 limine.o limine_sys.o limine-install.c -o limine-install
|
||||||
|
|
||||||
limine.o: limine.bin
|
limine.o: limine.bin
|
||||||
$(OBJCOPY) -B i8086 -I binary -O default limine.bin limine.o
|
$(OBJCOPY) -B i8086 -I binary -O default limine.bin limine.o
|
||||||
|
|
||||||
|
limine_sys.o: limine.bin
|
||||||
|
$(OBJCOPY) -B i8086 -I binary -O default limine.sys limine_sys.o
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f limine.o limine-install
|
rm -f limine.o limine-install
|
||||||
|
|
||||||
|
@ -28,6 +31,7 @@ bootloader: stage2 decompressor
|
||||||
cd bootsect && nasm bootsect.asm -fbin -o ../limine.bin
|
cd bootsect && nasm bootsect.asm -fbin -o ../limine.bin
|
||||||
cd pxeboot && nasm bootsect.asm -fbin -o ../limine-pxe.bin
|
cd pxeboot && nasm bootsect.asm -fbin -o ../limine-pxe.bin
|
||||||
cp stage2/stage2.map ./
|
cp stage2/stage2.map ./
|
||||||
|
cp stage2/stage3.bin ./limine.sys
|
||||||
|
|
||||||
bootloader-clean: stage2-clean decompressor-clean test-clean
|
bootloader-clean: stage2-clean decompressor-clean test-clean
|
||||||
rm -f stage2/stage2.bin.gz test/stage2.map test.hdd
|
rm -f stage2/stage2.bin.gz test/stage2.map test.hdd
|
||||||
|
@ -72,8 +76,8 @@ echfs-test: test.hdd bootloader | all
|
||||||
echfs-utils -g -p0 test.hdd import stage2.map boot/stage2.map
|
echfs-utils -g -p0 test.hdd import stage2.map boot/stage2.map
|
||||||
echfs-utils -g -p0 test.hdd import test/test.elf boot/test.elf
|
echfs-utils -g -p0 test.hdd import test/test.elf boot/test.elf
|
||||||
echfs-utils -g -p0 test.hdd import test/bg.bmp boot/bg.bmp
|
echfs-utils -g -p0 test.hdd import test/bg.bmp boot/bg.bmp
|
||||||
echfs-utils -g -p0 test.hdd import test/font.bin boot/font.bin
|
./limine-install ./ test.hdd
|
||||||
./limine-install test.hdd
|
echfs-utils -g -p0 test.hdd import ./limine.sys boot/limine.sys
|
||||||
qemu-system-x86_64 -net none -smp 4 -enable-kvm -cpu host -hda test.hdd -debugcon stdio
|
qemu-system-x86_64 -net none -smp 4 -enable-kvm -cpu host -hda test.hdd -debugcon stdio
|
||||||
|
|
||||||
ext2-test: test.hdd bootloader | all
|
ext2-test: test.hdd bootloader | all
|
||||||
|
|
|
@ -260,34 +260,53 @@ static bool _device_write(const void *buffer, uint64_t loc, size_t count) {
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
extern uint8_t _binary_limine_bin_start[], _binary_limine_bin_end[];
|
extern uint8_t _binary_limine_bin_start[], _binary_limine_bin_end[];
|
||||||
|
extern uint8_t _binary_limine_sys_start[], _binary_limine_sys_end[];
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
int ok = 1;
|
int ok = 1;
|
||||||
uint8_t *bootloader_img = _binary_limine_bin_start;
|
uint8_t *bootloader_img = _binary_limine_bin_start;
|
||||||
size_t bootloader_file_size =
|
size_t bootloader_file_size =
|
||||||
(size_t)_binary_limine_bin_end - (size_t)_binary_limine_bin_start;
|
(size_t)_binary_limine_bin_end - (size_t)_binary_limine_bin_start;
|
||||||
|
uint8_t *stage3_img = _binary_limine_sys_start;
|
||||||
|
size_t stage3_file_size =
|
||||||
|
(size_t)_binary_limine_sys_end - (size_t)_binary_limine_sys_start;
|
||||||
uint8_t orig_mbr[70], timestamp[6];
|
uint8_t orig_mbr[70], timestamp[6];
|
||||||
|
char *limine_sys_path = NULL;
|
||||||
|
int limine_sys = -1;
|
||||||
|
|
||||||
if (sizeof(off_t) != 8) {
|
if (sizeof(off_t) != 8) {
|
||||||
fprintf(stderr, "ERROR: off_t type is not 64-bit.\n");
|
fprintf(stderr, "ERROR: off_t type is not 64-bit.\n");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc > 1 && strstr(argv[1], "limine.bin") != NULL) {
|
if (argc < 3) {
|
||||||
fprintf(stderr,
|
printf("Usage: %s <boot directory> <device> [GPT partition index]\n", argv[0]);
|
||||||
"WARNING: Passing the bootloader binary as a file argument is\n"
|
|
||||||
" deprecated and should be avoided in the future.\n");
|
|
||||||
argc--;
|
|
||||||
argv[1] = argv[0];
|
|
||||||
argv++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argc < 2) {
|
|
||||||
printf("Usage: %s <device> [GPT partition index]\n", argv[0]);
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
device = open(argv[1], O_RDWR);
|
#define MAX_STAGE3_PATH 1024
|
||||||
|
|
||||||
|
limine_sys_path = malloc(MAX_STAGE3_PATH);
|
||||||
|
if (limine_sys_path == NULL) {
|
||||||
|
perror("ERROR");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(limine_sys_path, MAX_STAGE3_PATH, "%s/limine.sys", argv[1]);
|
||||||
|
|
||||||
|
limine_sys = creat(limine_sys_path, 0644);
|
||||||
|
if (limine_sys == -1) {
|
||||||
|
perror("ERROR");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (write(limine_sys, stage3_img, stage3_file_size) !=
|
||||||
|
(ssize_t)stage3_file_size) {
|
||||||
|
perror("ERROR");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
device = open(argv[2], O_RDWR);
|
||||||
if (device == -1) {
|
if (device == -1) {
|
||||||
perror("ERROR");
|
perror("ERROR");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
@ -483,6 +502,10 @@ cleanup:
|
||||||
free(cache);
|
free(cache);
|
||||||
if (device != -1)
|
if (device != -1)
|
||||||
close(device);
|
close(device);
|
||||||
|
if (limine_sys_path != NULL)
|
||||||
|
free(limine_sys_path);
|
||||||
|
if (limine_sys != -1)
|
||||||
|
close(limine_sys);
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
BIN
limine-pxe.bin
BIN
limine-pxe.bin
Binary file not shown.
BIN
limine.bin
BIN
limine.bin
Binary file not shown.
Binary file not shown.
BIN
stage2.map
BIN
stage2.map
Binary file not shown.
|
@ -2,6 +2,7 @@ CC = i386-elf-gcc
|
||||||
LD = i386-elf-gcc
|
LD = i386-elf-gcc
|
||||||
OBJCOPY = i386-elf-objcopy
|
OBJCOPY = i386-elf-objcopy
|
||||||
OBJDUMP = i386-elf-objdump
|
OBJDUMP = i386-elf-objdump
|
||||||
|
READELF = i386-elf-readelf
|
||||||
|
|
||||||
LIMINE_VERSION := $(shell git branch --show-current | sed 's/-branch//')
|
LIMINE_VERSION := $(shell git branch --show-current | sed 's/-branch//')
|
||||||
WERROR = -Werror
|
WERROR = -Werror
|
||||||
|
@ -44,13 +45,19 @@ ASM_FILES := $(shell find ./ -type f -name '*.asm' | sort)
|
||||||
OBJ := $(ASM_FILES:.asm=.o) $(C_FILES:.c=.o)
|
OBJ := $(ASM_FILES:.asm=.o) $(C_FILES:.c=.o)
|
||||||
HEADER_DEPS := $(C_FILES:.c=.d)
|
HEADER_DEPS := $(C_FILES:.c=.d)
|
||||||
|
|
||||||
all: stage2.map stage2.bin
|
all: stage2.map stage2.bin stage3.bin
|
||||||
|
|
||||||
|
stage2.bin: stages.bin
|
||||||
|
dd if=stages.bin bs=$$(( 0x$$($(READELF) -S stage2.elf | grep .stage3 | sed 's/^.*] //' | awk '{print $$3}' | sed 's/^0*//') - 0x8000 )) count=1 of=$@
|
||||||
|
|
||||||
|
stage3.bin: stages.bin
|
||||||
|
dd if=stages.bin bs=$$(( 0x$$($(READELF) -S stage2.elf | grep .stage3 | sed 's/^.*] //' | awk '{print $$3}' | sed 's/^0*//') - 0x8000 )) skip=1 of=$@
|
||||||
|
|
||||||
stage2.map: stage2.elf
|
stage2.map: stage2.elf
|
||||||
./gensyms.sh $(OBJDUMP)
|
./gensyms.sh $(OBJDUMP)
|
||||||
nasm symlist.gen -f bin -o $@
|
nasm symlist.gen -f bin -o $@
|
||||||
|
|
||||||
stage2.bin: stage2.elf
|
stages.bin: stage2.elf
|
||||||
$(OBJCOPY) -O binary $< $@
|
$(OBJCOPY) -O binary $< $@
|
||||||
|
|
||||||
stage2.elf: $(OBJ)
|
stage2.elf: $(OBJ)
|
||||||
|
@ -65,4 +72,4 @@ stage2.elf: $(OBJ)
|
||||||
nasm $< -f elf32 -o $@
|
nasm $< -f elf32 -o $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f symlist.gen stage2.map stage2.bin stage2.elf $(OBJ) $(HEADER_DEPS)
|
rm -f symlist.gen stage2.map stage2.bin stage2.elf stage3.bin $(OBJ) $(HEADER_DEPS)
|
||||||
|
|
|
@ -17,9 +17,9 @@
|
||||||
#define VGA_FONT_GLYPHS 256
|
#define VGA_FONT_GLYPHS 256
|
||||||
#define VGA_FONT_MAX (VGA_FONT_HEIGHT * VGA_FONT_GLYPHS)
|
#define VGA_FONT_MAX (VGA_FONT_HEIGHT * VGA_FONT_GLYPHS)
|
||||||
|
|
||||||
static uint8_t *vga_font;
|
stage3_data static uint8_t *vga_font;
|
||||||
|
|
||||||
static void vga_font_retrieve(void) {
|
stage3_text static void vga_font_retrieve(void) {
|
||||||
struct rm_regs r = {0};
|
struct rm_regs r = {0};
|
||||||
|
|
||||||
r.eax = 0x1130;
|
r.eax = 0x1130;
|
||||||
|
@ -31,37 +31,37 @@ static void vga_font_retrieve(void) {
|
||||||
memcpy(vga_font, (void *)rm_desegment(r.es, r.ebp), VGA_FONT_MAX);
|
memcpy(vga_font, (void *)rm_desegment(r.es, r.ebp), VGA_FONT_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t ansi_colours[8];
|
stage3_data static uint32_t ansi_colours[8];
|
||||||
|
|
||||||
static struct vbe_framebuffer_info fbinfo;
|
stage3_data static struct vbe_framebuffer_info fbinfo;
|
||||||
static uint32_t *vbe_framebuffer;
|
stage3_data static uint32_t *vbe_framebuffer;
|
||||||
static uint16_t vbe_pitch;
|
stage3_data static uint16_t vbe_pitch;
|
||||||
static uint16_t vbe_width;
|
stage3_data static uint16_t vbe_width;
|
||||||
static uint16_t vbe_height;
|
stage3_data static uint16_t vbe_height;
|
||||||
static uint16_t vbe_bpp;
|
stage3_data static uint16_t vbe_bpp;
|
||||||
|
|
||||||
static int frame_height, frame_width;
|
stage3_data static int frame_height, frame_width;
|
||||||
|
|
||||||
static struct image *background;
|
stage3_data static struct image *background;
|
||||||
|
|
||||||
static struct vbe_char *grid;
|
stage3_data static struct vbe_char *grid;
|
||||||
static struct vbe_char *front_grid;
|
stage3_data static struct vbe_char *front_grid;
|
||||||
|
|
||||||
static bool double_buffer_enabled = false;
|
stage3_data static bool double_buffer_enabled = false;
|
||||||
|
|
||||||
static bool cursor_status = true;
|
stage3_data static bool cursor_status = true;
|
||||||
|
|
||||||
static int cursor_x;
|
stage3_data static int cursor_x;
|
||||||
static int cursor_y;
|
stage3_data static int cursor_y;
|
||||||
|
|
||||||
static uint32_t cursor_fg = 0x00000000;
|
stage3_data static uint32_t cursor_fg = 0x00000000;
|
||||||
static uint32_t cursor_bg = 0x00ffffff;
|
stage3_data static uint32_t cursor_bg = 0x00ffffff;
|
||||||
static uint32_t text_fg;
|
stage3_data static uint32_t text_fg;
|
||||||
static uint32_t text_bg;
|
stage3_data static uint32_t text_bg;
|
||||||
|
|
||||||
static int rows;
|
stage3_data static int rows;
|
||||||
static int cols;
|
stage3_data static int cols;
|
||||||
static int margin_gradient;
|
stage3_data static int margin_gradient;
|
||||||
|
|
||||||
#define A(rgb) (uint8_t)(rgb >> 24)
|
#define A(rgb) (uint8_t)(rgb >> 24)
|
||||||
#define R(rgb) (uint8_t)(rgb >> 16)
|
#define R(rgb) (uint8_t)(rgb >> 16)
|
||||||
|
@ -69,7 +69,7 @@ static int margin_gradient;
|
||||||
#define B(rgb) (uint8_t)(rgb)
|
#define B(rgb) (uint8_t)(rgb)
|
||||||
#define ARGB(a, r, g, b) (a << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF)
|
#define ARGB(a, r, g, b) (a << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF)
|
||||||
|
|
||||||
static inline uint32_t colour_blend(uint32_t fg, uint32_t bg) {
|
stage3_text static inline uint32_t colour_blend(uint32_t fg, uint32_t bg) {
|
||||||
unsigned alpha = 255 - A(fg);
|
unsigned alpha = 255 - A(fg);
|
||||||
unsigned inv_alpha = A(fg) + 1;
|
unsigned inv_alpha = A(fg) + 1;
|
||||||
|
|
||||||
|
@ -80,19 +80,19 @@ static inline uint32_t colour_blend(uint32_t fg, uint32_t bg) {
|
||||||
return ARGB(0, r, g, b);
|
return ARGB(0, r, g, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vbe_plot_px(int x, int y, uint32_t hex) {
|
stage3_text void vbe_plot_px(int x, int y, uint32_t hex) {
|
||||||
size_t fb_i = x + (vbe_pitch / sizeof(uint32_t)) * y;
|
size_t fb_i = x + (vbe_pitch / sizeof(uint32_t)) * y;
|
||||||
|
|
||||||
vbe_framebuffer[fb_i] = hex;
|
vbe_framebuffer[fb_i] = hex;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _vbe_plot_bg_blent_px(int x, int y, uint32_t hex) {
|
stage3_text static void _vbe_plot_bg_blent_px(int x, int y, uint32_t hex) {
|
||||||
vbe_plot_px(x, y, colour_blend(hex, background->get_pixel(background, x, y)));
|
vbe_plot_px(x, y, colour_blend(hex, background->get_pixel(background, x, y)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void (*vbe_plot_bg_blent_px)(int x, int y, uint32_t hex) = vbe_plot_px;
|
stage3_data void (*vbe_plot_bg_blent_px)(int x, int y, uint32_t hex) = vbe_plot_px;
|
||||||
|
|
||||||
static uint32_t blend_gradient_from_box(int x, int y, uint32_t hex) {
|
stage3_text static uint32_t blend_gradient_from_box(int x, int y, uint32_t hex) {
|
||||||
if (x >= frame_width && x < frame_width + VGA_FONT_WIDTH * cols
|
if (x >= frame_width && x < frame_width + VGA_FONT_WIDTH * cols
|
||||||
&& y >= frame_height && y < frame_height + VGA_FONT_HEIGHT * rows) {
|
&& y >= frame_height && y < frame_height + VGA_FONT_HEIGHT * rows) {
|
||||||
return hex;
|
return hex;
|
||||||
|
@ -133,7 +133,7 @@ static uint32_t blend_gradient_from_box(int x, int y, uint32_t hex) {
|
||||||
return colour_blend((hex & 0xffffff) | (new_alpha << 24), bg_px);
|
return colour_blend((hex & 0xffffff) | (new_alpha << 24), bg_px);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vbe_plot_background(int x, int y, int width, int height) {
|
stage3_text void vbe_plot_background(int x, int y, int width, int height) {
|
||||||
if (background) {
|
if (background) {
|
||||||
for (int yy = 0; yy < height; yy++) {
|
for (int yy = 0; yy < height; yy++) {
|
||||||
for (int xx = 0; xx < width; xx++) {
|
for (int xx = 0; xx < width; xx++) {
|
||||||
|
@ -149,7 +149,7 @@ void vbe_plot_background(int x, int y, int width, int height) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vbe_plot_rect(int x, int y, int width, int height, uint32_t hex) {
|
stage3_text void vbe_plot_rect(int x, int y, int width, int height, uint32_t hex) {
|
||||||
for (int yy = 0; yy < height; yy++) {
|
for (int yy = 0; yy < height; yy++) {
|
||||||
for (int xx = 0; xx < width; xx++) {
|
for (int xx = 0; xx < width; xx++) {
|
||||||
vbe_plot_px(x + xx, y + yy, hex);
|
vbe_plot_px(x + xx, y + yy, hex);
|
||||||
|
@ -157,7 +157,7 @@ void vbe_plot_rect(int x, int y, int width, int height, uint32_t hex) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vbe_plot_bg_blent_rect(int x, int y, int width, int height, uint32_t hex) {
|
stage3_text void vbe_plot_bg_blent_rect(int x, int y, int width, int height, uint32_t hex) {
|
||||||
for (int yy = 0; yy < height; yy++) {
|
for (int yy = 0; yy < height; yy++) {
|
||||||
for (int xx = 0; xx < width; xx++) {
|
for (int xx = 0; xx < width; xx++) {
|
||||||
vbe_plot_bg_blent_px(x + xx, y + yy, hex);
|
vbe_plot_bg_blent_px(x + xx, y + yy, hex);
|
||||||
|
@ -171,7 +171,7 @@ struct vbe_char {
|
||||||
uint32_t bg;
|
uint32_t bg;
|
||||||
};
|
};
|
||||||
|
|
||||||
void vbe_plot_char(struct vbe_char *c, int x, int y) {
|
stage3_text void vbe_plot_char(struct vbe_char *c, int x, int y) {
|
||||||
uint8_t *glyph = &vga_font[(size_t)c->c * VGA_FONT_HEIGHT];
|
uint8_t *glyph = &vga_font[(size_t)c->c * VGA_FONT_HEIGHT];
|
||||||
|
|
||||||
vbe_plot_bg_blent_rect(x, y, VGA_FONT_WIDTH, VGA_FONT_HEIGHT, c->bg);
|
vbe_plot_bg_blent_rect(x, y, VGA_FONT_WIDTH, VGA_FONT_HEIGHT, c->bg);
|
||||||
|
@ -184,7 +184,7 @@ void vbe_plot_char(struct vbe_char *c, int x, int y) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void plot_char_grid(struct vbe_char *c, int x, int y) {
|
stage3_text static void plot_char_grid(struct vbe_char *c, int x, int y) {
|
||||||
if (!double_buffer_enabled) {
|
if (!double_buffer_enabled) {
|
||||||
vbe_plot_char(c, x * VGA_FONT_WIDTH + frame_width,
|
vbe_plot_char(c, x * VGA_FONT_WIDTH + frame_width,
|
||||||
y * VGA_FONT_HEIGHT + frame_height);
|
y * VGA_FONT_HEIGHT + frame_height);
|
||||||
|
@ -192,14 +192,14 @@ static void plot_char_grid(struct vbe_char *c, int x, int y) {
|
||||||
grid[x + y * cols] = *c;
|
grid[x + y * cols] = *c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_cursor(void) {
|
stage3_text static void clear_cursor(void) {
|
||||||
struct vbe_char c = grid[cursor_x + cursor_y * cols];
|
struct vbe_char c = grid[cursor_x + cursor_y * cols];
|
||||||
c.fg = text_fg;
|
c.fg = text_fg;
|
||||||
c.bg = text_bg;
|
c.bg = text_bg;
|
||||||
plot_char_grid(&c, cursor_x, cursor_y);
|
plot_char_grid(&c, cursor_x, cursor_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void draw_cursor(void) {
|
stage3_text static void draw_cursor(void) {
|
||||||
if (cursor_status) {
|
if (cursor_status) {
|
||||||
struct vbe_char c = grid[cursor_x + cursor_y * cols];
|
struct vbe_char c = grid[cursor_x + cursor_y * cols];
|
||||||
c.fg = cursor_fg;
|
c.fg = cursor_fg;
|
||||||
|
@ -208,7 +208,7 @@ static void draw_cursor(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scroll(void) {
|
stage3_text static void scroll(void) {
|
||||||
clear_cursor();
|
clear_cursor();
|
||||||
|
|
||||||
for (int i = cols; i < rows * cols; i++) {
|
for (int i = cols; i < rows * cols; i++) {
|
||||||
|
@ -227,7 +227,7 @@ static void scroll(void) {
|
||||||
draw_cursor();
|
draw_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void vbe_clear(bool move) {
|
stage3_text void vbe_clear(bool move) {
|
||||||
clear_cursor();
|
clear_cursor();
|
||||||
|
|
||||||
struct vbe_char empty;
|
struct vbe_char empty;
|
||||||
|
@ -246,37 +246,37 @@ void vbe_clear(bool move) {
|
||||||
draw_cursor();
|
draw_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void vbe_enable_cursor(void) {
|
stage3_text void vbe_enable_cursor(void) {
|
||||||
cursor_status = true;
|
cursor_status = true;
|
||||||
draw_cursor();
|
draw_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void vbe_disable_cursor(void) {
|
stage3_text void vbe_disable_cursor(void) {
|
||||||
clear_cursor();
|
clear_cursor();
|
||||||
cursor_status = false;
|
cursor_status = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vbe_set_cursor_pos(int x, int y) {
|
stage3_text void vbe_set_cursor_pos(int x, int y) {
|
||||||
clear_cursor();
|
clear_cursor();
|
||||||
cursor_x = x;
|
cursor_x = x;
|
||||||
cursor_y = y;
|
cursor_y = y;
|
||||||
draw_cursor();
|
draw_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void vbe_get_cursor_pos(int *x, int *y) {
|
stage3_text void vbe_get_cursor_pos(int *x, int *y) {
|
||||||
*x = cursor_x;
|
*x = cursor_x;
|
||||||
*y = cursor_y;
|
*y = cursor_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vbe_set_text_fg(int fg) {
|
stage3_text void vbe_set_text_fg(int fg) {
|
||||||
text_fg = ansi_colours[fg];
|
text_fg = ansi_colours[fg];
|
||||||
}
|
}
|
||||||
|
|
||||||
void vbe_set_text_bg(int bg) {
|
stage3_text void vbe_set_text_bg(int bg) {
|
||||||
text_bg = ansi_colours[bg];
|
text_bg = ansi_colours[bg];
|
||||||
}
|
}
|
||||||
|
|
||||||
void vbe_double_buffer_flush(void) {
|
stage3_text void vbe_double_buffer_flush(void) {
|
||||||
for (size_t i = 0; i < (size_t)rows * cols; i++) {
|
for (size_t i = 0; i < (size_t)rows * cols; i++) {
|
||||||
if (!memcmp(&grid[i], &front_grid[i], sizeof(struct vbe_char)))
|
if (!memcmp(&grid[i], &front_grid[i], sizeof(struct vbe_char)))
|
||||||
continue;
|
continue;
|
||||||
|
@ -291,7 +291,7 @@ void vbe_double_buffer_flush(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vbe_double_buffer(bool state) {
|
stage3_text void vbe_double_buffer(bool state) {
|
||||||
if (state) {
|
if (state) {
|
||||||
memcpy(front_grid, grid, rows * cols * sizeof(struct vbe_char));
|
memcpy(front_grid, grid, rows * cols * sizeof(struct vbe_char));
|
||||||
double_buffer_enabled = true;
|
double_buffer_enabled = true;
|
||||||
|
@ -308,7 +308,7 @@ void vbe_double_buffer(bool state) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vbe_putchar(uint8_t c) {
|
stage3_text void vbe_putchar(uint8_t c) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '\b':
|
case '\b':
|
||||||
if (cursor_x || cursor_y) {
|
if (cursor_x || cursor_y) {
|
||||||
|
@ -354,7 +354,7 @@ void vbe_putchar(uint8_t c) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vbe_tty_init(int *_rows, int *_cols, uint32_t *_colours, int _margin, int _margin_gradient, struct image *_background) {
|
stage3_text bool vbe_tty_init(int *_rows, int *_cols, uint32_t *_colours, int _margin, int _margin_gradient, struct image *_background) {
|
||||||
int req_width = 0, req_height = 0, req_bpp = 0;
|
int req_width = 0, req_height = 0, req_bpp = 0;
|
||||||
|
|
||||||
char *menu_resolution = config_get_value(NULL, 0, "MENU_RESOLUTION");
|
char *menu_resolution = config_get_value(NULL, 0, "MENU_RESOLUTION");
|
||||||
|
@ -495,7 +495,7 @@ struct vbe_mode_info_struct {
|
||||||
uint8_t reserved2[189];
|
uint8_t reserved2[189];
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
static void get_vbe_info(struct vbe_info_struct *buf) {
|
stage3_text static void get_vbe_info(struct vbe_info_struct *buf) {
|
||||||
struct rm_regs r = {0};
|
struct rm_regs r = {0};
|
||||||
|
|
||||||
r.eax = 0x4f00;
|
r.eax = 0x4f00;
|
||||||
|
@ -503,7 +503,7 @@ static void get_vbe_info(struct vbe_info_struct *buf) {
|
||||||
rm_int(0x10, &r, &r);
|
rm_int(0x10, &r, &r);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_vbe_mode_info(struct vbe_mode_info_struct *buf,
|
stage3_text static void get_vbe_mode_info(struct vbe_mode_info_struct *buf,
|
||||||
uint16_t mode) {
|
uint16_t mode) {
|
||||||
struct rm_regs r = {0};
|
struct rm_regs r = {0};
|
||||||
|
|
||||||
|
@ -513,7 +513,7 @@ static void get_vbe_mode_info(struct vbe_mode_info_struct *buf,
|
||||||
rm_int(0x10, &r, &r);
|
rm_int(0x10, &r, &r);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_vbe_mode(uint16_t mode) {
|
stage3_text static int set_vbe_mode(uint16_t mode) {
|
||||||
struct rm_regs r = {0};
|
struct rm_regs r = {0};
|
||||||
|
|
||||||
r.eax = 0x4f02;
|
r.eax = 0x4f02;
|
||||||
|
@ -550,7 +550,7 @@ struct edid_info_struct {
|
||||||
uint8_t checksum;
|
uint8_t checksum;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
static int get_edid_info(struct edid_info_struct *buf) {
|
stage3_text static int get_edid_info(struct edid_info_struct *buf) {
|
||||||
struct rm_regs r = {0};
|
struct rm_regs r = {0};
|
||||||
|
|
||||||
r.eax = 0x4f15;
|
r.eax = 0x4f15;
|
||||||
|
@ -572,13 +572,13 @@ struct resolution {
|
||||||
uint16_t bpp;
|
uint16_t bpp;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct resolution fallback_resolutions[] = {
|
stage3_data static struct resolution fallback_resolutions[] = {
|
||||||
{ 1024, 768, 32 },
|
{ 1024, 768, 32 },
|
||||||
{ 800, 600, 32 },
|
{ 800, 600, 32 },
|
||||||
{ 640, 480, 32 }
|
{ 640, 480, 32 }
|
||||||
};
|
};
|
||||||
|
|
||||||
bool init_vbe(struct vbe_framebuffer_info *ret,
|
stage3_text bool init_vbe(struct vbe_framebuffer_info *ret,
|
||||||
uint16_t target_width, uint16_t target_height, uint16_t target_bpp) {
|
uint16_t target_width, uint16_t target_height, uint16_t target_bpp) {
|
||||||
print("vbe: Initialising...\n");
|
print("vbe: Initialising...\n");
|
||||||
|
|
||||||
|
|
|
@ -43,4 +43,7 @@ uint64_t strtoui(const char *s, const char **end, int base);
|
||||||
|
|
||||||
typedef void *symbol[];
|
typedef void *symbol[];
|
||||||
|
|
||||||
|
#define stage3_text __attribute__((section(".stage3_text")))
|
||||||
|
#define stage3_data __attribute__((section(".stage3_data")))
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,7 +16,18 @@ bool config_ready = false;
|
||||||
|
|
||||||
static char *config_addr;
|
static char *config_addr;
|
||||||
|
|
||||||
|
extern symbol stage3_addr;
|
||||||
|
|
||||||
int init_config_disk(struct volume *part) {
|
int init_config_disk(struct volume *part) {
|
||||||
|
struct file_handle stage3;
|
||||||
|
|
||||||
|
if (fopen(&stage3, part, "/limine.sys")
|
||||||
|
&& fopen(&stage3, part, "/boot/limine.sys")) {
|
||||||
|
panic("Could not open stage 3");
|
||||||
|
}
|
||||||
|
|
||||||
|
fread(&stage3, stage3_addr, 0, stage3.size);
|
||||||
|
|
||||||
struct file_handle f;
|
struct file_handle f;
|
||||||
|
|
||||||
if (fopen(&f, part, "/limine.cfg")
|
if (fopen(&f, part, "/limine.cfg")
|
||||||
|
@ -35,6 +46,12 @@ int init_config_disk(struct volume *part) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int init_config_pxe(void) {
|
int init_config_pxe(void) {
|
||||||
|
struct tftp_file_handle stage3;
|
||||||
|
if (tftp_open(&stage3, 0, 69, "limine.sys")) {
|
||||||
|
panic("Could not open stage 3");
|
||||||
|
}
|
||||||
|
tftp_read(&stage3, stage3_addr, 0, stage3.file_size);
|
||||||
|
|
||||||
struct tftp_file_handle cfg;
|
struct tftp_file_handle cfg;
|
||||||
if (tftp_open(&cfg, 0, 69, "limine.cfg")
|
if (tftp_open(&cfg, 0, 69, "limine.cfg")
|
||||||
&& tftp_open(&cfg, 0, 69, "tomatboot.cfg")) {
|
&& tftp_open(&cfg, 0, 69, "tomatboot.cfg")) {
|
||||||
|
|
|
@ -5,18 +5,24 @@ SECTIONS
|
||||||
{
|
{
|
||||||
. = 0x8000;
|
. = 0x8000;
|
||||||
|
|
||||||
.text : {
|
.entry : {
|
||||||
KEEP(*(.entry*))
|
KEEP(*(.entry*))
|
||||||
KEEP(*(.realmode*))
|
|
||||||
*(.text*)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.rodata : {
|
.realmode : {
|
||||||
|
KEEP(*(.realmode*))
|
||||||
|
}
|
||||||
|
|
||||||
|
.stage2 : {
|
||||||
|
*(.text*)
|
||||||
|
*(.data*)
|
||||||
*(.rodata*)
|
*(.rodata*)
|
||||||
}
|
}
|
||||||
|
|
||||||
.data : {
|
.stage3 : {
|
||||||
*(.data*)
|
stage3_addr = .;
|
||||||
|
*(.stage3_text*)
|
||||||
|
*(.stage3_data*)
|
||||||
}
|
}
|
||||||
|
|
||||||
.bss : {
|
.bss : {
|
||||||
|
|
Loading…
Reference in New Issue