duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit 99a3401106e67987264a577ac9c42c9bb80112be
parent feb49ae3f486ce121c90a888b91ceeae589fca46
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Mon, 25 Jul 2022 21:39:05 -0400

i386: booting up to init.fs!

Diffstat:
MMakefile | 4++--
Mbuildpc.fs | 6++++++
Mfs/asm/i386.fs | 7+++++++
Afs/drv/pc/fdc.fs | 20++++++++++++++++++++
Afs/drv/pc/int13h.fs | 14++++++++++++++
Mfs/xcomp/i386.fs | 37++++++++++++++++++++++++++++++++++++-
Mfs/xcomp/pc/glue1.fs | 5++---
Afs/xcomp/pc/glue2.fs | 8++++++++
Afs/xcomp/pc/kernel.fs | 30++++++++++++++++++++++++++++++
Mfs/xcomp/pc/mbr.fs | 17++++++++---------
10 files changed, 133 insertions(+), 15 deletions(-)

diff --git a/Makefile b/Makefile @@ -29,14 +29,14 @@ pc.bin: dusk buildpc.fs pc.img: mbr.bin pc.bin dd if=/dev/zero of=$@ bs=1M count=1 # We need to reserve (-R) enough sectors for MBR + pc.bin - mformat -M 512 -d 1 -R 16 -i $@ :: + mformat -M 512 -d 1 -R 40 -i $@ :: dd if=mbr.bin of=$@ bs=1 seek=62 conv=notrunc dd if=pc.bin of=$@ bs=1 seek=512 conv=notrunc mcopy -sQ -i $@ fs/* :: .PHONY: pcrun pcrun: pc.img - qemu-system-i386 -drive file=pc.img,if=floppy,format=raw + qemu-system-i386 -drive file=pc.img,format=raw .PHONY: run run: dusk diff --git a/buildpc.fs b/buildpc.fs @@ -4,7 +4,13 @@ dup getc dup 0>= while stderr repeat ( fc c ) drop fclose ; 1 to fecho f<< /xcomp/i386.fs +f<< /xcomp/pc/kernel.fs +xbindict orgifydict org here org - spit spitfile<< /xcomp/bootlo.fs +spitfile<< /drv/pc/int13h.fs spitfile<< /xcomp/pc/glue1.fs +spitfile<< /fs/fatlo.fs +spitfile<< /xcomp/pc/glue2.fs +spitfile<< /xcomp/boothi.fs bye diff --git a/fs/asm/i386.fs b/fs/asm/i386.fs @@ -162,6 +162,7 @@ $c3 op ret, $90 op nop, $fa op cli, $fc op cld, $ac op lodsb, $ad op lods, $a6 op cmpsb, $a7 op cmps, $a4 op movsb, $a5 op movs, $f3 op repz, $f2 op repnz, $f3 op rep, +$9c op pushf, $9d op popf, $cf op iret, \ Jumps and relative addresses \ i386 jumps and calls in their immediate modes are relative. We keep it that @@ -247,6 +248,12 @@ $58 op pop, $50 op _push, op8b if $6a else $68 then c, imm, asm$ else _push, then ; +\ IN/OUT +: op ( op -- ) doer c, does> c@ ( opcode -- ) + opreg oprm and -1 = _assert + maybe8b imm? if c, imm, else 8 + c, then asm$ ; +$e4 op in, $e6 op out, + \ MOV has this special reg<-imm shortcut : mov, imm? if opmod 3 = if \ mov reg, imm shortcut diff --git a/fs/drv/pc/fdc.fs b/fs/drv/pc/fdc.fs @@ -0,0 +1,20 @@ +\ PC floppy disk controller driver + +\ get number of floppy drives from CMOS register $10 +$10 $70 pc! $71 pc@ dup $f and const FDSLAVETYPE 16 / const FDMASTERTYPE + +\ hardcode for 1.44M disks. + +2 const FDHEADS +80 const FDCYLCNT +18 const FDSECPERTRK +FDSECPERTRK FDHEADS * const FDSECPERCYL + +: lba>chs ( lba -- cyl head sec ) + dup FDSECPERCYL / ( lba cyl ) + over FDHEADS mod ( lba cyl head ) + rot FDSECPERCYL mod ( cyl head sec ) ; + +\ TODO finish this. I was set on starting with this driver because I thought +\ that my hardware treated boot USB key as a floppy, but it doesn't (master and +\ slave config from CMOS are both 0). I'll come back to floppies later. diff --git a/fs/drv/pc/int13h.fs b/fs/drv/pc/int13h.fs @@ -0,0 +1,14 @@ +\ Driver around int13h +\ This implements a read-only drive protocol over a +\ int13h ( drv head cyl sec dst ) word which must be implemented in the kernel. + +$200 const BIOSSECSZ +$7c18 w@ const SECPERTRK +$7c1a w@ const NUMHEADS +$7c24 c@ const DRVNO +$80 const DRVNO +SECPERTRK NUMHEADS * const SECPERCYL + +: biossec@ ( sec dst -- ) + >r DRVNO swap SECPERCYL /mod ( drv sec cyl ) + swap SECPERTRK /mod ( drv cyl sec head ) rot> 1+ r> int13h ; diff --git a/fs/xcomp/i386.fs b/fs/xcomp/i386.fs @@ -260,6 +260,16 @@ xcode >>c [ebp] setc, ret, +xcode lshift ( n u -- n ) + CX pspop, + [ebp] shlcl, + ret, + +xcode rshift ( n u -- n ) + CX pspop, + [ebp] shrcl, + ret, + xcode and AX pspop, [ebp] ax and, @@ -310,6 +320,19 @@ pc to lblcwrite \ al=c lblhere m) inc, ret, +xcode w@ + si [ebp] mov, + ax ax xor, + 16b! ax [esi] mov, + [ebp] ax mov, + ret, + +xcode w! + AX pspop, + BX pspop, + 16b! ax 0 d) bx mov, + ret, + xcode @ ax [ebp] mov, ax ax 0 d) mov, @@ -336,6 +359,19 @@ pc to lblwrite \ eax=n lblhere m) CELLSZ i) add, ret, +xcode pc@ ( port -- n ) + dx [ebp] mov, + ax ax xor, + 8b! in, + [ebp] ax mov, + ret, + +xcode pc! ( n port -- ) + DX pspop, + AX pspop, + 8b! out, + ret, + xcode move ( src dst u -- ) CX pspop, DI pspop, @@ -734,4 +770,3 @@ pc ( loop ) ( pc ) abs>rel jmp, pc lblbootptr pc>addr ! -xbindict orgifydict diff --git a/fs/xcomp/pc/glue1.fs b/fs/xcomp/pc/glue1.fs @@ -1,3 +1,2 @@ -: foo ." Hello World!" 5 >r begin r@ 'A' + emit next ; foo -bye - +BIOSSECSZ const drvblksz +alias biossec@ (drv@) diff --git a/fs/xcomp/pc/glue2.fs b/fs/xcomp/pc/glue2.fs @@ -0,0 +1,8 @@ +\ Glue code that goes between the filesystem part and boothi +alias fatopenlo fopen +alias fatchild fchild +0 S" drv" fchild S" pc" fchild S" int13h.fs" fchild floaded, +0 S" fs" fchild S" fatlo.fs" fchild floaded, +: foo ." Hello World!" ; foo +bye \ almost there! it *does* load init.fs, but this init.fs is written for the +\ POSIX Dusk. I have to reorganize how init.fs is placed in the final FS. diff --git a/fs/xcomp/pc/kernel.fs b/fs/xcomp/pc/kernel.fs @@ -0,0 +1,30 @@ +\ Extra native code cross-compiled into the kernel +\ For the PC platform, we need to fiddle with real mode/protected mode so that +\ we can use int13h to properly boot ourselves to init.fs + +pc to L1 \ back to protected mode! + ax $10 i) mov, ds ax mov, ss ax mov, es ax mov, gs ax mov, fs ax mov, + ret, + +pc to L2 1 to realmode \ we're in realmode + ax ax xor, es ax mov, + ax $0201 i) mov, $13 int, + \ we've done what we came for, let's go back to 32bit + ax cr0 mov, ax 1 i) or, cr0 ax mov, + $08 L1 jmpfar, + +pc to L1 \ segment with ffff limits + ax $20 i) mov, ds ax mov, ss ax mov, es ax mov, gs ax mov, fs ax mov, + ax cr0 mov, ax $fffffffe i) and, cr0 ax mov, + 0 L2 jmpfar, +0 to realmode + +xcode int13h ( drv head cyl sec dst -- ) pc lblcurrent pc>addr ! + BX pspop, + AX pspop, cl al mov, \ sec + AX pspop, ch al mov, \ cyl + AX pspop, dh al mov, \ head + AX pspop, dl al mov, \ drive + $18 L1 jmpfar, + +pc lblbootptr pc>addr ! diff --git a/fs/xcomp/pc/mbr.fs b/fs/xcomp/pc/mbr.fs @@ -12,11 +12,15 @@ forward8 jmp, to L1 \ bypass GDT pc to lblgdt \ Inspired by GNU grub at grub-core/kern/i386/realmode.S \ First entry (the null entry) is a reference to itself -$17 w, lblgdt , 0 w, -\ Code segment. base=0, limit=ffffff*4kb, present, execute/read, DPL=0 +$27 w, lblgdt , 0 w, +\ Code segment. base=0, limit=ffffff*4kb, present, 32bit, execute/read, DPL=0 $ffff w, 0 w, 0 c, $9a c, $cf c, 0 c, -\ Data segment. base=0, limit=ffffff*4kb, present, read/write, DPL=0 +\ Data segment. base=0, limit=ffffff*4kb, present, 32bit, read/write, DPL=0 $ffff w, 0 w, 0 c, $92 c, $cf c, 0 c, +\ Code segment. base=0, limit=ffff*1b, present, 32bit, execute/read, DPL=0 +$ffff w, 0 w, 0 c, $9a c, 0 c, 0 c, +\ Data segment. base=0, limit=ffff*1b, present, 32bit, read/write, DPL=0 +$ffff w, 0 w, 0 c, $92 c, 0 c, 0 c, L1 forward! cli, cld, lblgdt m) lgdt, ax $0003 i) mov, $10 int, \ video mode 80x25 @@ -28,11 +32,6 @@ bx $8000 i) mov, cx $0002 i) mov, dh 0 i) mov, $13 int, ax cr0 mov, ax 1 i) or, cr0 ax mov, $08 0 jmpfar, here org - binstart + here 4 - w! 0 to realmode \ initialize all segments -ax 16 i) mov, -ds ax mov, -ss ax mov, -es ax mov, -gs ax mov, -fs ax mov, +ax $10 i) mov, ds ax mov, ss ax mov, es ax mov, gs ax mov, fs ax mov, \ Jump to payload $08 $8000 jmpfar,