console changes

Signed-off-by: kaguya3311 <kaguya3311@national.shitposting.agency>
This commit is contained in:
kaguya
2026-05-18 05:40:43 -04:00
parent e9e750bd74
commit 19521c6ab4
5 changed files with 148 additions and 3 deletions
+1
View File
@@ -7,3 +7,4 @@ void serial_putchar(char ch);
void serial_puts(char *str); void serial_puts(char *str);
char serial_get_byte(void); char serial_get_byte(void);
char serial_getchar(void); char serial_getchar(void);
int serial_received(void);
+132 -1
View File
@@ -9,6 +9,8 @@
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <stdbool.h> #include <stdbool.h>
#include "arch/x86_64/serial/serial.h"
#include "sched/sched.h"
struct console { struct console {
struct resource res; struct resource res;
@@ -19,6 +21,11 @@ struct console {
struct console *console_device = NULL; struct console *console_device = NULL;
static void console_emit(char c) {
framebuffer_putchar(c);
serial_putchar(c);
}
static ssize_t console_write(struct resource *this, static ssize_t console_write(struct resource *this,
struct f_description *description, const void *buf, struct f_description *description, const void *buf,
off_t offset, size_t count) { off_t offset, size_t count) {
@@ -34,13 +41,114 @@ static ssize_t console_write(struct resource *this,
char *r = (char *)buf; char *r = (char *)buf;
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
framebuffer_putchar(r[i]); console_emit(r[i]);
} }
spinlock_drop(&this->lock); spinlock_drop(&this->lock);
return count; return count;
} }
static ssize_t console_read(struct resource *this,
struct f_description *description, void *buf,
off_t offset, size_t count) {
(void)this;
(void)description;
(void)offset;
if (!buf) {
errno = EFAULT;
return -1;
}
if (count == 0) {
return 0;
}
char *out = (char *)buf;
size_t pos = 0;
tcflag_t lflag = console_device->term.c_lflag;
tcflag_t iflag = console_device->term.c_iflag;
bool canon = (lflag & ICANON) != 0;
bool echo = (lflag & ECHO) != 0;
bool echoe = (lflag & ECHOE) != 0;
cc_t verase = console_device->term.c_cc[VERASE];
if (verase == 0) {
verase = 0x7f;
}
cc_t veof = console_device->term.c_cc[VEOF];
while (pos < count) {
while (!serial_received()) {
sched_yield(true);
}
char c = serial_get_byte();
// Input mode flags
if ((iflag & ISTRIP) != 0) {
c = (char)((unsigned char)c & 0x7f);
}
if ((iflag & IGNCR) != 0 && c == '\r') {
continue;
}
if ((iflag & ICRNL) != 0 && c == '\r') {
c = '\n';
} else if ((iflag & INLCR) != 0 && c == '\n') {
c = '\r';
}
if (canon) {
// Backspace / VERASE handling
if (c == (char)verase || c == 0x08) {
if (pos > 0) {
pos--;
if (echo && echoe) {
console_emit('\b');
console_emit(' ');
console_emit('\b');
}
}
continue;
}
// EOF: return what we have so far (possibly 0)
if (veof != 0 && c == (char)veof) {
break;
}
out[pos++] = c;
if (echo) {
if (c == '\n') {
console_emit('\n');
} else if ((unsigned char)c < 0x20 && c != '\t' &&
(lflag & ECHOCTL) != 0) {
console_emit('^');
console_emit((char)(c + 0x40));
} else {
console_emit(c);
}
} else if (c == '\n' && (lflag & ECHONL) != 0) {
console_emit('\n');
}
if (c == '\n') {
break;
}
} else {
// Non-canonical (raw) mode: return as soon as we have any data.
out[pos++] = c;
if (echo) {
console_emit(c);
}
break;
}
}
return (ssize_t)pos;
}
int console_ioctl(struct resource *this, struct f_description *description, int console_ioctl(struct resource *this, struct f_description *description,
uint64_t request, uint64_t arg) { uint64_t request, uint64_t arg) {
(void)description; (void)description;
@@ -76,6 +184,27 @@ int console_ioctl(struct resource *this, struct f_description *description,
} }
break; break;
} }
case TIOCSWINSZ:
// Accept but ignore: the console window size is fixed by the fb.
break;
case TIOCSCTTY:
// Becoming the controlling tty is a no-op; there's only one console
// and any process opening it is implicitly attached.
break;
case TIOCGPGRP:
case TIOCGSID: {
int *n = (int *)arg;
if (n) {
*n = sched_get_running_thread()->mother_proc->pid;
} else {
errno = EINVAL;
ret = -1;
}
break;
}
case TIOCSPGRP:
// Accept but ignore: no foreground-pgrp tracking yet.
break;
default: default:
errno = EINVAL; errno = EINVAL;
ret = -1; ret = -1;
@@ -141,12 +270,14 @@ void console_init(void) {
console_device->res.status |= POLLOUT; console_device->res.status |= POLLOUT;
console_device->res.read = console_read;
console_device->res.write = console_write; console_device->res.write = console_write;
console_device->res.ioctl = console_ioctl; console_device->res.ioctl = console_ioctl;
console_device->decckm = false; console_device->decckm = false;
devtmpfs_add_device((struct resource *)console_device, "console"); devtmpfs_add_device((struct resource *)console_device, "console");
devtmpfs_add_device((struct resource *)console_device, "tty");
kprintffos(false, "Bye bye!\n"); kprintffos(false, "Bye bye!\n");
framebuffer_clear(0x00eee8d5, 0); framebuffer_clear(0x00eee8d5, 0);
+11
View File
@@ -406,6 +406,9 @@ bool elf_load(struct pagemap *pagemap, struct resource *res, uint64_t load_base,
return false; return false;
} }
auxv->at_phdr = 0;
bool phdr_set = false;
for (size_t i = 0; i < header.e_phnum; i++) { for (size_t i = 0; i < header.e_phnum; i++) {
Elf64_Phdr phdr; Elf64_Phdr phdr;
if (res->read(res, NULL, &phdr, header.e_phoff + i * header.e_phentsize, if (res->read(res, NULL, &phdr, header.e_phoff + i * header.e_phentsize,
@@ -446,10 +449,18 @@ bool elf_load(struct pagemap *pagemap, struct resource *res, uint64_t load_base,
goto fail; goto fail;
} }
// Fallback when no PT_PHDR: if this LOAD segment covers the
// program header table, derive at_phdr from it.
if (!phdr_set && header.e_phoff >= phdr.p_offset &&
header.e_phoff < phdr.p_offset + phdr.p_filesz) {
auxv->at_phdr = phdr.p_vaddr + (header.e_phoff - phdr.p_offset) + load_base;
}
break; break;
} }
case PT_PHDR: case PT_PHDR:
auxv->at_phdr = phdr.p_vaddr + load_base; auxv->at_phdr = phdr.p_vaddr + load_base;
phdr_set = true;
break; break;
case PT_INTERP: { case PT_INTERP: {
void *path = kmalloc(phdr.p_filesz + 1); void *path = kmalloc(phdr.p_filesz + 1);
+2 -1
View File
@@ -12,6 +12,7 @@
#include "fs/elf.h" #include "fs/elf.h"
#include "sched/sched_types.h" #include "sched/sched_types.h"
#include "kargs.h" #include "kargs.h"
#include "arch/x86_64/serial/serial.h"
#if PRINTF_ALIAS_STANDARD_FUNCTION_NAMES_HARD #if PRINTF_ALIAS_STANDARD_FUNCTION_NAMES_HARD
# define printf_ printf # define printf_ printf
@@ -650,7 +651,7 @@ bool print_now = false;
void kputchar(char c) { void kputchar(char c) {
if (c == '\n') if (c == '\n')
kputchar('\r'); kputchar('\r');
//kputchar_(c); kputchar_(c);
if (put_to_fb) if (put_to_fb)
framebuffer_putchar(c); framebuffer_putchar(c);
+1
View File
@@ -133,6 +133,7 @@ void debug_hex_dump(const void *data, size_t size);
#define log_err(module, ...) logf(module, LVL_ERROR, __VA_ARGS__) #define log_err(module, ...) logf(module, LVL_ERROR, __VA_ARGS__)
#define log_crit(module, ...) logf(module, LVL_CRITICAL, __VA_ARGS__) #define log_crit(module, ...) logf(module, LVL_CRITICAL, __VA_ARGS__)
#define kprintf(...) kprintffos(put_to_fb, __VA_ARGS__) #define kprintf(...) kprintffos(put_to_fb, __VA_ARGS__)
#define kputchar_ serial_putchar
#define putchar_ kputchar #define putchar_ kputchar