summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhpa <hpa>2001-12-09 07:01:42 +0000
committerhpa <hpa>2001-12-09 07:01:42 +0000
commit8b77853436b60b3d4297d5eefd80f3d7a88d1e0c (patch)
tree56470d5ddb7d30789a3fb5a7b9a13e57b1000ba8
parent4a19e6aff7dcc8ff4db9d0ef350a681404dff93a (diff)
downloadsyslinux-8b77853436b60b3d4297d5eefd80f3d7a88d1e0c.tar.gz
Snapshot the work.
-rw-r--r--memdisk/Makefile16
-rw-r--r--memdisk/memdisk.asm64
-rw-r--r--memdisk/msetup.c122
3 files changed, 174 insertions, 28 deletions
diff --git a/memdisk/Makefile b/memdisk/Makefile
index 9eb73cf7..52b33f71 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 b175d711..46e19236 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 c37169be..907d8d3c 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));
+}