From: John Tsiombikas Date: Wed, 4 Oct 2023 00:45:33 +0000 (+0300) Subject: works and returns to DOS on dosbox X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=commitdiff_plain;h=5f1715379ac10a17b30fa51d5c30399f4d544e4e;p=com32 works and returns to DOS on dosbox --- diff --git a/.gitignore b/.gitignore index 5300cea..cec07fe 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ disasm dosbox.conf *.log tofloppy +*.s diff --git a/Makefile b/Makefile index accedf7..68742d5 100644 --- a/Makefile +++ b/Makefile @@ -10,8 +10,9 @@ inc = -Isrc -Isrc/libc AS = nasm ASFLAGS = -Isrc/ -CFLAGS = -m32 -march=i386 $(warn) $(opt) $(dbg) -fno-pic -ffreestanding -nostdinc \ - -ffast-math $(inc) $(def) +CFLAGS = -m32 -march=i386 $(warn) $(opt) $(dbg) -fno-pic -ffreestanding \ + -fno-stack-protector -mpreferred-stack-boundary=2 -nostdinc -ffast-math \ + $(inc) $(def) LDFLAGS = -m elf_i386 -nostdlib -T com32.ld -Map test.map $(bin): $(obj) @@ -23,7 +24,7 @@ $(bin): $(obj) $(AS) -o $@ -f elf $(ASFLAGS) $< %.s: %.c - $(CC) $(CFLAGS) -S $< -o $@ + $(CC) $(CFLAGS) -masm=intel -g0 -fno-asynchronous-unwind-tables -S $< -o $@ .PHONY: clean clean: diff --git a/src/intr.c b/src/intr.c index 29ca70e..b1fd004 100644 --- a/src/intr.c +++ b/src/intr.c @@ -90,11 +90,6 @@ void init_intr(void) interrupt(i, 0); } - /* mask all IRQs by default */ - for(i=0; i<16; i++) { - mask_irq(i); - } - /* by including intrtab.h here the series of INTR_ENTRY_* macros will be * expanded to a series of function prototypes for all interrupt entry * points and the corresponding calls to set_intr_entry to set up the IDT @@ -111,10 +106,17 @@ void init_intr(void) /* initialize the programmable interrupt controller * setting up the maping of IRQs [0, 15] to interrupts [32, 47] */ - init_pic(); + prog_pic(IRQ_OFFSET); eoi_pending = 0; } +void cleanup_intr(void) +{ + disable_intr(); + /* reprogram the PIC to the default BIOS offset (8) */ + prog_pic(8); +} + /* retrieve the current interrupt frame. * returns 0 when called during init. */ @@ -151,7 +153,7 @@ void dispatch_intr(struct intr_frame frm) panic("unhandled exception %u, error code: %u, at cs:eip=%x:%x\n", frm.inum, frm.err, frm.cs, frm.eip); } - printf("unhandled interrupt %d\n", frm.inum); + /*printf("unhandled interrupt %d\n", frm.inum);*/ } disable_intr(); @@ -160,11 +162,6 @@ void dispatch_intr(struct intr_frame frm) } } -void init_pic(void) -{ - prog_pic(IRQ_OFFSET); -} - void prog_pic(int offs) { /* send ICW1 saying we'll follow with ICW4 later on */ @@ -210,7 +207,7 @@ void set_intr_entry(int num, void (*handler)(void)) */ int dpl = (num == SYSCALL_INT) ? 3 : 0; - gate_desc(idt + num, selector(SEGM_KCODE, 0), (uint32_t)handler, dpl, type); + gate_desc(idt + num, selector(SEGM_CODE, 0), (uint32_t)handler, dpl, type); } void set_pic_mask(int pic, unsigned char mask) diff --git a/src/intr.h b/src/intr.h index f33ec23..3cfbe8b 100644 --- a/src/intr.h +++ b/src/intr.h @@ -61,6 +61,7 @@ typedef void (*intr_func_t)(int); void init_intr(void); +void cleanup_intr(void); struct intr_frame *get_intr_frame(void); diff --git a/src/loader.asm b/src/loader.asm index ea0de70..d31c6a8 100644 --- a/src/loader.asm +++ b/src/loader.asm @@ -96,14 +96,7 @@ _start: mov esp, _main_start call 8:startup - - PMPRINT 'X' - PMPRINT 'Y' - PMPRINT 'Z' - PMPRINT 'Z' - PMPRINT 'Y' - PMPRINT 13 - PMPRINT 10 + cli ; return to real mode jmp 28h:.rm @@ -120,12 +113,15 @@ _start: mov es, ax mov ss, ax + ; restore real-mode IVT + lidt [rmidt] + sti + + mov ax, 3 + int 10h exit: mov ax, 4c00h int 21h -dbg_inpm db 'DBG: in pmode',10,0 -dbg_retrm db 'DBG: returning to real mode...',10,0 - str_errvm86 db 'Error: memory manager detected! Stop it and try again (e.g. emm386 off)',10,0 str_enterpm db 'Entering 32bit protected mode ...',10,0 @@ -532,5 +528,10 @@ gdt: ; 0: null segment dd 0000ffffh dd 00009a00h + ; pseudo IDTR descriptor for real-mode IVT at address 0 + align 4 + dw 0 +rmidt: dw 3ffh ; IVT limit (1kb / 256 entries) + dd 0 ; IVT base 0 ; vi:set ts=8 sts=8 sw=8 ft=nasm: diff --git a/src/main.c b/src/main.c index 08f9510..c19dd5f 100644 --- a/src/main.c +++ b/src/main.c @@ -7,13 +7,16 @@ #include "psaux.h" #include "timer.h" +extern uint16_t orig_seg; + int main(void) { + init_segm(); init_intr(); con_init(); kb_init(); - init_psaux(); + /*init_psaux();*/ init_mem(); @@ -21,6 +24,9 @@ int main(void) enable_intr(); - printf("hello from C\n"); + printf("\nhello from C\n"); + + cleanup_intr(); /* also disables interrupts */ + cleanup_timer(); return 0; } diff --git a/src/segm.c b/src/segm.c index c6baffd..0d8f4b4 100644 --- a/src/segm.c +++ b/src/segm.c @@ -15,6 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include #include #include "segm.h" #include "desc.h" @@ -44,30 +45,38 @@ enum {TYPE_DATA, TYPE_CODE}; static void segm_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl, int type); static void segm_desc16(desc_t *desc, uint32_t base, uint32_t limit, int dpl, int type); -static void task_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl); +/*static void task_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl);*/ /* these functions are implemented in segm-asm.S */ 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))); - +uint16_t orig_seg; void init_segm(void) { + asm volatile ( + "mov %%fs, %0\n\t" + : "=a"(orig_seg)); + memset(gdt, 0, sizeof gdt); - segm_desc(gdt + SEGM_KCODE, 0, 0xffffffff, 0, TYPE_CODE); - segm_desc(gdt + SEGM_KDATA, 0, 0xffffffff, 0, TYPE_DATA); - segm_desc(gdt + SEGM_UCODE, 0, 0xffffffff, 3, TYPE_CODE); - segm_desc(gdt + SEGM_UDATA, 0, 0xffffffff, 3, TYPE_DATA); - segm_desc16(gdt + SEGM_CODE16, 0, 0xffff, 0, TYPE_CODE); + segm_desc(gdt + SEGM_CODE, 0, 0xffffffff, 0, TYPE_CODE); + segm_desc(gdt + SEGM_DATA, 0, 0xffffffff, 0, TYPE_DATA); + segm_desc(gdt + SEGM_XCODE, orig_seg << 4, 0xffffffff, 0, TYPE_CODE); + segm_desc(gdt + SEGM_XDATA, orig_seg << 4, 0xffffffff, 0, TYPE_DATA); + segm_desc16(gdt + SEGM_CODE16, orig_seg << 4, 0xffff, 0, TYPE_CODE); set_gdt((uint32_t)gdt, sizeof gdt - 1); - setup_selectors(selector(SEGM_KCODE, 0), selector(SEGM_KDATA, 0)); + setup_selectors(selector(SEGM_CODE, 0), selector(SEGM_DATA, 0)); + + dbg_print_gdt(); } /* constructs a GDT selector based on index and priviledge level */ @@ -76,11 +85,13 @@ uint16_t selector(int idx, int rpl) return (idx << 3) | (rpl & 3); } +/* void set_tss(uint32_t addr) { task_desc(gdt + SEGM_TASK, addr, sizeof(struct task_state) - 1, 3); set_task_reg(selector(SEGM_TASK, 0)); } +*/ static void segm_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl, int type) { @@ -116,6 +127,7 @@ static void segm_desc16(desc_t *desc, uint32_t base, uint32_t limit, int dpl, in desc->d[3] = 0; } +#if 0 static void task_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl) { desc->d[0] = limit & 0xffff; @@ -125,7 +137,8 @@ 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) { int i; @@ -133,7 +146,8 @@ static void dbg_print_gdt(void) printf("Global Descriptor Table\n"); printf("-----------------------\n"); - for(i=0; i<6; i++) { + for(i=0; id[0] | desc->d[1] | desc->d[2] | desc->d[3]) == 0) { + printf("null\n"); + } base = (uint32_t)desc->d[1] | ((uint32_t)(desc->d[2] & 0xff) << 16) | ((uint32_t)(desc->d[3] >> 8) << 24); limit = (uint32_t)desc->d[0] | ((uint32_t)(desc->d[3] & 0xf) << 16); dpl = (desc->d[2] >> 13) & 3; - type = (desc->d[2] >> 8) & 0xf; - g = (desc->d[3] >> 23) & 1; - db = (desc->d[3] >> 22) & 1; - l = (desc->d[3] >> 21) & 1; - avl = (desc->d[3] >> 20) & 1; - - p = (desc->d[2] >> 15) & 1; - s = (desc->d[2] >> 12) & 1; + g = (desc->d[3] >> 7) & 1; + + if(g) limit = ((limit + 1) << 12) - 1; + + 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); } -*/ diff --git a/src/segm.h b/src/segm.h index bf76c72..f3b083c 100644 --- a/src/segm.h +++ b/src/segm.h @@ -21,11 +21,11 @@ along with this program. If not, see . #include enum { - SEGM_KCODE = 1, - SEGM_KDATA = 2, - SEGM_UCODE, - SEGM_UDATA, - SEGM_TASK, + SEGM_NULL, + SEGM_CODE, + SEGM_DATA, + SEGM_XCODE, /* transition 32bit code with base matching the RM segment */ + SEGM_XDATA, /* same for data */ SEGM_CODE16, NUM_SEGMENTS diff --git a/src/startup.asm b/src/startup.asm index 8c7dfbb..bc033e2 100644 --- a/src/startup.asm +++ b/src/startup.asm @@ -21,6 +21,7 @@ startup: rep stosd .nobss: + mov ebp, 12345678h call main cli ; XXX @@ -29,7 +30,7 @@ startup: test al, 1 jz .waitkey in al, 60h - ret + retf ; global putchar ;putchar: diff --git a/src/timer.c b/src/timer.c index f4a812b..c050b84 100644 --- a/src/timer.c +++ b/src/timer.c @@ -89,6 +89,14 @@ void init_timer(void) unmask_irq(0); } +void cleanup_timer(void) +{ + /* return the timer to the original rate */ + outp(PORT_CMD, CMD_CHAN0 | CMD_ACCESS_BOTH | CMD_OP_SQWAVE); + outp(PORT_DATA0, 0); + outp(PORT_DATA0, 0); +} + void set_alarm(unsigned long msec, void (*func)(void)) { int ticks, tsum, iflag; diff --git a/src/timer.h b/src/timer.h index c41c0f5..c057801 100644 --- a/src/timer.h +++ b/src/timer.h @@ -26,6 +26,7 @@ along with this program. If not, see . extern volatile unsigned long nticks; void init_timer(void); +void cleanup_timer(void); /* int sys_sleep(int sec);