Fix metal bugs so deathstar.com runs in qemu (#20)

- Remove XD bit in page tables
- Fix cylinder+head+sector arithmetic
- Implement fstat() for serial file descriptors on metal

Here's how to boot an Actually Portable Executable in QEMU:

    make -j12 o//tool/viz/deathstar.com
    qemu-system-x86_64 -serial stdio -fda o//tool/viz/deathstar.com

Here's a screenshot of DEATHSTAR.COM booted in QEMU:
https://justine.lol/cosmopolitan/cosmo-metal-qemu.png

Thus metal support is in much better shape now, but still incomplete.
Only a few system calls have been polyfilled. To figure out which ones
your program needs, simply boot it in the blinkenlights emulator with a
breakpoint, and press CTRL-C to continue to the system call breakpoint.
If it doesn't break then you should be good. (Note: to emulate normally
you can press 'c' and use CTRL-T and ALT-T to tune the speed.)

    m=tiny
    make -j12 SILENT=0 MODE=$m          \
      o/$m/tool/build/blinkenlights.com \
      o/$m/tool/viz/deathstar.com
    o/$m/tool/build/blinkenlights.com   \
      -r -t -b systemfive.linux         \
      o/$m/tool/viz/deathstar.com

Thank @Theldus for the bug report that made this change possible.
Fixes #20 which explains this change further.
This commit is contained in:
Justine Tunney 2021-01-16 17:52:15 -08:00
parent 58d9659d53
commit f0600a898c
13 changed files with 182 additions and 119 deletions

View file

@ -239,18 +239,17 @@ pc: cld
/ can have an understanding of physical locality, which deeply
/ impacts the latency of operations.
/
/ - 160KB: 1 head × 40 cylinders × 8 sectors × 512 = 163,840
/ - 180KB: 1 head × 40 cylinders × 9 sectors × 512 = 184,320
/ - 320KB: 2 heads × 40 cylinders × 8 sectors × 512 = 327,680
/ - 360KB: 2 heads × 40 cylinders × 9 sectors × 512 = 368,640
/ - 720KB: 2 heads × 80 cylinders × 9 sectors × 512 = 737,280
/ - 1.2MB: 2 heads × 80 cylinders × 15 sectors × 512 = 1,228,800
/ - 1.44MB: 2 heads × 80 cylinders × 18 sectors × 512 = 1,474,560
/ - 160KB: 40 cylinders × 1 head × 8 sectors × 512 = 163,840
/ - 180KB: 40 cylinders × 1 head × 9 sectors × 512 = 184,320
/ - 320KB: 40 cylinders × 2 heads × 8 sectors × 512 = 327,680
/ - 360KB: 40 cylinders × 2 heads × 9 sectors × 512 = 368,640
/ - 720KB: 80 cylinders × 2 heads × 9 sectors × 512 = 737,280
/ - 1.2MB: 80 cylinders × 2 heads × 15 sectors × 512 = 1,228,800
/ - 1.44MB: 80 cylinders × 2 heads × 18 sectors × 512 = 1,474,560
/
/ Terminology
/
/ - Cylinder / Tracks should mean the same thing
/ - Heads / Sides / Spindles should mean the same thing
/ - Heads are also known as Tracks
/
/ Disk Base Table
/
@ -341,18 +340,18 @@ pcread: push %ax
pop %cx
pop %ax
jc 9f
mov %es,%si
mov %es,%si # addr += 512
add $512>>4,%si
mov %si,%es
inc %al
inc %al # ++sector
cmp XLM(DRIVE_LAST_SECTOR),%al
jbe 2f
mov $1,%al
inc %cx
cmp XLM(DRIVE_LAST_CYLINDER),%cx
jbe 2f
xor %cx,%cx
inc %dh
inc %dh # ++head
cmp XLM(DRIVE_LAST_HEAD),%cx
jb 2f
xor %dh,%dh
inc %cx # ++cylinder
2: ret
9: push %ax
xor %ax,%ax # try disk reset on error

View file

@ -30,7 +30,7 @@ textreal static void __map_segment(uint64_t k, uint64_t a, uint64_t b) {
textreal void __map_image(void) {
__map_segment(PAGE_V | PAGE_U, 0, (uintptr_t)_etext - IMAGE_BASE_VIRTUAL);
__map_segment(PAGE_V | PAGE_U | PAGE_RW | PAGE_XD,
__map_segment(PAGE_V | PAGE_U | PAGE_RW,
(uintptr_t)_etext - IMAGE_BASE_VIRTUAL,
(uintptr_t)_end - IMAGE_BASE_VIRTUAL);
}