boot: add command line editor
This commit is contained in:
parent
61b7444192
commit
079db87617
@ -48,7 +48,7 @@ int kmain() {
|
||||
"Enable debug output in the bootloader and enable the",
|
||||
"serial debug log in the operating system itself.");
|
||||
|
||||
BOOT_OPTION(_nosmp, 0, "Disable SMP",
|
||||
BOOT_OPTION(_smp, 1, "Enable SMP",
|
||||
"SMP support may not be completely stable and can be",
|
||||
"disabled with this option if desired.");
|
||||
|
||||
@ -76,6 +76,10 @@ int kmain() {
|
||||
"Migrates the ramdisk from tarball to an in-memory",
|
||||
"temporary filesystem at boot. Needed for packages.");
|
||||
|
||||
BOOT_OPTION(_qemubug, 0, "QEMU PS/2 workaround",
|
||||
"Work around a bug in QEMU's PS/2 controller",
|
||||
"prior to 6.0.50.");
|
||||
|
||||
/* Loop over rendering the menu */
|
||||
show_menu();
|
||||
|
||||
@ -120,10 +124,18 @@ int kmain() {
|
||||
strcat(cmdline, "novmwareresset ");
|
||||
}
|
||||
|
||||
if (_nosmp) {
|
||||
if (!_smp) {
|
||||
strcat(cmdline, "nosmp ");
|
||||
}
|
||||
|
||||
if (_qemubug) {
|
||||
strcat(cmdline, "sharedps2 ");
|
||||
}
|
||||
|
||||
if (boot_edit) {
|
||||
boot_editor();
|
||||
}
|
||||
|
||||
boot();
|
||||
|
||||
while (1) {}
|
||||
|
68
boot/editor.c
Normal file
68
boot/editor.c
Normal file
@ -0,0 +1,68 @@
|
||||
#include <stdint.h>
|
||||
#include "options.h"
|
||||
#include "text.h"
|
||||
#include "util.h"
|
||||
|
||||
extern int read_key(char * c);
|
||||
|
||||
void boot_editor(void) {
|
||||
|
||||
int len = strlen(cmdline);
|
||||
int cursor = len;
|
||||
|
||||
while (1) {
|
||||
move_cursor(0,0);
|
||||
for (int i = 0; i <= len; ++i) {
|
||||
set_attr(i == cursor ? 0x70 : 0x07);
|
||||
print_((char[]){cmdline[i],'\0'});
|
||||
}
|
||||
print_(" ");
|
||||
set_attr(0x07);
|
||||
do {
|
||||
do {
|
||||
print_(" ");
|
||||
} while (x);
|
||||
} while (y);
|
||||
|
||||
char data = 0;
|
||||
int status = read_key(&data);
|
||||
|
||||
if (status == 0) {
|
||||
/* Handle a few special characters */
|
||||
if (data == '\n') {
|
||||
return;
|
||||
} else if (data == '\b') {
|
||||
if (!cursor) continue;
|
||||
if (cursor == len) {
|
||||
cmdline[len-1] = '\0';
|
||||
cursor--;
|
||||
len--;
|
||||
} else {
|
||||
cmdline[cursor-1] = '\0';
|
||||
strcat(cmdline,&cmdline[cursor]);
|
||||
cursor--;
|
||||
len--;
|
||||
}
|
||||
} else {
|
||||
if (len > 1022) continue;
|
||||
/* Move everything from the cursor onward forward */
|
||||
if (cursor < len) {
|
||||
int x = len + 1;
|
||||
while (x > cursor) {
|
||||
cmdline[x] = cmdline[x-1];
|
||||
x--;
|
||||
}
|
||||
}
|
||||
cmdline[cursor] = data;
|
||||
len++;
|
||||
cursor++;
|
||||
}
|
||||
} else if (status == 2) {
|
||||
/* Left */
|
||||
if (cursor) cursor--;
|
||||
} else if (status == 3) {
|
||||
if (cursor < len) cursor++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
48
boot/kbd.c
48
boot/kbd.c
@ -6,6 +6,54 @@ int read_cmos_seconds(void) {
|
||||
return inportb(0x71);
|
||||
}
|
||||
|
||||
static char kbd_us[128] = {
|
||||
0, 27, '1','2','3','4','5','6','7','8','9','0',
|
||||
'-','=','\b', '\t', 'q','w','e','r','t','y','u','i','o','p','[',']','\n',
|
||||
0, 'a','s','d','f','g','h','j','k','l',';','\'', '`',
|
||||
0, '\\','z','x','c','v','b','n','m',',','.','/',
|
||||
0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
'-', 0, 0, 0, '+', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
static char kbd_us_l2[128] = {
|
||||
0, 27, '!','@','#','$','%','^','&','*','(',')',
|
||||
'_','+','\b', '\t', 'Q','W','E','R','T','Y','U','I','O','P','{','}','\n',
|
||||
0, 'A','S','D','F','G','H','J','K','L',':','"', '~',
|
||||
0, '|','Z','X','C','V','B','N','M','<','>','?',
|
||||
0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
'-', 0, 0, 0, '+', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
int read_key(char * c) {
|
||||
static int shift_state = 0;
|
||||
|
||||
int sc = read_scancode(0);
|
||||
|
||||
switch (sc) {
|
||||
/* Shift down */
|
||||
case 0x2A:
|
||||
case 0x36:
|
||||
shift_state = 1;
|
||||
return 1;
|
||||
/* Shift up */
|
||||
case 0xAA:
|
||||
case 0xB6:
|
||||
shift_state = 0;
|
||||
return 1;
|
||||
|
||||
/* Keft left and right */
|
||||
case 0x4B: return 2;
|
||||
case 0x4D: return 3;
|
||||
}
|
||||
|
||||
if (!(sc & 0x80)) {
|
||||
*c = shift_state ? kbd_us_l2[sc] : kbd_us[sc];
|
||||
return *c == 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int read_scancode(int timeout) {
|
||||
if (timeout) {
|
||||
int start_s = read_cmos_seconds();
|
||||
|
@ -9,6 +9,7 @@ struct option boot_options[20] = {{0}};
|
||||
int sel_max = 0;
|
||||
int sel = 0;
|
||||
int boot_mode = 0;
|
||||
int boot_edit = 0;
|
||||
|
||||
void toggle(int ndx, int value, char *str) {
|
||||
set_attr(sel == ndx ? 0x70 : 0x07);
|
||||
@ -80,7 +81,7 @@ void show_menu(void) {
|
||||
}
|
||||
|
||||
set_attr(0x07);
|
||||
move_cursor(x,15);
|
||||
move_cursor(0,15);
|
||||
if (timeout) {
|
||||
*timeout_val = timeout + '0';
|
||||
print_banner(timeout_msg);
|
||||
@ -148,6 +149,12 @@ void show_menu(void) {
|
||||
int index = sel - base_sel - 1;
|
||||
*boot_options[index].value = !*boot_options[index].value;
|
||||
}
|
||||
} else if (s == 0x12) { /* e */
|
||||
if (sel <= base_sel) {
|
||||
boot_edit = 1;
|
||||
boot_mode = boot_mode_names[sel].index;
|
||||
break;
|
||||
}
|
||||
} else if (s >= 2 && s <= 10) {
|
||||
int i = s - 2;
|
||||
if (i <= base_sel) {
|
||||
|
@ -1,4 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
extern int boot_mode;
|
||||
extern int boot_edit;
|
||||
void show_menu(void);
|
||||
void boot_editor(void);
|
||||
|
@ -31,6 +31,15 @@ char * strchr(const char * s, int c) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long strlen(const char *s) {
|
||||
unsigned long out = 0;
|
||||
while (*s) {
|
||||
out++;
|
||||
s++;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
char * strcat(char *dest, const char *src) {
|
||||
char * end = dest;
|
||||
while (*end != '\0') {
|
||||
|
@ -41,5 +41,6 @@ char * strchr(const char * s, int c);
|
||||
char * strcat(char *dest, const char *src);
|
||||
void copy_sectors(unsigned long lba, unsigned char * buf, int sectors);
|
||||
void copy_sector(unsigned long lba, unsigned char * buf);
|
||||
unsigned long strlen(const char *s);
|
||||
|
||||
#define DATA_LOAD_BASE 0x4000000
|
||||
|
Loading…
x
Reference in New Issue
Block a user