From dcb609894339d82c9129a81c30a35ddbb4de71f4 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Fri, 6 Oct 2023 04:53:55 +0300 Subject: [PATCH] progress on all fronts --- Makefile | 4 ++-- com32.ld | 10 +++++++++- src/asmops.h | 4 ++++ src/config.h | 2 +- src/contty.c | 14 +++++++++++++- src/intr.c | 1 - src/kbscan.h | 4 ++++ src/keyb.c | 26 ++++++++++++++++++++++++-- src/libc/stdio.c | 2 ++ src/libc/string.c | 3 ++- src/loader.asm | 50 ++++++++++++++++++++++++++------------------------ src/macros.inc | 2 +- src/main.c | 2 -- src/panic.c | 16 ++++++++++++++++ src/panic.h | 1 + src/segm.c | 6 +++--- src/serial.c | 44 +++++++++++++++++++++++++++----------------- src/startup.asm | 2 +- 18 files changed, 136 insertions(+), 57 deletions(-) diff --git a/Makefile b/Makefile index 68742d5..1226610 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ AS = nasm ASFLAGS = -Isrc/ CFLAGS = -m32 -march=i386 $(warn) $(opt) $(dbg) -fno-pic -ffreestanding \ -fno-stack-protector -mpreferred-stack-boundary=2 -nostdinc -ffast-math \ - $(inc) $(def) + -fno-asynchronous-unwind-tables $(inc) $(def) -MMD LDFLAGS = -m elf_i386 -nostdlib -T com32.ld -Map test.map $(bin): $(obj) @@ -24,7 +24,7 @@ $(bin): $(obj) $(AS) -o $@ -f elf $(ASFLAGS) $< %.s: %.c - $(CC) $(CFLAGS) -masm=intel -g0 -fno-asynchronous-unwind-tables -S $< -o $@ + $(CC) $(CFLAGS) -masm=intel -S $< -o $@ .PHONY: clean clean: diff --git a/com32.ld b/com32.ld index 701a0b4..213b4e2 100644 --- a/com32.ld +++ b/com32.ld @@ -12,13 +12,16 @@ SECTIONS { /* main program will be moved to 2MB by the loader */ . = 2M; - main ALIGN(4): AT (_ldr_main_start) { + .main ALIGN(4): AT (_ldr_main_start) { _main_start = .; * (.startup); * (.text*); * (.rodata*); * (.data*); + . = ALIGN(4); + } + .bss ALIGN(4): AT (_ldr_main_start + SIZEOF(.main)) { . = ALIGN(4); _bss_start = .; * (.bss*); @@ -30,4 +33,9 @@ SECTIONS { . = ALIGN(4); _main_size = . - _main_start; _mem_start = .; + + /DISCARD/ : { + *(.note.GNU-stack); + *(.comment); + } } diff --git a/src/asmops.h b/src/asmops.h index 09adb13..5d8ec31 100644 --- a/src/asmops.h +++ b/src/asmops.h @@ -77,5 +77,9 @@ static inline uint32_t inpd(uint16_t port) /* delay for about 1us */ #define iodelay() outp(0x80, 0) +#define get_ebp(ebp) \ + asm volatile( \ + "mov %%ebp, %0\n\t" \ + : "=g"((uint32_t)(ebp))) #endif /* ASMOPS_H_ */ diff --git a/src/config.h b/src/config.h index 1c1f7ad..c83bb90 100644 --- a/src/config.h +++ b/src/config.h @@ -22,6 +22,6 @@ along with this program. If not, see . #define TICK_FREQ_HZ 250 #define CON_TEXTMODE -/*#define CON_SERIAL*/ +#define CON_SERIAL #endif /* PCBOOT_CONFIG_H_ */ diff --git a/src/contty.c b/src/contty.c index b36a9c2..2ed22e7 100644 --- a/src/contty.c +++ b/src/contty.c @@ -46,6 +46,7 @@ static void scroll(void); static void crtc_cursor(int x, int y); static void crtc_getcursor(int *x, int *y); static void crtc_setstart(int y); +static int crtc_getstart(void); static inline unsigned char crtc_read(int reg); static inline void crtc_write(int reg, unsigned char val); @@ -56,6 +57,7 @@ static unsigned char cy0, cy1; static int curvis; static int scr_on = 1; + int con_init(void) { #ifdef CON_SERIAL @@ -68,9 +70,9 @@ int con_init(void) cy0 &= 0x1f; cy1 = crtc_read(CRTC_REG_CUREND) & 0x1f; + start_line = crtc_getstart(); crtc_getcursor(&cursor_x, &cursor_y); con_show_cursor(1); - crtc_setstart(0); scr_on = 1; #endif @@ -285,6 +287,16 @@ static void crtc_setstart(int y) crtc_write(CRTC_REG_START_H, addr >> 8); } +static int crtc_getstart(void) +{ + unsigned int addr; + + addr = crtc_read(CRTC_REG_START_L); + addr |= (unsigned int)crtc_read(CRTC_REG_START_H) << 8; + + return addr / NCOLS; +} + static inline unsigned char crtc_read(int reg) { outp(CRTC_ADDR, reg); diff --git a/src/intr.c b/src/intr.c index b1fd004..616189e 100644 --- a/src/intr.c +++ b/src/intr.c @@ -55,7 +55,6 @@ along with this program. If not, see . #define OCW2_EOI (1 << 5) -void init_pic(void); static void gate_desc(desc_t *desc, uint16_t sel, uint32_t addr, int dpl, int type); /* defined in intr_asm.S */ diff --git a/src/kbscan.h b/src/kbscan.h index aaca8b8..0c1cdee 100644 --- a/src/kbscan.h +++ b/src/kbscan.h @@ -27,12 +27,15 @@ static int scantbl_set1[] = { KB_NUM_MUL, KB_LALT, ' ', KB_CAPSLK, KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8, KB_F9, KB_F10, /* 37 - 44 */ KB_NUMLK, KB_SCRLK, KB_NUM_7, KB_NUM_8, KB_NUM_9, KB_NUM_MINUS, KB_NUM_4, KB_NUM_5, KB_NUM_6, KB_NUM_PLUS, /* 45 - 4e */ KB_NUM_1, KB_NUM_2, KB_NUM_3, KB_NUM_0, KB_NUM_DOT, KB_SYSRQ, 0, 0, KB_F11, KB_F12, /* 4d - 58 */ +#if 0 0, 0, 0, 0, 0, 0, 0, /* 59 - 5f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 - 6f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 70 - 7f */ +#endif }; /* extended scancodes, after the 0xe0 prefix */ +#if 0 static int scantbl_set1_ext[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 - f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\r', KB_RCTRL, 0, 0, /* 10 - 1f */ @@ -43,6 +46,7 @@ static int scantbl_set1_ext[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 - 6f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 70 - 7f */ }; +#endif #endif /* KBSCAN_H_ */ diff --git a/src/keyb.c b/src/keyb.c index 2b01408..ea32945 100644 --- a/src/keyb.c +++ b/src/keyb.c @@ -272,8 +272,30 @@ static void kbintr() num_pressed++; } - key = ext ? scantbl_set1_ext[code] : scantbl_set1[code]; - ext = 0; + if(!ext) { + key = code < 0x59 ? scantbl_set1[code] : 0; + } else { + switch(code) { + case 0x1c: key = '\r'; break; + case 0x1d: key = KB_RCTRL; break; + //case 0x35: key = KB_NUM_MINUS; break; + //case 0x37: key = KB_SYSRQ; break; + case 0x38: key = KB_RALT; break; + case 0x47: key = KB_HOME; break; + case 0x48: key = KB_UP; break; + case 0x49: key = KB_PGUP; break; + case 0x4b: key = KB_LEFT; break; + case 0x4d: key = KB_RIGHT; break; + case 0x4f: key = KB_END; break; + case 0x50: key = KB_DOWN; break; + case 0x51: key = KB_PGDN; break; + case 0x52: key = KB_INSERT; break; + case 0x53: key = KB_DEL; break; + default: + key = 0; + } + ext = 0; + } if(press) { if(key == KB_DEL && (keystate[KB_LALT] || keystate[KB_RALT]) && (keystate[KB_LCTRL] || keystate[KB_RCTRL])) { diff --git a/src/libc/stdio.c b/src/libc/stdio.c index 1f12fd6..a0e39b1 100644 --- a/src/libc/stdio.c +++ b/src/libc/stdio.c @@ -139,10 +139,12 @@ int ser_vprintf(const char *fmt, va_list ap) return intern_printf(OUT_SER, 0, 0, fmt, ap); } +/* void perror(const char *s) { printf("%s: %s\n", s, strerror(errno)); } +*/ /* intern_printf provides all the functionality needed by all the printf * variants. diff --git a/src/libc/string.c b/src/libc/string.c index 5afe839..06d8f87 100644 --- a/src/libc/string.c +++ b/src/libc/string.c @@ -223,7 +223,7 @@ char *strncpy(char *dest, const char *src, int n) return dest; } - +/* static const char *errstr[] = { "Success", "Foo", @@ -257,3 +257,4 @@ char *strerror(int err) } return (char*)errstr[err]; } +*/ diff --git a/src/loader.asm b/src/loader.asm index d31c6a8..26a0743 100644 --- a/src/loader.asm +++ b/src/loader.asm @@ -8,6 +8,7 @@ extern boot_mem_map_size %include 'macros.inc' +%define CON_SERIAL [bits 16] global _start @@ -34,7 +35,9 @@ _start: jmp exit .notvm86: +%ifdef CON_SERIAL call setup_serial +%endif call enable_a20 call detect_memory @@ -213,6 +216,8 @@ kbc_wait_write: ; ---------------------- memory detection ----------------------- detect_memory: + mov si, memdet_detram + call printstr mov si, memdet_e820_msg call printstr call detect_mem_e820 @@ -220,6 +225,8 @@ detect_memory: mov si, str_fail call printstr + mov si, memdet_detram + call printstr mov si, memdet_e801_msg call printstr call detect_mem_e801 @@ -227,6 +234,8 @@ detect_memory: mov si, str_fail call printstr + mov si, memdet_detram + call printstr mov esi, memdet_88_msg call printstr call detect_mem_88 @@ -234,6 +243,8 @@ detect_memory: mov esi, str_fail call printstr + mov si, memdet_detram + call printstr mov esi, memdet_cmos_msg call printstr call detect_mem_cmos @@ -252,10 +263,11 @@ detect_memory: str_ok db 'OK',10,0 str_fail db 'failed',10,0 memdet_fail_msg db 'Failed to detect available memory!',10,0 -memdet_e820_msg db 'Detecting RAM (BIOS 15h/0xe820)... ',0 -memdet_e801_msg db 'Detecting RAM (BIOS 15h/0xe801)... ',0 -memdet_88_msg db 'Detecting RAM (BIOS 15h/0x88, max 64mb)... ',0 -memdet_cmos_msg db 'Detecting RAM (CMOS)...',0 +memdet_detram db 'Detecting RAM ' +memdet_e820_msg db '(BIOS 15h/0xe820)... ',0 +memdet_e801_msg db '(BIOS 15h/0xe801)... ',0 +memdet_88_msg db '(BIOS 15h/0x88, max 64mb)... ',0 +memdet_cmos_msg db '(CMOS)...',0 ; detect extended memory using BIOS call 15h/e820 detect_mem_e820: @@ -424,6 +436,7 @@ mem_map times 128 db 0 ; ----------------------- serial console ------------------------ +%ifdef CON_SERIAL setup_serial: ; set clock divisor mov dx, UART_BASE + 3 ; LCTL @@ -461,6 +474,9 @@ ser_printstr: jmp ser_printstr .end: ret +%endif ; def CON_SERIAL + + printstr: lodsb test al, al @@ -468,38 +484,24 @@ printstr: cmp al, 10 ; check for line-feed and insert CR before it jnz .nolf push ax +%ifdef CON_SERIAL mov al, 13 call ser_putchar +%endif mov dl, 13 mov ah, 2 int 21h pop ax -.nolf: call ser_putchar +.nolf: +%ifdef CON_SERIAL + call ser_putchar +%endif mov ah, 2 mov dl, al int 21h jmp printstr .end: ret - [bits 32] -ser_putchar_pmode: - SER_PUTCHAR - ret - -ser_putstr_pmode: - lodsb - test al, al - jz .end - cmp al, 10 - jnz .nolf - push ax - mov al, 13 - call ser_putchar_pmode - pop ax -.nolf: call ser_putchar_pmode - jmp ser_putstr_pmode -.end: ret - align 4 enterpm dd 0xbad00d ; space for linear address for far jump to pmode diff --git a/src/macros.inc b/src/macros.inc index 03613dc..065c601 100644 --- a/src/macros.inc +++ b/src/macros.inc @@ -14,7 +14,7 @@ UART_DIVISOR equ 115200 / 9600 ; 9600 baud push ax mov dx, UART_BASE + 5 ; LSTAT %%wait: in al, dx - test al, 20h ; TRIG_EMPTY + test al, 20h ; TREG_EMPTY jz %%wait mov dx, UART_BASE pop ax diff --git a/src/main.c b/src/main.c index c19dd5f..d3ed273 100644 --- a/src/main.c +++ b/src/main.c @@ -7,8 +7,6 @@ #include "psaux.h" #include "timer.h" -extern uint16_t orig_seg; - int main(void) { init_segm(); diff --git a/src/panic.c b/src/panic.c index 18e7dc6..788900e 100644 --- a/src/panic.c +++ b/src/panic.c @@ -18,6 +18,7 @@ along with this program. If not, see . #include #include #include +#include "intr.h" #include "asmops.h" struct all_registers { @@ -63,3 +64,18 @@ void panic(const char *fmt, ...) for(;;) halt_cpu(); } + +void backtrace(void) +{ + int lvl = 0; + uint32_t *frmptr; + int ien = get_intr_flag(); + disable_intr(); + get_ebp(frmptr); + set_intr_flag(ien); + + while(frmptr) { + printf("%d: %p\n", lvl++, (void*)frmptr[1]); + frmptr = (uint32_t*)*frmptr; + } +} diff --git a/src/panic.h b/src/panic.h index 012eecb..0785059 100644 --- a/src/panic.h +++ b/src/panic.h @@ -19,5 +19,6 @@ along with this program. If not, see . #define PANIC_H_ void panic(const char *fmt, ...) __attribute__((noreturn)); +void backtrace(void); #endif /* PANIC_H_ */ diff --git a/src/segm.c b/src/segm.c index 0d8f4b4..2a461a6 100644 --- a/src/segm.c +++ b/src/segm.c @@ -52,8 +52,10 @@ void setup_selectors(uint16_t code, uint16_t data); void set_gdt(uint32_t addr, uint16_t limit); void set_task_reg(uint16_t tss_selector); +/* static void dbg_print_gdt(void); static void print_desc(desc_t *desc); +*/ /* our global descriptor table */ static desc_t gdt[NUM_SEGMENTS] __attribute__((aligned(8))); @@ -75,8 +77,6 @@ void init_segm(void) set_gdt((uint32_t)gdt, sizeof gdt - 1); setup_selectors(selector(SEGM_CODE, 0), selector(SEGM_DATA, 0)); - - dbg_print_gdt(); } /* constructs a GDT selector based on index and priviledge level */ @@ -137,7 +137,6 @@ static void task_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl) TSS_TYPE_BITS; /* XXX busy ? */ desc->d[3] = ((limit >> 16) & 0xf) | ((base >> 16) & 0xff00) | BIT_GRAN; } -#endif static void dbg_print_gdt(void) { @@ -171,3 +170,4 @@ static void print_desc(desc_t *desc) printf("base:%x lim:%x dpl:%d type:%s %dbit\n", base, limit, dpl, desc->d[2] & BIT_CODE ? "code" : "data", desc->d[3] & BIT_BIG ? 32 : 16); } +#endif diff --git a/src/serial.c b/src/serial.c index f9ee14c..6954508 100644 --- a/src/serial.c +++ b/src/serial.c @@ -17,6 +17,7 @@ along with this program. If not, see . */ #include #include +#include #include "config.h" #include "serial.h" #include "asmops.h" @@ -113,16 +114,19 @@ along with this program. If not, see . #define COM_FMT_8N1 LCTL_8N1 #define COM_FMT_8N2 LCTL_8N2 +#define INBUF_SIZE 16 +#define BNEXT(x) (((x) + 1) & (INBUF_SIZE - 1)) +#define BEMPTY(b) (b##_ridx == b##_widx) + struct serial_port { int base, intr; int blocking; + int ref; - char inbuf[256]; + char inbuf[INBUF_SIZE]; int inbuf_ridx, inbuf_widx; }; -#define BNEXT(x) (((x) + 1) & 0xff) -#define BEMPTY(b) (b##_ridx == b##_widx) static int have_recv(int base); static void recv_intr(); @@ -136,7 +140,7 @@ static int uart_irq[] = {UART1_IRQ, UART2_IRQ}; int ser_open(int pidx, int baud, unsigned int mode) { unsigned short div = 115200 / baud; - int base, intr; + int i, fd, base, intr; unsigned int fmt; if(pidx < 0 || pidx > 1) { @@ -144,11 +148,16 @@ int ser_open(int pidx, int baud, unsigned int mode) return -1; } - if(ports[pidx].base) { - printf("ser_open: port %d already open!\n", pidx); - return -1; + for(i=0; i