From: DeaDDooMER Date: Wed, 27 Jun 2018 15:24:33 +0000 (+0300) Subject: Initial Bare Metal BlackBox Prototype X-Git-Url: http://deadsoftware.ru/gitweb?p=bmbb.git;a=commitdiff_plain;h=21efe406346aee850b1fe0f3050f10c28310f5bf Initial Bare Metal BlackBox Prototype --- 21efe406346aee850b1fe0f3050f10c28310f5bf diff --git a/Boot486/1run.sh b/Boot486/1run.sh new file mode 100755 index 0000000..25caf33 --- /dev/null +++ b/Boot486/1run.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +set -e +qemu-system-i386 -s -S -fda ../BlackBox.img diff --git a/Boot486/2run.sh b/Boot486/2run.sh new file mode 100755 index 0000000..f36443c --- /dev/null +++ b/Boot486/2run.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +#bochs -q 'boot:a' 'floppya: 1_44=../BlackBox.img, status=inserted' +#bochs -q 'boot:c' 'ata0-master: type=disk, path="boot.bin", mode=flat' +#bochs -q 'boot:c' 'ata0-master: type=disk, path="boot.bin", mode=flat' 'display_library: x, options="gui_debug"' 2> bochs.log +bochs -q \ + 'boot:a' \ + 'floppya: 1_44=boot.bin, status=inserted' \ + 'display_library: x, options="gui_debug"' \ + 'com1: enabled=1, mode=file, dev=serial.txt' \ +2> bochs.log diff --git a/Boot486/boot0.S b/Boot486/boot0.S new file mode 100644 index 0000000..21608cb --- /dev/null +++ b/Boot486/boot0.S @@ -0,0 +1,440 @@ +.text +.global _start + +/* + * Bootloader configuration + */ + +.set STACK1, 0x7000 +.set STACK2, 0xe000 +.set BUFFER, 0x8000 # 0x80000 - 0x8000 = 480k +.set READBLOCKS, 1 + +/* + * Kernel configuration (sync with Kernel.odc!) + */ + +.set KernelSizeAdr, 0x7e00 +.set BootDiskAdr, 0x7e04 +.set BootDiskDxAdr, 0x7e06 +.set BootDiskCxAdr, 0x7e08 +.set MemoryMapAdr, 0x7e0A +.set ImageBase, 0x1000000 + +# =========================================================================== # +# Stage 1 +# =========================================================================== # + +.code16 +_start: +stage1: +# 1. Setup canonical %cs:%eip, segment registers %ds, %es, %fs, %gs, %ss and stack %sp + cli + ljmp $0x0, $canonized_label; canonized_label: + xor %ax, %ax + mov %ax, %ds + mov %ax, %es +# mov %ax, %fs +# mov %ax, %gs + mov %ax, %ss + mov $STACK1, %sp + + mov %dx, BootDiskAdr + call mapmem + +# 2. Enable A20 gate + call enable_A20 + sti + +# 3. Reset disk controller (%dl and %dh initialized by bios) and read Kernel into buffer + movl $(kernel_code_end - kernel_code_start), KernelSizeAdr + + stage1__read: + mov current_sector, %ax + add $1, %ax + call lba2chs + + mov current_sector, %ax + shl $5, %ax + add $(BUFFER / 16), %ax + mov %ax, %es + call readsectors + + mov current_sector, %ax + add $READBLOCKS, %ax + mov %ax, current_sector + cmp $((kernel_code_end - kernel_code_start + 511) / 512), %ax + jl stage1__read + +# 4. Disable interrupts and load GDT + mov $msg_protected_mode, %si + call print + cli + lgdt gdt_info + +# 5. Switch to protected mode + mov %cr0, %eax + or $1, %al + mov %eax, %cr0 + jmp $8, $stage2 + +# =========================================================================== # +# Stage 2 +# =========================================================================== # + +.code32 +stage2: +# 6. Setup data segments %ds, %es, %fs, %gs and stack %sp + mov $16, %ax + mov %ax, %ds + mov %ax, %ss + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + mov $STACK2, %sp +# 7. Copy Kernel from buffer + xor %eax, %eax + stage2_copy_loop: + mov BUFFER(%eax), %bh + mov %bh, ImageBase(%eax) + inc %eax + cmp $(kernel_code_end - kernel_code_start), %eax + jne stage2_copy_loop +# 8. Exec Kernel + jmp ImageBase + + +# =========================================================================== # +# Print asciiz string +# input: %si = String +# =========================================================================== # + +.code16 +print: + pusha + movb $0x0e, %ah + print__loop: + lodsb + orb %al, %al + jz print__ret + int $0x10 + jmp print__loop + print__ret: + popa + ret + +# =========================================================================== # +# Make memory map for kernel +# =========================================================================== # + +.code16 +mapmem: + pusha + movl $0, MemoryMapAdr + xor %ebx, %ebx + mov $(MemoryMapAdr + 4), %di + mapmem__loop: + mov $0xe820, %eax + mov $20, %ecx + mov $0x0534D4150, %edx + int $0x15 + jc mapmem__failed + cmp %edx, %eax + jne mapmem__failed + cmp $0, %ebx + je mapmem__done + add $20, %di + incl MemoryMapAdr + jmp mapmem__loop + mapmem__done: + popa + ret # <============ + mapmem__failed: + mov $msg_mapmem_failed, %si + call print + cli + hlt + +# =========================================================================== # +# Convert LBA to CHS +# input: %ax = LBA %dl = disk +# output: %ch = cylider %cl = sector %dh = head %dl = disk +# =========================================================================== # + +.code16 +lba2chs: +# push %es +# push %di + push %dx + push %ax + + clc + mov $0x0, %ax + mov %ax, %es + mov %ax, %di + mov $0x8, %ah + int $0x13 + jnc lba2chs__success + mov $msg_chs_error, %si + call print + cli + hlt + lba2chs__success: + mov %dx, BootDiskDxAdr + mov %cx, BootDiskCxAdr + + # SPT = %cl & 63 + # HPC = %dh + 1 + # CYL = LBA / ( HPC * SPT ) + # TEMP = LBA % ( HPC * SPT ) + # HEAD = TEMP / SPT + # SECT = TEMP % SPT + 1 + + # %ax = FREE %bx = FREE %cx = GSPT %dx = HPC-1 + and $0x3F, %cl + movzx %cl, %cx + + # %ax = FREE %bx = FREE %cx = SPT %dx = HPC-1 + movzx %dh, %dx + inc %dx + + # %ax = FREE %bx = FREE %cx = SPT %dx = HPC + mov %dx, %ax + mul %cx; # overflow in %dx + mov %ax, %dx + + # %ax = FREE %bx = FREE %cx = SPT %dx = (HPC * SPT) + pop %ax # LBA + mov %dx, %bx + xor %dx, %dx + div %bx + xchg %ax, %dx + + # %ax = TEMP %bx = FREE %cx = SPT %dx = CYL + mov %dx, %bx + xor %dx, %dx + div %cx + inc %dx + + # %ax = HEAD %bx = CYL %cx = FREE %dx = SECT + mov %bl, %ch + mov %bh, %cl + shl $6, %cl + add %dx, %cx + + # %ax = HEAD %bx = FREE %cx = CYL&SECT %dx = FREE + pop %dx + mov %al, %dh + + # %ax = FREE %bx = FREE %cx = CYL&SECT %dx = HEAD&DISK + +# pop %di +# pop %es + ret + +# =========================================================================== # +# Read sectors to buffer +# input: %cx = Cylider+Sector; %es = 64k buf +# =========================================================================== # + +.code16 +readsectors: + xor %ah, %ah + int $0x13 + + xor %bx, %bx + mov $0x2, %ah + mov $READBLOCKS, %al + clc + int $0x13 + + jnc readsectors__success + + /* zero if sectors not readed */ + or %ah, %ah + jnz readsectors__success + + mov $msg_kernel_read_failed, %si + call print + cli + hlt + +readsectors__success: + ret + +# =========================================================================== # +# Check that A20 Gate is enabled +# output: set zero flag if disabled +# restore: %ds %es +# =========================================================================== # + +.code16 +check_A20: + push %ds + push %es +# push %ax +# push %di +# push %si + + xor %ax, %ax + mov %ax, %es + + not %ax + mov %ax, %ds + + mov $0x0500, %di + mov $0x0510, %si + + mov %es:0(%di), %al + push %ax + + mov %ds:0(%si), %al + push %ax + + movb $0x00, %es:0(%di) + movb $0xff, %ds:0(%si) + + cmpb $0xff, %es:0(%di) + + pop %ax + mov %es:0(%di), %al + + pop %ax + mov %es:0(%di), %al + + mov $0, %ax + + je check_A20__exit + + mov $1, %ax + +check_A20__exit: +# pop %si +# pop %di +# pop %ax + pop %es + pop %ds + or %al, %al + ret + +# =========================================================================== # +# Enable A20 Gate +# =========================================================================== # + +enable_A20: + /* First check */ + call check_A20 + jnz enable_A20__success + + /* BIOS method */ + mov $0x2401, %ax + int $0x15 + + call check_A20 + jnz enable_A20__success + + /* Keyboard method 1 */ + mov $0xd0, %al + out %al, $0x64 + + call check_A20 + jnz enable_A20__success + + /* Keyboard method 2 */ +/* +# cli + + call enable_A20__wait1 + mov $0xad, %al + out %al, $0x64 + + call enable_A20__wait1 + mov $0xd0, %al + out %al, $0x64 + + enable_A20__wait2: + in $0x64, %al + test $1, %al + jz enable_A20__wait2 + + in $0x60, %al + push %eax + + call enable_A20__wait1 + mov $0xd1, %al + out %al, $0x64 + + call enable_A20__wait1 + pop %eax + or $2, %al + out %al, $0x64 + + call enable_A20__wait1 + mov $0xae, %al + out %al, $0x64 + + call enable_A20__wait1 +# sti + +# call check_A20 +# jnz enable_A20__success +*/ + + /* Control port A method */ + mov $1, %al + out %al, $0x92 + + call check_A20 + jnz enable_A20__success + + /* Fast method */ + in $0xee, %al + + call check_A20 + jnz enable_A20__success + + mov $msg_a20_failed, %si + call print +# cli +# hlt + +enable_A20__success: + ret + +/* +enable_A20__wait1: + in $0x64, %al + test $2, %al + jnz enable_A20__wait1 + ret +*/ + +# =========================================================================== # +# =========================================================================== # +# =========================================================================== # + +msg_mapmem_failed: .asciz "1" +msg_a20_failed: .asciz "2" +msg_chs_error: .asciz "3" +msg_kernel_read_failed: .asciz "4" + +msg_protected_mode: .asciz ">5" + +current_sector: +.word 0 +gdt_begin: +.byte 0x00, 0x00, 0, 0, 0, 0b00000000, 0b00000000, 0 # null dsc +.byte 0xff, 0xff, 0, 0, 0, 0b10011010, 0b11001111, 0 # code dsc +.byte 0xff, 0xff, 0, 0, 0, 0b10010010, 0b11001111, 0 # data dsc +gdt_info: +.word (gdt_info - gdt_begin - 1) +.quad (gdt_begin) + +.fill _start + 510 - . +.word 0xaa55 + +kernel_code_start: +.incbin "../BlackBox.bin" +kernel_code_end: + +.fill _start + (1440 * 1024) - . diff --git a/Boot486/dis.sh b/Boot486/dis.sh new file mode 100755 index 0000000..fa9dee1 --- /dev/null +++ b/Boot486/dis.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +set -e +objdump -b binary -m i8086 -D boot.bin | less diff --git a/Boot486/gdbcommands b/Boot486/gdbcommands new file mode 100644 index 0000000..f06460f --- /dev/null +++ b/Boot486/gdbcommands @@ -0,0 +1,6 @@ +target remote localhost:1234 +set architecture i8086 +break *0x7c00 +break *0x1000000 +cont +#layout asm diff --git a/Boot486/kdis.sh b/Boot486/kdis.sh new file mode 100755 index 0000000..1b491a6 --- /dev/null +++ b/Boot486/kdis.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +set -e +objdump -b binary -m i386 -D ../../Kernel.bin | less diff --git a/Boot486/make.sh b/Boot486/make.sh new file mode 100755 index 0000000..41f80bd --- /dev/null +++ b/Boot486/make.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +set -e +as -o boot0.o boot0.S +ld --oformat binary -o ../BlackBox.img -Ttext 0x7c00 boot0.o +rm -f boot0.o diff --git a/Boot486/mkcharfn.c b/Boot486/mkcharfn.c new file mode 100644 index 0000000..5ee9dc0 --- /dev/null +++ b/Boot486/mkcharfn.c @@ -0,0 +1,169 @@ +#include +#include +#include +#include + +#define MAX_CP_CAHR 0x10000 + +static wint_t isalphatab[MAX_CP_CAHR]; +static wint_t isuppertab[MAX_CP_CAHR]; +static wint_t islowertab[MAX_CP_CAHR]; +static wint_t uppertable[MAX_CP_CAHR]; +static wint_t lowertable[MAX_CP_CAHR]; + +static void +print_tabs(int n) { + for (int i = 0; i < n; i++) { + putchar('\t'); + } +} + +static void +print_range (wint_t *tab, int max, int t, int retbool) { + int i = 0; + int begin = 0; + int end = 0; + int oddmode = 0; + int fold = 0; + int count = 0; + + print_tabs(t); + printf("CASE ch OF\n"); + + while (i < max) { + while ((i < max) && (tab[i] == 0)) ++i; + begin = i; + + oddmode = 0; + if (i + 2 < max && tab[i + 1] == 0 && tab[i + 2] != 0) { + if (tab[i] % 2 == 1) { + oddmode = 1; + } else { + oddmode = 2; + } + } + + if (oddmode == 0) { + while (i < max && tab[i] != 0) i += 1; + end = i - 1; + } else { + while (i + 1 < max && tab[i] != 0 && tab[i + 1] == 0) i += 2; + end = i; + } + + if (i < max && begin <= end) { + print_tabs(t); + // printf("(* %i *) ", oddmode) + printf("| "); + + if (begin == end) { + if (retbool) { + printf("0%XX: RETURN TRUE\n", begin); + } else { + printf("0%XX: RETURN 0%XX\n", begin, tab[begin]); + } + } else { + printf("0%XX..0%XX: ", begin, end); + if (retbool) { + if (oddmode == 0) { + printf("RETURN TRUE\n"); + } else if (oddmode == 1) { + printf("RETURN ODD(ORD(ch))\n"); + } else if (oddmode == 2) { + printf("RETURN ~ODD(ORD(ch))\n"); + } + } else { + if (oddmode == 0) { + printf("RETURN CHR(0%XH + ORD(ch) - 0%XH)\n", tab[begin], begin); + } else if (oddmode == 1) { + printf("IF ODD(ORD(ch)) THEN RETURN CHR(0%XH + ORD(ch) - 0%XH) ELSE RETURN ch END\n", tab[begin], begin); + } else if (oddmode == 2) { + printf("IF ~ODD(ORD(ch)) THEN RETURN CHR(0%XH + ORD(ch) - 0%XH) ELSE RETURN ch END\n", tab[begin], begin); + } + } + } + + count += 1; + if (count > 4096) { + count = 0; + fold += 1; + print_tabs(t); + printf("ELSE\n"); + t += 1; + print_tabs(t); + printf("CASE ch OF\n"); + } + } + + i += 1; + } + + for (int i = 0; i < fold + 1; i++) { + print_tabs(t); + printf("ELSE "); + if (retbool) { + printf("RETURN FALSE\n"); + } else { + printf("RETURN ch\n"); + } + print_tabs(t); + printf("END\n"); + t -= 1; + } +} + +int +main (int argc, char **argv) { + setlocale(LC_ALL, ""); + for (wint_t i = 0; i < MAX_CP_CAHR; i++) { + isalphatab[i] = iswalpha(i) ? i : 0; + isuppertab[i] = iswupper(i) ? i : 0; + islowertab[i] = iswlower(i) ? i : 0; + uppertable[i] = (towupper(i) == i) ? 0 : towupper(i); + lowertable[i] = (towlower(i) == i) ? 0 : towlower(i); + } + + printf("MODULE Unicode;\n\n"); + + printf("\tIMPORT Kernel;\n\n"); + + printf("\tTYPE\n"); + printf("\t\tHook = POINTER TO RECORD (Kernel.CharHook) END;\n\n"); + + printf("\tPROCEDURE (h: Hook) Upper (ch: CHAR): CHAR;\n"); + printf("\tBEGIN\n"); + print_range(uppertable, MAX_CP_CAHR, 2, 0); + printf("\tEND Upper;\n\n"); + + printf("\tPROCEDURE (h: Hook) Lower (ch: CHAR): CHAR;\n"); + printf("\tBEGIN\n"); + print_range(lowertable, MAX_CP_CAHR, 2, 0); + printf("\tEND Lower;\n\n"); + + printf("\tPROCEDURE (h: Hook) IsAlpha (ch: CHAR): BOOLEAN;\n"); + printf("\tBEGIN\n"); + print_range(isalphatab, MAX_CP_CAHR, 2, 1); + printf("\tEND IsAlpha;\n\n"); + + printf("\tPROCEDURE (h: Hook) IsUpper (ch: CHAR): BOOLEAN;\n"); + printf("\tBEGIN\n"); + print_range(isuppertab, MAX_CP_CAHR, 2, 1); + printf("\tEND IsUpper;\n\n"); + + printf("\tPROCEDURE (h: Hook) IsLower (ch: CHAR): BOOLEAN;\n"); + printf("\tBEGIN\n"); + print_range(islowertab, MAX_CP_CAHR, 2, 1); + printf("\tEND IsLower;\n\n"); + + printf("\tPROCEDURE Init;\n"); + printf("\t\tVAR h: Hook;\n"); + printf("\tBEGIN\n"); + printf("\t\tNEW(h); Kernel.SetCharHook(h)\n"); + printf("\tEND Init;\n\n"); + + printf("BEGIN\n"); + printf("\tInit\n"); + printf("CLOSE\n"); + printf("\tKernel.SetCharHook(NIL)\n"); + printf("END Unicode."); +} diff --git a/Boot486/mksdb.sh b/Boot486/mksdb.sh new file mode 100755 index 0000000..07e3d8d --- /dev/null +++ b/Boot486/mksdb.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +DRIVE=/dev/sdb + +if ! [ -e $DRIVE ]; then + echo "${DRIVE} not available" + exit 1 +fi + +echo "overwrite ${DRIVE}" +sudo dd if=boot.bin of=$DRIVE diff --git a/Boot486/run.sh b/Boot486/run.sh new file mode 100755 index 0000000..6a315f7 --- /dev/null +++ b/Boot486/run.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +set -e +qemu-system-i386 -s -m 1G -fda ../BlackBox.img diff --git a/Clean486.sh b/Clean486.sh new file mode 100755 index 0000000..bdaa3d3 --- /dev/null +++ b/Clean486.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +find . -type d -name 'Code486' -exec rm -rv {} + +find . -type d -name 'Sym486' -exec rm -rv {} + +rm -f BlackBox.bin BlackBox.img diff --git a/Docu486/Build-Tool.odc b/Docu486/Build-Tool.odc new file mode 100644 index 0000000..2eae911 Binary files /dev/null and b/Docu486/Build-Tool.odc differ diff --git a/Dsw/Docu/BMBB-Build-Tool.odc b/Dsw/Docu/BMBB-Build-Tool.odc new file mode 100644 index 0000000..661a1dc Binary files /dev/null and b/Dsw/Docu/BMBB-Build-Tool.odc differ diff --git a/Dsw/Docu/Cmds.odc b/Dsw/Docu/Cmds.odc new file mode 100644 index 0000000..97f233e Binary files /dev/null and b/Dsw/Docu/Cmds.odc differ diff --git a/Dsw/Docu/Compiler486.odc b/Dsw/Docu/Compiler486.odc new file mode 100644 index 0000000..cf3691f Binary files /dev/null and b/Dsw/Docu/Compiler486.odc differ diff --git a/Dsw/Mod/Cmds.odc b/Dsw/Mod/Cmds.odc new file mode 100644 index 0000000..696b503 Binary files /dev/null and b/Dsw/Mod/Cmds.odc differ diff --git a/Dsw/Mod/Compiler486.odc b/Dsw/Mod/Compiler486.odc new file mode 100644 index 0000000..8a2910a Binary files /dev/null and b/Dsw/Mod/Compiler486.odc differ diff --git a/Dsw/Mod/Linker.odc b/Dsw/Mod/Linker.odc new file mode 100644 index 0000000..d12dca6 Binary files /dev/null and b/Dsw/Mod/Linker.odc differ diff --git a/Dsw/Rsrc/Goto.odc b/Dsw/Rsrc/Goto.odc new file mode 100644 index 0000000..b262aef Binary files /dev/null and b/Dsw/Rsrc/Goto.odc differ diff --git a/Dsw/Rsrc/Menus.odc b/Dsw/Rsrc/Menus.odc new file mode 100644 index 0000000..5765ceb Binary files /dev/null and b/Dsw/Rsrc/Menus.odc differ diff --git a/Dsw/Rsrc/Strings.odc b/Dsw/Rsrc/Strings.odc new file mode 100644 index 0000000..45576f0 Binary files /dev/null and b/Dsw/Rsrc/Strings.odc differ diff --git a/Host/Mod486/Keyboard.odc b/Host/Mod486/Keyboard.odc new file mode 100644 index 0000000..f19a17b Binary files /dev/null and b/Host/Mod486/Keyboard.odc differ diff --git a/Host/Mod486/RamFiles.odc b/Host/Mod486/RamFiles.odc new file mode 100644 index 0000000..5fe4a2a Binary files /dev/null and b/Host/Mod486/RamFiles.odc differ diff --git a/Host/Mod486/Shell.odc b/Host/Mod486/Shell.odc new file mode 100644 index 0000000..f8defd5 Binary files /dev/null and b/Host/Mod486/Shell.odc differ diff --git a/Host/Mod486/Speaker.odc b/Host/Mod486/Speaker.odc new file mode 100644 index 0000000..9719a46 Binary files /dev/null and b/Host/Mod486/Speaker.odc differ diff --git a/Host/Mod486/Unicode.odc b/Host/Mod486/Unicode.odc new file mode 100644 index 0000000..db81219 Binary files /dev/null and b/Host/Mod486/Unicode.odc differ diff --git a/Make486.sh b/Make486.sh new file mode 100755 index 0000000..4b87c48 --- /dev/null +++ b/Make486.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +cd Boot486 +./make.sh diff --git a/Run486.sh b/Run486.sh new file mode 100755 index 0000000..6985be4 --- /dev/null +++ b/Run486.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +cd Boot486 +./run.sh diff --git a/System/Mod486/Init.odc b/System/Mod486/Init.odc new file mode 100644 index 0000000..27fccbb Binary files /dev/null and b/System/Mod486/Init.odc differ diff --git a/System/Mod486/Kernel.odc b/System/Mod486/Kernel.odc new file mode 100644 index 0000000..0930a93 Binary files /dev/null and b/System/Mod486/Kernel.odc differ