mirror of
https://github.com/Plexi09/Nadir-Kernel.git
synced 2026-10-20 15:07:27 +02:00
fix: backspace behavior
This commit is contained in:
parent
a60338054a
commit
0727a2c1d4
1 changed files with 131 additions and 4 deletions
|
|
@ -2,30 +2,157 @@
|
||||||
*
|
*
|
||||||
* Called once from the stage-2 entry stub after the CPU is in 64-bit long
|
* Called once from the stage-2 entry stub after the CPU is in 64-bit long
|
||||||
* mode with a valid stack, zeroed BSS and identity-mapped memory. Runs at
|
* mode with a valid stack, zeroed BSS and identity-mapped memory. Runs at
|
||||||
* Ring 0 (CPL 0) interrupts disabled. Installs the exception IDT first
|
* Ring 0 (CPL 0) with IF=0 on entry under the stage-2 GDT (CS 0x18);
|
||||||
* so from then on a fault prints diagnostics instead of triple-faulting.
|
* `-mno-red-zone` keeps IRQ pushes off the red zone so interrupt frames
|
||||||
* It never returns; on return the caller halts the CPU.
|
* are safe. Installs the exception IDT first so from then on a fault
|
||||||
|
* prints diagnostics instead of triple-faulting. `sti` runs exactly once
|
||||||
|
* after every device is programmed; the main loop keeps IF=1 and sleeps
|
||||||
|
* in `hlt` (which wakes on each IRQ) — never `cli`-parks, or timer ticks
|
||||||
|
* and keystrokes would stop. It never returns; on return the caller halts.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "idt.h"
|
#include "idt.h"
|
||||||
|
#include "keyboard.h"
|
||||||
|
#include "pic.h"
|
||||||
|
#include "pit.h"
|
||||||
|
#include "serial.h"
|
||||||
|
|
||||||
/* A value that only comes out right if the CPU truly executes 64-bit
|
/* A value that only comes out right if the CPU truly executes 64-bit
|
||||||
* arithmetic: every nibble survives the shifts above 32 bits. */
|
* arithmetic: every nibble survives the shifts above 32 bits. */
|
||||||
#define PROOF_VALUE 0x0123456789ABCDEFULL
|
#define PROOF_VALUE 0x0123456789ABCDEFULL
|
||||||
|
|
||||||
|
/* Print an unsigned decimal via console_putchar (no libc printf). */
|
||||||
|
static void print_dec(uint64_t v)
|
||||||
|
{
|
||||||
|
char buf[20];
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
if (v == 0) {
|
||||||
|
console_putchar('0');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (v != 0 && n < (int)sizeof(buf)) {
|
||||||
|
buf[n++] = (char)('0' + (v % 10U));
|
||||||
|
v /= 10U;
|
||||||
|
}
|
||||||
|
while (n > 0) {
|
||||||
|
n--;
|
||||||
|
console_putchar(buf[n]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mirror one echoed keystroke to COM1 when the UART looks present. */
|
||||||
|
static void serial_echo(char c, int ok)
|
||||||
|
{
|
||||||
|
char tmp[2];
|
||||||
|
|
||||||
|
if (ok == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (c == '\b') {
|
||||||
|
/* Erase on a serial terminal: back, blank, back. */
|
||||||
|
serial_puts("\b \b");
|
||||||
|
} else if (c == '\n') {
|
||||||
|
serial_puts("\r\n");
|
||||||
|
} else {
|
||||||
|
tmp[0] = c;
|
||||||
|
tmp[1] = '\0';
|
||||||
|
serial_puts(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void kmain(void)
|
void kmain(void)
|
||||||
{
|
{
|
||||||
|
int serial_present;
|
||||||
|
uint64_t last_uptime;
|
||||||
|
|
||||||
console_clear();
|
console_clear();
|
||||||
console_puts("Hello World from Nadir Kernel !\n");
|
console_puts("Hello World from Nadir Kernel !\n");
|
||||||
console_puts("Running C code in 64-bit long mode (Ring 0).\n");
|
console_puts("Running C code in 64-bit long mode (Ring 0).\n");
|
||||||
|
|
||||||
|
/* WHY this order: pic_remap must precede idt_install_irqs so IRQ
|
||||||
|
* gates land on valid remapped vectors 32-47 (pre-remap they would
|
||||||
|
* overlap CPU exceptions 0-15 and a tick would look like a fault);
|
||||||
|
* devices (serial/PIT/keyboard) are programmed before sti so no IRQ
|
||||||
|
* fires into a half-wired handler; pic_remap masks everything and
|
||||||
|
* each device opts in via pic_unmask, so stray lines stay silent. */
|
||||||
idt_init();
|
idt_init();
|
||||||
console_puts("IDT installed (vectors 0-31).\n");
|
console_puts("IDT installed (vectors 0-31).\n");
|
||||||
|
|
||||||
|
pic_remap();
|
||||||
|
console_puts("PIC remapped (IRQ 0-15 -> vectors 32-47, masked).\n");
|
||||||
|
|
||||||
|
idt_install_irqs();
|
||||||
|
console_puts("IRQ gates installed (vectors 32-47).\n");
|
||||||
|
|
||||||
|
serial_init();
|
||||||
|
serial_present = serial_ok();
|
||||||
|
console_puts("Serial COM1 38400 8N1 ready.\n");
|
||||||
|
if (serial_present != 0) {
|
||||||
|
serial_puts("Hello World from Nadir Kernel !\n");
|
||||||
|
serial_puts("Serial COM1 38400 8N1 ready.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
pit_init();
|
||||||
|
console_puts("PIT 100Hz on IRQ0 ready.\n");
|
||||||
|
if (serial_present != 0) {
|
||||||
|
serial_puts("PIT 100Hz on IRQ0 ready.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
keyboard_init();
|
||||||
|
console_puts("Keyboard PS/2 IRQ1 ready.\n");
|
||||||
|
if (serial_present != 0) {
|
||||||
|
serial_puts("Keyboard PS/2 IRQ1 ready.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Explicit opt-in for the two live lines; idempotent even though
|
||||||
|
* keyboard_init already unmasked IRQ1. */
|
||||||
|
pic_unmask(0);
|
||||||
|
pic_unmask(1);
|
||||||
|
|
||||||
|
__asm__ volatile("sti");
|
||||||
|
console_puts("Interrupts enabled (IRQs 0-1).\n");
|
||||||
|
if (serial_present != 0) {
|
||||||
|
serial_puts("Interrupts enabled (IRQs 0-1).\n");
|
||||||
|
}
|
||||||
|
|
||||||
console_puts("64-bit proof value: ");
|
console_puts("64-bit proof value: ");
|
||||||
console_puthex64(PROOF_VALUE);
|
console_puthex64(PROOF_VALUE);
|
||||||
console_puts("\nHalting.\n");
|
console_puts("\nHalting in hlt loop (timer + keyboard live).\n");
|
||||||
|
|
||||||
|
/* Main loop: hlt sleeps until the next IRQ (IF=1 throughout), then
|
||||||
|
* one poll pass prints uptime ~1/s and drains echoed keys. */
|
||||||
|
last_uptime = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
uint64_t now;
|
||||||
|
|
||||||
__asm__ volatile("hlt");
|
__asm__ volatile("hlt");
|
||||||
|
now = pit_ticks();
|
||||||
|
if ((now - last_uptime) >= 100U) {
|
||||||
|
uint64_t secs = now / 100U;
|
||||||
|
uint64_t tenths = (now / 10U) % 10U;
|
||||||
|
|
||||||
|
last_uptime = now;
|
||||||
|
console_puts("uptime ");
|
||||||
|
print_dec(secs);
|
||||||
|
console_puts(".");
|
||||||
|
print_dec(tenths);
|
||||||
|
console_puts("s (ticks ");
|
||||||
|
console_puthex64(now);
|
||||||
|
console_puts(")\n");
|
||||||
|
if (serial_present != 0) {
|
||||||
|
serial_puts("uptime (see VGA for value)\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (keyboard_has_key() != 0) {
|
||||||
|
char c = keyboard_dequeue();
|
||||||
|
|
||||||
|
/* console_putchar erases on '\b' and wraps on '\n'. */
|
||||||
|
console_putchar(c);
|
||||||
|
serial_echo(c, serial_present);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue