progress on all fronts
authorJohn Tsiombikas <nuclear@member.fsf.org>
Fri, 6 Oct 2023 01:53:55 +0000 (04:53 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Fri, 6 Oct 2023 01:53:55 +0000 (04:53 +0300)
18 files changed:
Makefile
com32.ld
src/asmops.h
src/config.h
src/contty.c
src/intr.c
src/kbscan.h
src/keyb.c
src/libc/stdio.c
src/libc/string.c
src/loader.asm
src/macros.inc
src/main.c
src/panic.c
src/panic.h
src/segm.c
src/serial.c
src/startup.asm

index 68742d5..1226610 100644 (file)
--- 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:
index 701a0b4..213b4e2 100644 (file)
--- 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);
+       }
 }
index 09adb13..5d8ec31 100644 (file)
@@ -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_ */
index 1c1f7ad..c83bb90 100644 (file)
@@ -22,6 +22,6 @@ along with this program.  If not, see <https://www.gnu.org/licenses/>.
 #define TICK_FREQ_HZ           250
 
 #define CON_TEXTMODE
-/*#define CON_SERIAL*/
+#define CON_SERIAL
 
 #endif /* PCBOOT_CONFIG_H_ */
index b36a9c2..2ed22e7 100644 (file)
@@ -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);
index b1fd004..616189e 100644 (file)
@@ -55,7 +55,6 @@ along with this program.  If not, see <https://www.gnu.org/licenses/>.
 #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 */
index aaca8b8..0c1cdee 100644 (file)
@@ -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_ */
index 2b01408..ea32945 100644 (file)
@@ -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])) {
index 1f12fd6..a0e39b1 100644 (file)
@@ -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.
index 5afe839..06d8f87 100644 (file)
@@ -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];
 }
+*/
index d31c6a8..26a0743 100644 (file)
@@ -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
index 03613dc..065c601 100644 (file)
@@ -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
index c19dd5f..d3ed273 100644 (file)
@@ -7,8 +7,6 @@
 #include "psaux.h"
 #include "timer.h"
 
-extern uint16_t orig_seg;
-
 int main(void)
 {
        init_segm();
index 18e7dc6..788900e 100644 (file)
@@ -18,6 +18,7 @@ along with this program.  If not, see <https://www.gnu.org/licenses/>.
 #include <stdio.h>
 #include <string.h>
 #include <stdarg.h>
+#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;
+       }
+}
index 012eecb..0785059 100644 (file)
@@ -19,5 +19,6 @@ along with this program.  If not, see <https://www.gnu.org/licenses/>.
 #define PANIC_H_
 
 void panic(const char *fmt, ...) __attribute__((noreturn));
+void backtrace(void);
 
 #endif /* PANIC_H_ */
index 0d8f4b4..2a461a6 100644 (file)
@@ -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
index f9ee14c..6954508 100644 (file)
@@ -17,6 +17,7 @@ along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
 #include <stdio.h>
 #include <string.h>
+#include <assert.h>
 #include "config.h"
 #include "serial.h"
 #include "asmops.h"
@@ -113,16 +114,19 @@ along with this program.  If not, see <https://www.gnu.org/licenses/>.
 #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<num_open; i++) {
+               if(ports[i].base == uart_base[pidx]) {
+                       /* the port is already open, return the same fd and increment ref */
+                       ports[i].ref++;
+                       return i;
+               }
        }
-       memset(ports + pidx, 0, sizeof ports[pidx]);
+
+       fd = num_open++;
+       memset(ports + fd, 0, sizeof ports[pidx]);
 
        base = uart_base[pidx];
        intr = uart_irq[pidx];
@@ -169,21 +178,22 @@ int ser_open(int pidx, int baud, unsigned int mode)
        outp(base + UART_MCTL, MCTL_DTR | MCTL_RTS | MCTL_OUT2);
        outp(base + UART_INTR, INTR_RECV);
 
-       ports[pidx].base = base;
-       ports[pidx].intr = intr;
-       ports[pidx].blocking = 1;
-       ++num_open;
-       return pidx;
+       ports[fd].base = base;
+       ports[fd].intr = intr;
+       ports[fd].blocking = 1;
+       ports[fd].ref = 1;
+       return fd;
 }
 
 void ser_close(int fd)
 {
-       if(--num_open == 0) {
+       if(!ports[fd].ref) return;
+
+       if(--ports[fd].ref == 0) {
                outp(ports[fd].base + UART_INTR, 0);
                outp(ports[fd].base + UART_MCTL, 0);
+               ports[fd].base = 0;
        }
-
-       ports[fd].base = 0;
 }
 
 int ser_block(int fd)
@@ -271,8 +281,8 @@ int ser_read(int fd, char *buf, int count)
 
 char *ser_getline(int fd, char *buf, int bsz)
 {
-       static char linebuf[512];
        static int widx;
+       char linebuf[512];
        int i, rd, size, offs;
 
        size = sizeof linebuf - widx;
index bc033e2..d18c368 100644 (file)
@@ -21,7 +21,7 @@ startup:
        rep stosd
 .nobss:
 
-       mov ebp, 12345678h
+       xor ebp, ebp    ; terminate backtraces
        call main
        cli     ; XXX