Wire up logic for graphical terminal
This commit is contained in:
parent
3eb7d5f0ba
commit
902109ef68
BIN
limine.bin
BIN
limine.bin
Binary file not shown.
@ -19,7 +19,7 @@ static void vga_font_retrieve(void) {
|
||||
struct rm_regs r = {0};
|
||||
|
||||
r.eax = 0x1130;
|
||||
r.ebx = 0x06;
|
||||
r.ebx = 0x0600;
|
||||
rm_int(0x10, &r, &r);
|
||||
|
||||
vga_font = ext_mem_balloc(VGA_FONT_MAX);
|
||||
@ -39,6 +39,12 @@ void vbe_plot_px(int x, int y, uint32_t hex) {
|
||||
vbe_framebuffer[fb_i] = hex;
|
||||
}
|
||||
|
||||
struct vbe_char {
|
||||
char c;
|
||||
uint32_t fg;
|
||||
uint32_t bg;
|
||||
};
|
||||
|
||||
void vbe_plot_char(struct vbe_char c, int x, int y) {
|
||||
int orig_x = x;
|
||||
uint8_t *glyph = &vga_font[c.c * VGA_FONT_HEIGHT];
|
||||
@ -86,7 +92,7 @@ static void draw_cursor(void) {
|
||||
vbe_plot_char(c, cursor_x * VGA_FONT_WIDTH, cursor_y * VGA_FONT_HEIGHT);
|
||||
}
|
||||
|
||||
void vbe_scroll(void) {
|
||||
static void scroll(void) {
|
||||
clear_cursor();
|
||||
|
||||
for (int i = cols; i < rows * cols; i++) {
|
||||
@ -105,7 +111,7 @@ void vbe_scroll(void) {
|
||||
draw_cursor();
|
||||
}
|
||||
|
||||
void vbe_clear(void) {
|
||||
void vbe_clear(bool move) {
|
||||
clear_cursor();
|
||||
|
||||
struct vbe_char empty;
|
||||
@ -116,8 +122,10 @@ void vbe_clear(void) {
|
||||
plot_char_grid(empty, i % cols, i / cols);
|
||||
}
|
||||
|
||||
cursor_x = 0;
|
||||
cursor_y = 0;
|
||||
if (move) {
|
||||
cursor_x = 0;
|
||||
cursor_y = 0;
|
||||
}
|
||||
|
||||
draw_cursor();
|
||||
}
|
||||
@ -144,25 +152,78 @@ void vbe_get_cursor_pos(int *x, int *y) {
|
||||
*y = cursor_y;
|
||||
}
|
||||
|
||||
void vbe_set_text_attributes(uint32_t fg, uint32_t bg) {
|
||||
text_fg = fg;
|
||||
text_bg = bg;
|
||||
static uint32_t ansi_colours[] = {
|
||||
0x00000000, // black
|
||||
0x00aa0000, // red
|
||||
0x0000aa00, // green
|
||||
0x00aa5500, // brown
|
||||
0x000000aa, // blue
|
||||
0x00aa00aa, // magenta
|
||||
0x0000aaaa, // cyan
|
||||
0x00aaaaaa // grey
|
||||
};
|
||||
|
||||
void vbe_set_text_fg(int fg) {
|
||||
text_fg = ansi_colours[fg];
|
||||
}
|
||||
|
||||
void vbe_set_cursor_attributes(uint32_t fg, uint32_t bg) {
|
||||
clear_cursor();
|
||||
cursor_fg = fg;
|
||||
cursor_bg = bg;
|
||||
draw_cursor();
|
||||
void vbe_set_text_bg(int bg) {
|
||||
text_bg = ansi_colours[bg];
|
||||
}
|
||||
|
||||
void vbe_tty_init(void) {
|
||||
void vbe_putchar(char c) {
|
||||
switch (c) {
|
||||
case '\b':
|
||||
if (cursor_x || cursor_y) {
|
||||
clear_cursor();
|
||||
if (cursor_x) {
|
||||
cursor_x--;
|
||||
} else {
|
||||
cursor_y--;
|
||||
cursor_x = cols - 1;
|
||||
}
|
||||
draw_cursor();
|
||||
}
|
||||
break;
|
||||
case '\r':
|
||||
vbe_set_cursor_pos(0, cursor_y);
|
||||
break;
|
||||
case '\n':
|
||||
if (cursor_y == (rows - 1)) {
|
||||
vbe_set_cursor_pos(0, rows - 1);
|
||||
scroll();
|
||||
} else {
|
||||
vbe_set_cursor_pos(0, cursor_y + 1);
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
clear_cursor();
|
||||
struct vbe_char ch;
|
||||
ch.c = c;
|
||||
ch.fg = text_fg;
|
||||
ch.bg = text_bg;
|
||||
plot_char_grid(ch, cursor_x++, cursor_y);
|
||||
if (cursor_x == cols) {
|
||||
cursor_x = 0;
|
||||
cursor_y++;
|
||||
}
|
||||
if (cursor_y == rows) {
|
||||
cursor_y--;
|
||||
scroll();
|
||||
}
|
||||
draw_cursor();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vbe_tty_init(int *_rows, int *_cols) {
|
||||
init_vbe(&vbe_framebuffer, &vbe_pitch, &vbe_width, &vbe_height, &vbe_bpp);
|
||||
vga_font_retrieve();
|
||||
cols = vbe_width / VGA_FONT_WIDTH;
|
||||
rows = vbe_height / VGA_FONT_HEIGHT;
|
||||
*_cols = cols = vbe_width / VGA_FONT_WIDTH;
|
||||
*_rows = rows = vbe_height / VGA_FONT_HEIGHT;
|
||||
grid = ext_mem_balloc(rows * cols * sizeof(struct vbe_char));
|
||||
vbe_clear();
|
||||
vbe_clear(true);
|
||||
}
|
||||
|
||||
struct vbe_info_struct {
|
||||
|
@ -2,13 +2,19 @@
|
||||
#define __DRIVERS__VBE_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct vbe_char {
|
||||
char c;
|
||||
uint32_t fg;
|
||||
uint32_t bg;
|
||||
};
|
||||
#include <stdbool.h>
|
||||
|
||||
int init_vbe(uint32_t **framebuffer, uint16_t *pitch, uint16_t *target_width, uint16_t *target_height, uint16_t *target_bpp);
|
||||
|
||||
void vbe_tty_init(int *rows, int *cols);
|
||||
|
||||
void vbe_putchar(char c);
|
||||
void vbe_clear(bool move);
|
||||
void vbe_enable_cursor(void);
|
||||
void vbe_disable_cursor(void);
|
||||
void vbe_set_cursor_pos(int x, int y);
|
||||
void vbe_get_cursor_pos(int *x, int *y);
|
||||
void vbe_set_text_fg(int fg);
|
||||
void vbe_set_text_bg(int bg);
|
||||
|
||||
#endif
|
||||
|
@ -9,23 +9,11 @@
|
||||
#define VD_COLS (80 * 2)
|
||||
#define VD_ROWS 25
|
||||
|
||||
static bool vga_textmode_initialised = false;
|
||||
|
||||
static void escape_parse(char c);
|
||||
static void text_putchar(char c);
|
||||
|
||||
static char *video_mem = (char *)0xb8000;
|
||||
static size_t cursor_offset = 0;
|
||||
static int cursor_status = 1;
|
||||
static uint8_t text_palette = 0x07;
|
||||
static uint8_t cursor_palette = 0x70;
|
||||
static int escape = 0;
|
||||
static int esc_value0 = 0;
|
||||
static int esc_value1 = 0;
|
||||
static int *esc_value = &esc_value0;
|
||||
static int esc_default0 = 1;
|
||||
static int esc_default1 = 1;
|
||||
static int *esc_default = &esc_default0;
|
||||
|
||||
static void clear_cursor(void) {
|
||||
video_mem[cursor_offset + 1] = text_palette;
|
||||
@ -51,23 +39,14 @@ static void scroll(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
void text_clear(void) {
|
||||
clear_cursor();
|
||||
for (size_t i = 0; i < VIDEO_BOTTOM; i += 2) {
|
||||
video_mem[i] = ' ';
|
||||
video_mem[i + 1] = text_palette;
|
||||
}
|
||||
cursor_offset = 0;
|
||||
draw_cursor();
|
||||
return;
|
||||
}
|
||||
|
||||
static void text_clear_no_move(void) {
|
||||
void text_clear(bool move) {
|
||||
clear_cursor();
|
||||
for (size_t i = 0; i < VIDEO_BOTTOM; i += 2) {
|
||||
video_mem[i] = ' ';
|
||||
video_mem[i + 1] = text_palette;
|
||||
}
|
||||
if (move)
|
||||
cursor_offset = 0;
|
||||
draw_cursor();
|
||||
return;
|
||||
}
|
||||
@ -86,20 +65,13 @@ void text_disable_cursor(void) {
|
||||
|
||||
// VGA cursor code taken from: https://wiki.osdev.org/Text_Mode_Cursor
|
||||
|
||||
void init_vga_textmode(void) {
|
||||
void init_vga_textmode(int *_rows, int *_cols) {
|
||||
port_out_b(0x3d4, 0x0a);
|
||||
port_out_b(0x3d5, 0x20);
|
||||
text_clear();
|
||||
text_clear(true);
|
||||
|
||||
vga_textmode_initialised = true;
|
||||
}
|
||||
|
||||
void deinit_vga_textmode(void) {
|
||||
struct rm_regs r = {0};
|
||||
r.eax = 0x0003;
|
||||
rm_int(0x10, &r, &r);
|
||||
|
||||
vga_textmode_initialised = false;
|
||||
*_rows = VD_ROWS;
|
||||
*_cols = VD_COLS / 2;
|
||||
}
|
||||
|
||||
static void text_set_cursor_palette(uint8_t c) {
|
||||
@ -140,24 +112,28 @@ void text_set_cursor_pos(int x, int y) {
|
||||
draw_cursor();
|
||||
}
|
||||
|
||||
void text_write(const char *buf, size_t count) {
|
||||
if (!vga_textmode_initialised)
|
||||
return;
|
||||
for (size_t i = 0; i < count; i++)
|
||||
text_putchar(buf[i]);
|
||||
static uint8_t ansi_colours[] = { 0, 4, 2, 0x0e, 1, 5, 3, 7 };
|
||||
|
||||
void text_set_text_fg(int fg) {
|
||||
text_palette = (text_palette & 0xf0) | ansi_colours[fg];
|
||||
}
|
||||
|
||||
static void text_putchar(char c) {
|
||||
if (escape) {
|
||||
escape_parse(c);
|
||||
return;
|
||||
}
|
||||
void text_set_text_bg(int bg) {
|
||||
text_palette = (text_palette & 0x0f) | (ansi_colours[bg] << 4);
|
||||
}
|
||||
|
||||
void text_putchar(char c) {
|
||||
switch (c) {
|
||||
case 0x00:
|
||||
case '\b':
|
||||
if (cursor_offset) {
|
||||
clear_cursor();
|
||||
cursor_offset -= 2;
|
||||
draw_cursor();
|
||||
}
|
||||
break;
|
||||
case '\r':
|
||||
text_set_cursor_pos(0, text_get_cursor_pos_y());
|
||||
break;
|
||||
case 0x1B:
|
||||
escape = 1;
|
||||
return;
|
||||
case '\n':
|
||||
if (text_get_cursor_pos_y() == (VD_ROWS - 1)) {
|
||||
clear_cursor();
|
||||
@ -167,16 +143,6 @@ static void text_putchar(char c) {
|
||||
text_set_cursor_pos(0, (text_get_cursor_pos_y() + 1));
|
||||
}
|
||||
break;
|
||||
case '\r':
|
||||
text_set_cursor_pos(0, text_get_cursor_pos_y());
|
||||
break;
|
||||
case '\b':
|
||||
if (cursor_offset) {
|
||||
clear_cursor();
|
||||
cursor_offset -= 2;
|
||||
draw_cursor();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
clear_cursor();
|
||||
video_mem[cursor_offset] = c;
|
||||
@ -187,116 +153,4 @@ static void text_putchar(char c) {
|
||||
cursor_offset += 2;
|
||||
draw_cursor();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static uint8_t ansi_colours[] = { 0, 4, 2, 0x0e, 1, 5, 3, 7 };
|
||||
|
||||
static void sgr(void) {
|
||||
|
||||
if (esc_value0 >= 30 && esc_value0 <= 37) {
|
||||
uint8_t pal = text_get_text_palette();
|
||||
pal = (pal & 0xf0) + ansi_colours[esc_value0 - 30];
|
||||
text_set_text_palette(pal);
|
||||
return;
|
||||
}
|
||||
|
||||
if (esc_value0 >= 40 && esc_value0 <= 47) {
|
||||
uint8_t pal = text_get_text_palette();
|
||||
pal = (pal & 0x0f) + ansi_colours[esc_value0 - 40] * 0x10;
|
||||
text_set_text_palette(pal);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void escape_parse(char c) {
|
||||
|
||||
if (c >= '0' && c <= '9') {
|
||||
*esc_value *= 10;
|
||||
*esc_value += c - '0';
|
||||
*esc_default = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case '[':
|
||||
return;
|
||||
case ';':
|
||||
esc_value = &esc_value1;
|
||||
esc_default = &esc_default1;
|
||||
return;
|
||||
case 'A':
|
||||
if (esc_default0)
|
||||
esc_value0 = 1;
|
||||
if (esc_value0 > text_get_cursor_pos_y())
|
||||
esc_value0 = text_get_cursor_pos_y();
|
||||
text_set_cursor_pos(text_get_cursor_pos_x(),
|
||||
text_get_cursor_pos_y() - esc_value0);
|
||||
break;
|
||||
case 'B':
|
||||
if (esc_default0)
|
||||
esc_value0 = 1;
|
||||
if ((text_get_cursor_pos_y() + esc_value0) > (VD_ROWS - 1))
|
||||
esc_value0 = (VD_ROWS - 1) - text_get_cursor_pos_y();
|
||||
text_set_cursor_pos(text_get_cursor_pos_x(),
|
||||
text_get_cursor_pos_y() + esc_value0);
|
||||
break;
|
||||
case 'C':
|
||||
if (esc_default0)
|
||||
esc_value0 = 1;
|
||||
if ((text_get_cursor_pos_x() + esc_value0) > (VD_COLS / 2 - 1))
|
||||
esc_value0 = (VD_COLS / 2 - 1) - text_get_cursor_pos_x();
|
||||
text_set_cursor_pos(text_get_cursor_pos_x() + esc_value0,
|
||||
text_get_cursor_pos_y());
|
||||
break;
|
||||
case 'D':
|
||||
if (esc_default0)
|
||||
esc_value0 = 1;
|
||||
if (esc_value0 > text_get_cursor_pos_x())
|
||||
esc_value0 = text_get_cursor_pos_x();
|
||||
text_set_cursor_pos(text_get_cursor_pos_x() - esc_value0,
|
||||
text_get_cursor_pos_y());
|
||||
break;
|
||||
case 'H':
|
||||
esc_value0--;
|
||||
esc_value1--;
|
||||
if (esc_default0)
|
||||
esc_value0 = 0;
|
||||
if (esc_default1)
|
||||
esc_value1 = 0;
|
||||
if (esc_value1 >= (VD_COLS / 2))
|
||||
esc_value1 = (VD_COLS / 2) - 1;
|
||||
if (esc_value0 >= VD_ROWS)
|
||||
esc_value0 = VD_ROWS - 1;
|
||||
text_set_cursor_pos(esc_value1, esc_value0);
|
||||
break;
|
||||
case 'm':
|
||||
sgr();
|
||||
break;
|
||||
case 'J':
|
||||
switch (esc_value0) {
|
||||
case 2:
|
||||
text_clear_no_move();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
escape = 0;
|
||||
text_putchar('?');
|
||||
break;
|
||||
}
|
||||
|
||||
esc_value = &esc_value0;
|
||||
esc_value0 = 0;
|
||||
esc_value1 = 0;
|
||||
esc_default = &esc_default0;
|
||||
esc_default0 = 1;
|
||||
esc_default1 = 1;
|
||||
escape = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1,18 +1,17 @@
|
||||
#ifndef __DRIVERS__VGA_TEXTMODE_H__
|
||||
#define __DRIVERS__VGA_TEXTMODE_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
void init_vga_textmode(void);
|
||||
void deinit_vga_textmode(void);
|
||||
void init_vga_textmode(int *rows, int *cols);
|
||||
|
||||
void text_write(const char *, size_t);
|
||||
|
||||
void text_get_cursor_pos(int *x, int *y);
|
||||
void text_set_cursor_pos(int x, int y);
|
||||
|
||||
void text_clear(void);
|
||||
void text_putchar(char c);
|
||||
void text_clear(bool move);
|
||||
void text_enable_cursor(void);
|
||||
void text_disable_cursor(void);
|
||||
void text_set_cursor_pos(int x, int y);
|
||||
void text_get_cursor_pos(int *x, int *y);
|
||||
void text_set_text_fg(int fg);
|
||||
void text_set_text_bg(int bg);
|
||||
|
||||
#endif
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <lib/blib.h>
|
||||
#include <lib/libc.h>
|
||||
#include <drivers/vga_textmode.h>
|
||||
#include <lib/term.h>
|
||||
#include <lib/real.h>
|
||||
#include <lib/cio.h>
|
||||
#include <lib/e820.h>
|
||||
@ -214,14 +214,14 @@ int getchar(void) {
|
||||
|
||||
static void gets_reprint_string(int x, int y, const char *s, size_t limit) {
|
||||
int last_x, last_y;
|
||||
text_get_cursor_pos(&last_x, &last_y);
|
||||
text_set_cursor_pos(x, y);
|
||||
get_cursor_pos(&last_x, &last_y);
|
||||
set_cursor_pos(x, y);
|
||||
for (size_t i = 0; i < limit; i++) {
|
||||
text_write(" ", 1);
|
||||
term_write(" ", 1);
|
||||
}
|
||||
text_set_cursor_pos(x, y);
|
||||
text_write(s, strlen(s));
|
||||
text_set_cursor_pos(last_x, last_y);
|
||||
set_cursor_pos(x, y);
|
||||
term_write(s, strlen(s));
|
||||
set_cursor_pos(last_x, last_y);
|
||||
}
|
||||
|
||||
void gets(const char *orig_str, char *buf, size_t limit) {
|
||||
@ -230,7 +230,7 @@ void gets(const char *orig_str, char *buf, size_t limit) {
|
||||
buf[orig_str_len] = 0;
|
||||
|
||||
int orig_x, orig_y;
|
||||
text_get_cursor_pos(&orig_x, &orig_y);
|
||||
get_cursor_pos(&orig_x, &orig_y);
|
||||
|
||||
print("%s", buf);
|
||||
|
||||
@ -240,13 +240,13 @@ void gets(const char *orig_str, char *buf, size_t limit) {
|
||||
case GETCHAR_CURSOR_LEFT:
|
||||
if (i) {
|
||||
i--;
|
||||
text_write("\b", 1);
|
||||
term_write("\b", 1);
|
||||
}
|
||||
continue;
|
||||
case GETCHAR_CURSOR_RIGHT:
|
||||
if (i < strlen(buf)) {
|
||||
i++;
|
||||
text_write(" ", 1);
|
||||
term_write(" ", 1);
|
||||
gets_reprint_string(orig_x, orig_y, buf, limit);
|
||||
}
|
||||
continue;
|
||||
@ -258,12 +258,12 @@ void gets(const char *orig_str, char *buf, size_t limit) {
|
||||
if (!buf[j])
|
||||
break;
|
||||
}
|
||||
text_write("\b", 1);
|
||||
term_write("\b", 1);
|
||||
gets_reprint_string(orig_x, orig_y, buf, limit);
|
||||
}
|
||||
continue;
|
||||
case '\r':
|
||||
text_write("\n", 1);
|
||||
term_write("\n", 1);
|
||||
return;
|
||||
default:
|
||||
if (strlen(buf) < limit-1) {
|
||||
@ -273,7 +273,7 @@ void gets(const char *orig_str, char *buf, size_t limit) {
|
||||
break;
|
||||
}
|
||||
buf[i++] = c;
|
||||
text_write(" ", 1);
|
||||
term_write(" ", 1);
|
||||
gets_reprint_string(orig_x, orig_y, buf, limit);
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <lib/print.h>
|
||||
#include <lib/blib.h>
|
||||
#include <lib/cio.h>
|
||||
#include <drivers/vga_textmode.h>
|
||||
#include <lib/term.h>
|
||||
|
||||
static const char *base_digits = "0123456789abcdef";
|
||||
|
||||
@ -167,7 +167,7 @@ void vprint(const char *fmt, va_list args) {
|
||||
}
|
||||
|
||||
out:
|
||||
text_write(print_buf, print_buf_i);
|
||||
term_write(print_buf, print_buf_i);
|
||||
|
||||
#ifdef E9_OUTPUT
|
||||
for (size_t i = 0; i < print_buf_i; i++)
|
||||
|
209
src/lib/term.c
Normal file
209
src/lib/term.c
Normal file
@ -0,0 +1,209 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <lib/term.h>
|
||||
#include <lib/real.h>
|
||||
#include <drivers/vga_textmode.h>
|
||||
#include <drivers/vbe.h>
|
||||
|
||||
static enum {
|
||||
NOT_READY,
|
||||
VBE,
|
||||
TEXTMODE
|
||||
} term_backend = NOT_READY;
|
||||
|
||||
void (*raw_putchar)(char c);
|
||||
void (*clear)(bool move);
|
||||
void (*enable_cursor)(void);
|
||||
void (*disable_cursor)(void);
|
||||
void (*set_cursor_pos)(int x, int y);
|
||||
void (*get_cursor_pos)(int *x, int *y);
|
||||
void (*set_text_fg)(int fg);
|
||||
void (*set_text_bg)(int bg);
|
||||
|
||||
static int rows, cols;
|
||||
|
||||
void term_vbe(void) {
|
||||
vbe_tty_init(&rows, &cols);
|
||||
|
||||
raw_putchar = vbe_putchar;
|
||||
clear = vbe_clear;
|
||||
enable_cursor = vbe_enable_cursor;
|
||||
disable_cursor = vbe_disable_cursor;
|
||||
set_cursor_pos = vbe_set_cursor_pos;
|
||||
get_cursor_pos = vbe_get_cursor_pos;
|
||||
set_text_fg = vbe_set_text_fg;
|
||||
set_text_bg = vbe_set_text_bg;
|
||||
|
||||
term_backend = VBE;
|
||||
}
|
||||
|
||||
void term_textmode(void) {
|
||||
init_vga_textmode(&rows, &cols);
|
||||
|
||||
raw_putchar = text_putchar;
|
||||
clear = text_clear;
|
||||
enable_cursor = text_enable_cursor;
|
||||
disable_cursor = text_disable_cursor;
|
||||
set_cursor_pos = text_set_cursor_pos;
|
||||
get_cursor_pos = text_get_cursor_pos;
|
||||
set_text_fg = text_set_text_fg;
|
||||
set_text_bg = text_set_text_bg;
|
||||
|
||||
term_backend = TEXTMODE;
|
||||
}
|
||||
|
||||
void term_deinit(void) {
|
||||
struct rm_regs r = {0};
|
||||
r.eax = 0x0003;
|
||||
rm_int(0x10, &r, &r);
|
||||
|
||||
term_backend = NOT_READY;
|
||||
}
|
||||
|
||||
static void term_putchar(char c);
|
||||
|
||||
void term_write(const char *buf, size_t count) {
|
||||
if (term_backend == NOT_READY)
|
||||
return;
|
||||
for (size_t i = 0; i < count; i++)
|
||||
term_putchar(buf[i]);
|
||||
}
|
||||
|
||||
static int get_cursor_pos_x(void) {
|
||||
int x, y;
|
||||
get_cursor_pos(&x, &y);
|
||||
return x;
|
||||
}
|
||||
|
||||
static int get_cursor_pos_y(void) {
|
||||
int x, y;
|
||||
get_cursor_pos(&x, &y);
|
||||
return y;
|
||||
}
|
||||
|
||||
static void escape_parse(char c);
|
||||
|
||||
static int escape = 0;
|
||||
static int esc_value0 = 0;
|
||||
static int esc_value1 = 0;
|
||||
static int *esc_value = &esc_value0;
|
||||
static int esc_default0 = 1;
|
||||
static int esc_default1 = 1;
|
||||
static int *esc_default = &esc_default0;
|
||||
|
||||
static void term_putchar(char c) {
|
||||
if (escape) {
|
||||
escape_parse(c);
|
||||
return;
|
||||
}
|
||||
switch (c) {
|
||||
case 0x00:
|
||||
break;
|
||||
case 0x1B:
|
||||
escape = 1;
|
||||
return;
|
||||
default:
|
||||
raw_putchar(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void sgr(void) {
|
||||
if (esc_value0 >= 30 && esc_value0 <= 37) {
|
||||
set_text_fg(esc_value0 - 30);
|
||||
return;
|
||||
}
|
||||
|
||||
if (esc_value0 >= 40 && esc_value0 <= 47) {
|
||||
set_text_bg(esc_value0 - 40);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void escape_parse(char c) {
|
||||
if (c >= '0' && c <= '9') {
|
||||
*esc_value *= 10;
|
||||
*esc_value += c - '0';
|
||||
*esc_default = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case '[':
|
||||
return;
|
||||
case ';':
|
||||
esc_value = &esc_value1;
|
||||
esc_default = &esc_default1;
|
||||
return;
|
||||
case 'A':
|
||||
if (esc_default0)
|
||||
esc_value0 = 1;
|
||||
if (esc_value0 > get_cursor_pos_y())
|
||||
esc_value0 = get_cursor_pos_y();
|
||||
set_cursor_pos(get_cursor_pos_x(),
|
||||
get_cursor_pos_y() - esc_value0);
|
||||
break;
|
||||
case 'B':
|
||||
if (esc_default0)
|
||||
esc_value0 = 1;
|
||||
if ((get_cursor_pos_y() + esc_value0) > (rows - 1))
|
||||
esc_value0 = (rows - 1) - get_cursor_pos_y();
|
||||
set_cursor_pos(get_cursor_pos_x(),
|
||||
get_cursor_pos_y() + esc_value0);
|
||||
break;
|
||||
case 'C':
|
||||
if (esc_default0)
|
||||
esc_value0 = 1;
|
||||
if ((get_cursor_pos_x() + esc_value0) > (cols - 1))
|
||||
esc_value0 = (cols - 1) - get_cursor_pos_x();
|
||||
set_cursor_pos(get_cursor_pos_x() + esc_value0,
|
||||
get_cursor_pos_y());
|
||||
break;
|
||||
case 'D':
|
||||
if (esc_default0)
|
||||
esc_value0 = 1;
|
||||
if (esc_value0 > get_cursor_pos_x())
|
||||
esc_value0 = get_cursor_pos_x();
|
||||
set_cursor_pos(get_cursor_pos_x() - esc_value0,
|
||||
get_cursor_pos_y());
|
||||
break;
|
||||
case 'H':
|
||||
esc_value0--;
|
||||
esc_value1--;
|
||||
if (esc_default0)
|
||||
esc_value0 = 0;
|
||||
if (esc_default1)
|
||||
esc_value1 = 0;
|
||||
if (esc_value1 >= cols)
|
||||
esc_value1 = cols - 1;
|
||||
if (esc_value0 >= rows)
|
||||
esc_value0 = rows - 1;
|
||||
set_cursor_pos(esc_value1, esc_value0);
|
||||
break;
|
||||
case 'm':
|
||||
sgr();
|
||||
break;
|
||||
case 'J':
|
||||
switch (esc_value0) {
|
||||
case 2:
|
||||
clear(false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
escape = 0;
|
||||
raw_putchar('?');
|
||||
break;
|
||||
}
|
||||
|
||||
esc_value = &esc_value0;
|
||||
esc_value0 = 0;
|
||||
esc_value1 = 0;
|
||||
esc_default = &esc_default0;
|
||||
esc_default0 = 1;
|
||||
esc_default1 = 1;
|
||||
escape = 0;
|
||||
}
|
21
src/lib/term.h
Normal file
21
src/lib/term.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef __LIB__TERM_H__
|
||||
#define __LIB__TERM_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
extern void (*raw_putchar)(char c);
|
||||
extern void (*clear)(bool move);
|
||||
extern void (*enable_cursor)(void);
|
||||
extern void (*disable_cursor)(void);
|
||||
extern void (*set_cursor_pos)(int x, int y);
|
||||
extern void (*get_cursor_pos)(int *x, int *y);
|
||||
extern void (*set_text_fg)(int fg);
|
||||
extern void (*set_text_bg)(int bg);
|
||||
|
||||
void term_vbe(void);
|
||||
void term_textmode(void);
|
||||
void term_deinit(void);
|
||||
void term_write(const char *buf, size_t count);
|
||||
|
||||
#endif
|
30
src/main.c
30
src/main.c
@ -14,7 +14,7 @@ ASM_BASIC(
|
||||
);
|
||||
|
||||
#include <limine.h>
|
||||
#include <drivers/vga_textmode.h>
|
||||
#include <lib/term.h>
|
||||
#include <lib/real.h>
|
||||
#include <lib/blib.h>
|
||||
#include <lib/libc.h>
|
||||
@ -32,8 +32,7 @@ ASM_BASIC(
|
||||
#include <menu.h>
|
||||
|
||||
void main(int boot_drive) {
|
||||
// Initial prompt.
|
||||
init_vga_textmode();
|
||||
term_textmode();
|
||||
|
||||
print("Limine " LIMINE_VERSION "\n\n");
|
||||
|
||||
@ -59,25 +58,32 @@ void main(int boot_drive) {
|
||||
}
|
||||
}
|
||||
|
||||
char *cmdline = menu();
|
||||
|
||||
init_e820();
|
||||
init_memmap();
|
||||
|
||||
char proto[32];
|
||||
if (!config_get_value(proto, 0, 32, "KERNEL_PROTO")) {
|
||||
if (!config_get_value(proto, 0, 32, "PROTOCOL")) {
|
||||
char buf[32];
|
||||
|
||||
if (config_get_value(buf, 0, 32, "GRAPHICS")) {
|
||||
if (!strcmp(buf, "on")) {
|
||||
term_vbe();
|
||||
}
|
||||
}
|
||||
|
||||
char *cmdline = menu();
|
||||
|
||||
if (!config_get_value(buf, 0, 32, "KERNEL_PROTO")) {
|
||||
if (!config_get_value(buf, 0, 32, "PROTOCOL")) {
|
||||
panic("PROTOCOL not specified");
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcmp(proto, "stivale")) {
|
||||
if (!strcmp(buf, "stivale")) {
|
||||
stivale_load(cmdline, boot_drive);
|
||||
} else if (!strcmp(proto, "stivale2")) {
|
||||
} else if (!strcmp(buf, "stivale2")) {
|
||||
stivale2_load(cmdline, boot_drive);
|
||||
} else if (!strcmp(proto, "linux")) {
|
||||
} else if (!strcmp(buf, "linux")) {
|
||||
linux_load(cmdline, boot_drive);
|
||||
} else if (!strcmp(proto, "chainload")) {
|
||||
} else if (!strcmp(buf, "chainload")) {
|
||||
chainload();
|
||||
} else {
|
||||
panic("Invalid protocol specified");
|
||||
|
14
src/menu.c
14
src/menu.c
@ -7,7 +7,7 @@
|
||||
#include <lib/blib.h>
|
||||
#include <lib/libc.h>
|
||||
#include <lib/config.h>
|
||||
#include <drivers/vga_textmode.h>
|
||||
#include <lib/term.h>
|
||||
|
||||
static char *cmdline;
|
||||
#define CMDLINE_MAX 1024
|
||||
@ -26,12 +26,12 @@ char *menu(void) {
|
||||
}
|
||||
}
|
||||
|
||||
text_disable_cursor();
|
||||
disable_cursor();
|
||||
int selected_entry = 0;
|
||||
bool skip_timeout = false;
|
||||
|
||||
refresh:
|
||||
text_clear();
|
||||
clear(true);
|
||||
print("\n\n \e[36m Limine " LIMINE_VERSION " \e[37m\n\n\n");
|
||||
|
||||
print("Select an entry:\n\n");
|
||||
@ -78,17 +78,17 @@ refresh:
|
||||
case '\r':
|
||||
autoboot:
|
||||
config_set_entry(selected_entry);
|
||||
text_enable_cursor();
|
||||
enable_cursor();
|
||||
if (!config_get_value(cmdline, 0, CMDLINE_MAX, "KERNEL_CMDLINE")) {
|
||||
if (!config_get_value(cmdline, 0, CMDLINE_MAX, "CMDLINE")) {
|
||||
cmdline[0] = '\0';
|
||||
}
|
||||
}
|
||||
text_clear();
|
||||
clear(true);
|
||||
return cmdline;
|
||||
case 'e':
|
||||
config_set_entry(selected_entry);
|
||||
text_enable_cursor();
|
||||
enable_cursor();
|
||||
if (!config_get_value(cmdline, 0, CMDLINE_MAX, "KERNEL_CMDLINE")) {
|
||||
if (!config_get_value(cmdline, 0, CMDLINE_MAX, "CMDLINE")) {
|
||||
cmdline[0] = '\0';
|
||||
@ -96,7 +96,7 @@ refresh:
|
||||
}
|
||||
print("\n\n> ");
|
||||
gets(cmdline, cmdline, CMDLINE_MAX);
|
||||
text_clear();
|
||||
clear(true);
|
||||
return cmdline;
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include <lib/config.h>
|
||||
#include <lib/blib.h>
|
||||
#include <drivers/disk.h>
|
||||
#include <drivers/vga_textmode.h>
|
||||
#include <lib/term.h>
|
||||
#include <lib/asm.h>
|
||||
|
||||
void chainload(void) {
|
||||
@ -25,7 +25,7 @@ void chainload(void) {
|
||||
drive = (int)strtoui(buf);
|
||||
}
|
||||
|
||||
deinit_vga_textmode();
|
||||
term_deinit();
|
||||
|
||||
if (part != -1) {
|
||||
struct part p;
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <fs/file.h>
|
||||
#include <lib/blib.h>
|
||||
#include <lib/real.h>
|
||||
#include <drivers/vga_textmode.h>
|
||||
#include <lib/term.h>
|
||||
#include <lib/config.h>
|
||||
#include <lib/print.h>
|
||||
#include <lib/memmap.h>
|
||||
@ -135,7 +135,7 @@ void linux_load(char *cmdline, int boot_drive) {
|
||||
uint16_t real_mode_code_seg = rm_seg(real_mode_code);
|
||||
uint16_t kernel_entry_seg = real_mode_code_seg + 0x20;
|
||||
|
||||
deinit_vga_textmode();
|
||||
term_deinit();
|
||||
|
||||
ASM(
|
||||
"cli\n\t"
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <lib/rand.h>
|
||||
#include <lib/real.h>
|
||||
#include <drivers/vbe.h>
|
||||
#include <drivers/vga_textmode.h>
|
||||
#include <lib/term.h>
|
||||
#include <drivers/pic.h>
|
||||
#include <fs/file.h>
|
||||
#include <lib/asm.h>
|
||||
@ -224,6 +224,8 @@ void stivale_load(char *cmdline, int boot_drive) {
|
||||
stivale_struct.framebuffer_height = stivale_hdr.framebuffer_height;
|
||||
stivale_struct.framebuffer_bpp = stivale_hdr.framebuffer_bpp;
|
||||
|
||||
term_deinit();
|
||||
|
||||
if (stivale_hdr.flags & (1 << 0)) {
|
||||
uint32_t *fb32;
|
||||
init_vbe(&fb32,
|
||||
@ -232,8 +234,6 @@ void stivale_load(char *cmdline, int boot_drive) {
|
||||
&stivale_struct.framebuffer_height,
|
||||
&stivale_struct.framebuffer_bpp);
|
||||
stivale_struct.framebuffer_addr = (uint64_t)(size_t)fb32;
|
||||
} else {
|
||||
deinit_vga_textmode();
|
||||
}
|
||||
|
||||
size_t memmap_entries;
|
||||
@ -241,6 +241,12 @@ void stivale_load(char *cmdline, int boot_drive) {
|
||||
stivale_struct.memory_map_entries = (uint64_t)memmap_entries;
|
||||
stivale_struct.memory_map_addr = (uint64_t)(size_t)memmap;
|
||||
|
||||
stivale_spinup(bits, level5pg && (stivale_hdr.flags & (1 << 1)),
|
||||
entry_point, &stivale_struct, stivale_hdr.stack);
|
||||
}
|
||||
|
||||
__attribute__((noreturn)) void stivale_spinup(int bits, bool level5pg,
|
||||
uint64_t entry_point, void *stivale_struct, uint64_t stack) {
|
||||
if (bits == 64) {
|
||||
// If we're going 64, we might as well call this BIOS interrupt
|
||||
// to tell the BIOS that we are entering Long Mode, since it is in
|
||||
@ -256,7 +262,7 @@ void stivale_load(char *cmdline, int boot_drive) {
|
||||
|
||||
if (bits == 64) {
|
||||
void *pagemap_ptr;
|
||||
if (level5pg && (stivale_hdr.flags & (1 << 1))) {
|
||||
if (level5pg) {
|
||||
// Enable CR4.LA57
|
||||
ASM(
|
||||
"mov eax, cr4\n\t"
|
||||
@ -376,7 +382,7 @@ void stivale_load(char *cmdline, int boot_drive) {
|
||||
"iretq\n\t"
|
||||
".code32\n\t",
|
||||
: "a" (pagemap_ptr), "b" (&entry_point),
|
||||
"D" (&stivale_struct), "S" (&stivale_hdr.stack)
|
||||
"D" (stivale_struct), "S" (&stack)
|
||||
: "memory"
|
||||
);
|
||||
} else if (bits == 32) {
|
||||
@ -402,8 +408,9 @@ void stivale_load(char *cmdline, int boot_drive) {
|
||||
"xor ebp, ebp\n\t"
|
||||
|
||||
"iret\n\t",
|
||||
: "b" (&entry_point), "D" (&stivale_struct), "S" (&stivale_hdr.stack)
|
||||
: "b" (&entry_point), "D" (stivale_struct), "S" (&stack)
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
for (;;);
|
||||
}
|
||||
|
@ -1,8 +1,11 @@
|
||||
#ifndef __PROTOS__STIVALE_H__
|
||||
#define __PROTOS__STIVALE_H__
|
||||
|
||||
#include <fs/file.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void stivale_load(char *cmdline, int boot_drive);
|
||||
__attribute__((noreturn)) void stivale_spinup(int bits, bool level5pg,
|
||||
uint64_t entry_point, void *stivale_struct, uint64_t stack);
|
||||
|
||||
#endif
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <limine.h>
|
||||
#include <protos/stivale.h>
|
||||
#include <protos/stivale2.h>
|
||||
#include <lib/elf.h>
|
||||
#include <lib/blib.h>
|
||||
@ -14,7 +15,7 @@
|
||||
#include <lib/real.h>
|
||||
#include <lib/libc.h>
|
||||
#include <drivers/vbe.h>
|
||||
#include <drivers/vga_textmode.h>
|
||||
#include <lib/term.h>
|
||||
#include <drivers/pic.h>
|
||||
#include <fs/file.h>
|
||||
#include <lib/asm.h>
|
||||
@ -364,9 +365,9 @@ void stivale2_load(char *cmdline, int boot_drive) {
|
||||
{
|
||||
struct stivale2_hdr_tag_framebuffer *hdrtag = get_tag(&stivale2_hdr, STIVALE2_HDR_TAG_FRAMEBUFFER_ID);
|
||||
|
||||
if (hdrtag == NULL) {
|
||||
deinit_vga_textmode();
|
||||
} else {
|
||||
term_deinit();
|
||||
|
||||
if (hdrtag != NULL) {
|
||||
struct stivale2_struct_tag_framebuffer *tag = balloc(sizeof(struct stivale2_struct_tag_framebuffer));
|
||||
tag->tag.identifier = STIVALE2_STRUCT_TAG_FRAMEBUFFER_ID;
|
||||
|
||||
@ -407,169 +408,6 @@ void stivale2_load(char *cmdline, int boot_drive) {
|
||||
// Check if 5-level paging tag is requesting support
|
||||
bool level5pg_requested = get_tag(&stivale2_hdr, STIVALE2_HDR_TAG_5LV_PAGING_ID) ? true : false;
|
||||
|
||||
if (bits == 64) {
|
||||
// If we're going 64, we might as well call this BIOS interrupt
|
||||
// to tell the BIOS that we are entering Long Mode, since it is in
|
||||
// the specification.
|
||||
struct rm_regs r = {0};
|
||||
r.eax = 0xec00;
|
||||
r.ebx = 0x02; // Long mode only
|
||||
rm_int(0x15, &r, &r);
|
||||
}
|
||||
|
||||
pic_mask_all();
|
||||
pic_flush();
|
||||
|
||||
if (bits == 64) {
|
||||
void *pagemap_ptr;
|
||||
if (level5pg && level5pg_requested) {
|
||||
// Enable CR4.LA57
|
||||
ASM(
|
||||
"mov eax, cr4\n\t"
|
||||
"bts eax, 12\n\t"
|
||||
"mov cr4, eax\n\t", :: "eax", "memory"
|
||||
);
|
||||
|
||||
struct pagemap {
|
||||
uint64_t pml5[512];
|
||||
uint64_t pml4_lo[512];
|
||||
uint64_t pml4_hi[512];
|
||||
uint64_t pml3_lo[512];
|
||||
uint64_t pml3_hi[512];
|
||||
uint64_t pml2_0gb[512];
|
||||
uint64_t pml2_1gb[512];
|
||||
uint64_t pml2_2gb[512];
|
||||
uint64_t pml2_3gb[512];
|
||||
};
|
||||
struct pagemap *pagemap = balloc_aligned(sizeof(struct pagemap), 0x1000);
|
||||
pagemap_ptr = (void *)pagemap;
|
||||
|
||||
// zero out the pagemap
|
||||
for (uint64_t *p = (uint64_t *)pagemap; p < &pagemap->pml3_hi[512]; p++)
|
||||
*p = 0;
|
||||
|
||||
pagemap->pml5[511] = (uint64_t)(size_t)pagemap->pml4_hi | 0x03;
|
||||
pagemap->pml5[0] = (uint64_t)(size_t)pagemap->pml4_lo | 0x03;
|
||||
pagemap->pml4_hi[511] = (uint64_t)(size_t)pagemap->pml3_hi | 0x03;
|
||||
pagemap->pml4_hi[256] = (uint64_t)(size_t)pagemap->pml3_lo | 0x03;
|
||||
pagemap->pml4_lo[0] = (uint64_t)(size_t)pagemap->pml3_lo | 0x03;
|
||||
pagemap->pml3_hi[510] = (uint64_t)(size_t)pagemap->pml2_0gb | 0x03;
|
||||
pagemap->pml3_hi[511] = (uint64_t)(size_t)pagemap->pml2_1gb | 0x03;
|
||||
pagemap->pml3_lo[0] = (uint64_t)(size_t)pagemap->pml2_0gb | 0x03;
|
||||
pagemap->pml3_lo[1] = (uint64_t)(size_t)pagemap->pml2_1gb | 0x03;
|
||||
pagemap->pml3_lo[2] = (uint64_t)(size_t)pagemap->pml2_2gb | 0x03;
|
||||
pagemap->pml3_lo[3] = (uint64_t)(size_t)pagemap->pml2_3gb | 0x03;
|
||||
|
||||
// populate the page directories
|
||||
for (size_t i = 0; i < 512 * 4; i++)
|
||||
(&pagemap->pml2_0gb[0])[i] = (i * 0x200000) | 0x03 | (1 << 7);
|
||||
} else {
|
||||
struct pagemap {
|
||||
uint64_t pml4[512];
|
||||
uint64_t pml3_lo[512];
|
||||
uint64_t pml3_hi[512];
|
||||
uint64_t pml2_0gb[512];
|
||||
uint64_t pml2_1gb[512];
|
||||
uint64_t pml2_2gb[512];
|
||||
uint64_t pml2_3gb[512];
|
||||
};
|
||||
struct pagemap *pagemap = balloc_aligned(sizeof(struct pagemap), 0x1000);
|
||||
pagemap_ptr = (void *)pagemap;
|
||||
|
||||
// zero out the pagemap
|
||||
for (uint64_t *p = (uint64_t *)pagemap; p < &pagemap->pml3_hi[512]; p++)
|
||||
*p = 0;
|
||||
|
||||
pagemap->pml4[511] = (uint64_t)(size_t)pagemap->pml3_hi | 0x03;
|
||||
pagemap->pml4[256] = (uint64_t)(size_t)pagemap->pml3_lo | 0x03;
|
||||
pagemap->pml4[0] = (uint64_t)(size_t)pagemap->pml3_lo | 0x03;
|
||||
pagemap->pml3_hi[510] = (uint64_t)(size_t)pagemap->pml2_0gb | 0x03;
|
||||
pagemap->pml3_hi[511] = (uint64_t)(size_t)pagemap->pml2_1gb | 0x03;
|
||||
pagemap->pml3_lo[0] = (uint64_t)(size_t)pagemap->pml2_0gb | 0x03;
|
||||
pagemap->pml3_lo[1] = (uint64_t)(size_t)pagemap->pml2_1gb | 0x03;
|
||||
pagemap->pml3_lo[2] = (uint64_t)(size_t)pagemap->pml2_2gb | 0x03;
|
||||
pagemap->pml3_lo[3] = (uint64_t)(size_t)pagemap->pml2_3gb | 0x03;
|
||||
|
||||
// populate the page directories
|
||||
for (size_t i = 0; i < 512 * 4; i++)
|
||||
(&pagemap->pml2_0gb[0])[i] = (i * 0x200000) | 0x03 | (1 << 7);
|
||||
}
|
||||
|
||||
ASM(
|
||||
"cli\n\t"
|
||||
"cld\n\t"
|
||||
"mov cr3, eax\n\t"
|
||||
"mov eax, cr4\n\t"
|
||||
"or eax, 1 << 5\n\t"
|
||||
"mov cr4, eax\n\t"
|
||||
"mov ecx, 0xc0000080\n\t"
|
||||
"rdmsr\n\t"
|
||||
"or eax, 1 << 8\n\t"
|
||||
"wrmsr\n\t"
|
||||
"mov eax, cr0\n\t"
|
||||
"or eax, 1 << 31\n\t"
|
||||
"mov cr0, eax\n\t"
|
||||
FARJMP32("0x28", "1f")
|
||||
"1: .code64\n\t"
|
||||
"mov ax, 0x30\n\t"
|
||||
"mov ds, ax\n\t"
|
||||
"mov es, ax\n\t"
|
||||
"mov fs, ax\n\t"
|
||||
"mov gs, ax\n\t"
|
||||
"mov ss, ax\n\t"
|
||||
|
||||
"push 0x30\n\t"
|
||||
"push [rsi]\n\t"
|
||||
"pushfq\n\t"
|
||||
"push 0x28\n\t"
|
||||
"push [rbx]\n\t"
|
||||
|
||||
"xor rax, rax\n\t"
|
||||
"xor rbx, rbx\n\t"
|
||||
"xor rcx, rcx\n\t"
|
||||
"xor rdx, rdx\n\t"
|
||||
"xor rsi, rsi\n\t"
|
||||
"xor rbp, rbp\n\t"
|
||||
"xor r8, r8\n\t"
|
||||
"xor r9, r9\n\t"
|
||||
"xor r10, r10\n\t"
|
||||
"xor r11, r11\n\t"
|
||||
"xor r12, r12\n\t"
|
||||
"xor r13, r13\n\t"
|
||||
"xor r14, r14\n\t"
|
||||
"xor r15, r15\n\t"
|
||||
|
||||
"iretq\n\t"
|
||||
".code32\n\t",
|
||||
: "a" (pagemap_ptr), "b" (&entry_point),
|
||||
"D" (&stivale2_struct), "S" (&stivale2_hdr.stack)
|
||||
: "memory"
|
||||
);
|
||||
} else if (bits == 32) {
|
||||
ASM(
|
||||
"cli\n\t"
|
||||
"cld\n\t"
|
||||
|
||||
"sub esp, 4\n\t"
|
||||
"mov [esp], edi\n\t"
|
||||
|
||||
"push 0x20\n\t"
|
||||
"push [esi]\n\t"
|
||||
"pushfd\n\t"
|
||||
"push 0x18\n\t"
|
||||
"push [ebx]\n\t"
|
||||
|
||||
"xor eax, eax\n\t"
|
||||
"xor ebx, ebx\n\t"
|
||||
"xor ecx, ecx\n\t"
|
||||
"xor edx, edx\n\t"
|
||||
"xor esi, esi\n\t"
|
||||
"xor edi, edi\n\t"
|
||||
"xor ebp, ebp\n\t"
|
||||
|
||||
"iret\n\t",
|
||||
: "b" (&entry_point), "D" (&stivale2_struct), "S" (&stivale2_hdr.stack)
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
stivale_spinup(bits, level5pg && level5pg_requested,
|
||||
entry_point, &stivale2_struct, stivale2_hdr.stack);
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
TIMEOUT=3
|
||||
GRAPHICS=on
|
||||
|
||||
:MyOS
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user