From 8b77853436b60b3d4297d5eefd80f3d7a88d1e0c Mon Sep 17 00:00:00 2001 From: hpa Date: Sun, 9 Dec 2001 07:01:42 +0000 Subject: [PATCH] Snapshot the work. --- memdisk/Makefile | 16 +++++-- memdisk/memdisk.asm | 64 ++++++++++++++++----------- memdisk/msetup.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 174 insertions(+), 28 deletions(-) diff --git a/memdisk/Makefile b/memdisk/Makefile index 9eb73cf..52b33f7 100644 --- a/memdisk/Makefile +++ b/memdisk/Makefile @@ -14,14 +14,17 @@ CC = gcc CFLAGS = -g -O2 -fomit-frame-pointer -march=i386 -malign-functions=0 -malign-jumps=0 -malign-loops=0 LDFLAGS = +AS = as +LD = ld +NASM = nasm -all: e820func.o16 msetup.o16 e820test +all: e820func.o16 msetup.o16 e820test memdisk.bin clean: - rm -f *.o *.s *.o16 *.s16 e820test + rm -f *.o *.s *.o16 *.s16 *.bin *.lst e820test %.o16: %.s16 - as -o $@ $< + $(AS) -o $@ $< %.s16: %.s echo '.code16' | cat - $< > $@ @@ -32,6 +35,11 @@ clean: %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< -e820test: e820func.o msetup.o e820test.o +%.bin: %.asm + $(NASM) -f bin -o $@ -l $*.lst $< + +e820test: e820func.o msetup.o e820test.o memdisk.o $(CC) $(LDFLAGS) -o $@ $^ +memdisk.o: memdisk.bin + $(LD) -r -b binary -o $@ $< diff --git a/memdisk/memdisk.asm b/memdisk/memdisk.asm index b175d71..46e1923 100644 --- a/memdisk/memdisk.asm +++ b/memdisk/memdisk.asm @@ -52,6 +52,13 @@ MyStack equ 1024 %define P_DI word [bp] section .text + ; These pointers are used by the installer and + ; must be first in the binary +Pointers: dw Int13Start + dw Int15Start + dw PatchArea + dw TotalSize + Int13Start: ; See if DL points to our class of device (FD, HD) push dx @@ -66,10 +73,10 @@ Int13Start: jmp far [OldInt13] .our_drive: - mov [cs:Stack],sp + mov [cs:Stack],esp mov [cs:SavedAX],ax mov ax,ss - mov [cs:Stack+2],ax + mov [cs:Stack+4],ax mov ax,cs mov ss,ax mov sp,MyStack @@ -93,12 +100,12 @@ Done: ; Standard routine for return cmp ah,1 DoneWeird: setnb al ; AL <- (AH > 0) ? 1 : 0 (CF) - lds bx,[Stack] ; DS:BX <- Old stack pointer - mov [bx+4],al ; Low byte of old FLAGS -> arithmetric flags + lds ebx,[Stack] ; DS:EBX <- Old stack pointer + mov [ebx+4],al ; Low byte of old FLAGS -> arithmetric flags popad pop es pop ds - lss sp,[cs:Stack] + lss esp,[cs:Stack] iret Reset: @@ -108,7 +115,7 @@ Reset: popad pop es pop ds - lss sp,[cs:Stack] + lss esp,[cs:Stack] and dl,80h ; Clear all but the type bit jmp far [OldInt13] @@ -356,6 +363,7 @@ bcopy: ret section .data + alignb 8 Int13Funcs dw Reset ; 00h - RESET dw GetStatus ; 01h - GET STATUS dw Read ; 02h - READ @@ -382,22 +390,6 @@ Int13Funcs dw Reset ; 00h - RESET Int13FuncsEnd equ $ Int13FuncsMax equ (Int13FuncsEnd-Int13Funcs) >> 1 -DriveNo db 0 ; Our drive number -DriveType db 0 ; Our drive type (floppies) -LastStatus db 0 ; Last return status - - alignb 4, db 0 -Cylinders dw 0 ; Cylinder count -Heads dw 0 ; Head count -Sectors dd 0 ; Sector count (zero-extended) -DiskSize dd 0 ; Size of disk in blocks -DiskBuf dd 0 ; Linear address of high memory disk - -E820Table dd 0 ; E820 table in high memory -Mem1MB dd 0 ; 1MB-16MB memory amount (1K) -Mem16MB dd 0 ; 16MB-4G memory amount (64K) -MemInt1588 dw 0 ; 1MB-65MB memory amount (1K) - alignb 8, db 0 Mover dd 0, 0, 0, 0 ; Must be zero dw 0ffffh ; 64 K segment size @@ -411,8 +403,32 @@ Mover_dst1: db 0, 0, 0 ; Low 24 bits of target addy Mover_dst2: db 0 ; High 8 bits of source addy section .bss + alignb 4 +PatchArea equ $ ; This gets filled in by the installer + +DriveNo resb 1 ; Our drive number +DriveType resb 1 ; Our drive type (floppies) +LastStatus resb 1 ; Last return status + resb 1 ; pad + +Cylinders resw 1 ; Cylinder count +Heads resw 1 ; Head count +Sectors resd 1 ; Sector count (zero-extended) +DiskSize resd 1 ; Size of disk in blocks +DiskBuf resd 1 ; Linear address of high memory disk + +E820Table resd 1 ; E820 table in high memory +Mem1MB resd 1 ; 1MB-16MB memory amount (1K) +Mem16MB resd 1 ; 16MB-4G memory amount (64K) +MemInt1588 resd 1 ; 1MB-65MB memory amount (1K) + OldInt13 resd 1 ; INT 13h in chain OldInt15 resd 1 ; INT 15h in chain -Stack resd 1 ; Saved SS:SP on invocation + + ; End patch area + +Stack resd 2 ; Saved SS:ESP on invocation E820Buf resd 6 ; E820 fetch buffer -SavedAX resw 1 ; AX saved during initialization +SavedAX resw 1 ; AX saved on invocation + +TotalSize equ $ ; End pointer diff --git a/memdisk/msetup.c b/memdisk/msetup.c index c37169b..907d8d3 100644 --- a/memdisk/msetup.c +++ b/memdisk/msetup.c @@ -181,3 +181,125 @@ void parse_mem(void) } } } + +extern const char _binary_memdisk_bin_start[], _binary_memdisk_bin_end[]; +extern const char _binary_memdisk_bin_size[]; /* Weird, I know */ +struct memdisk_header { + uint16_t int13_offs; + uint16_t int15_offs; + uint16_t patch_offs; + uint16_t total_size; +}; +struct patch_area { + uint8_t driveno; + uint8_t drivetype; + uint8_t laststatus; + uint8_t _pad1; + + uint16_t cylinders; + uint16_t heads; + uint32_t sectors; + uint32_t disksize; + uint32_t diskbuf; + + uint32_t e820table; + uint32_t mem1mb; + uint32_t mem16mb; + uint32_t memint1588; + + uint32_t oldint13; + uint32_t oldint15; + uint16_t olddosmem; +}; + +/* Access to objects in the zero page */ +static inline void +wrz_8(uint32_t addr, uint8_t data) +{ + asm volatile("movb %0,%%fs:%1" :: "ri" (data), "m" (*(uint8_t *)addr)); +} +static inline void +wrz_16(uint32_t addr, uint16_t data) +{ + asm volatile("movw %0,%%fs:%1" :: "ri" (data), "m" (*(uint16_t *)addr)); +} +static inline void +wrz_32(uint32_t addr, uint16_t data) +{ + asm volatile("movl %0,%%fs:%1" :: "ri" (data), "m" (*(uint32_t *)addr)); +} +static inline uint8_t +rdz_8(uint32_t addr) +{ + uint8_t data; + asm volatile("movb %%fs:%1,%0" : "=r" (data) : "m" (*(uint8_t *)addr)); + return data; +} +static inline uint16_t +rdz_16(uint32_t addr) +{ + uint16_t data; + asm volatile("movw %%fs:%1,%0" : "=r" (data) : "m" (*(uint16_t *)addr)); + return data; +} +static inline uint8_t +rdz_32(uint32_t addr) +{ + uint32_t data; + asm volatile("movl %%fs:%1,%0" : "=r" (data) : "m" (*(uint32_t *)addr)); + return data; +} + +/* Addresses in the zero page */ +#define BIOS_BASEMEM 0x413 /* Amount of DOS memory */ + +void setup(void) +{ + unsigned int size = (int) &_binary_memdisk_bin_size; + struct memdisk_header *hptr; + struct patch_area *pptr; + uint32_t old_dos_mem; + + /* Point %fs to the zero page */ + asm volatile("movw %0,%%fs" :: "r" (0)); + + get_mem(); + parse_mem(); + + /* Figure out where it needs to go */ + hptr = (struct memdisk_header *) &_binary_memdisk_bin_start; + pptr = (struct patch_area *)(_binary_memdisk_bin_start + hptr->patch_offs); + + if ( hptr->total_size > dos_mem ) { + /* Badness... */ + } + + old_dos_mem = dos_mem; + + dos_mem -= hptr->total_size; + dos_mem &= ~0x3FF; + + /* Reserve this range of memory */ + insertrange(dos_mem, old_dos_mem-dos_mem, 2); + parse_mem(); + + pptr->mem1mb = low_mem >> 10; + pptr->mem16mb = high_mem >> 16; + pptr->memint1588 = (low_mem == 0xf00000) + ? ((high_mem > 0x30ffc00) ? 0xffff : (high_mem >> 10)+0x3c00) + : (low_mem >> 10); + pptr->olddosmem = rdz_16(BIOS_BASEMEM); + wrz_16(BIOS_BASEMEM, dos_mem >> 10); + + /* ... patch other things ... */ + + /* Copy the driver into place */ + asm volatile("pushw %%es ; " + "movw %0,%%es ; " + "rep ; movsl %%ds:(%%si), %%es:(%%di) ; " + "popw %%es" + :: "r" ((uint16_t)(dos_mem >> 4)), + "c" (size >> 2), + "S" (&_binary_memdisk_bin_start), + "D" (0)); +} -- 2.7.4