summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhpa <hpa>2001-12-11 09:20:18 +0000
committerhpa <hpa>2001-12-11 09:20:18 +0000
commit24612a86668be7a66deabe2644804c5a6e3370ad (patch)
treedbaf4e940ced39b76485d257f78d3e126da5b1e3
parent7de02ddf8887f37a5e3c0f810cbf45ac7029c165 (diff)
downloadsyslinux-24612a86668be7a66deabe2644804c5a6e3370ad.tar.gz
Checkpoint: many many changes, now successfully loads the
target OS bootsector, but then fails at a later point.
-rw-r--r--memdisk/e820func.c3
-rw-r--r--memdisk/init.S164
-rw-r--r--memdisk/memdisk.asm125
-rw-r--r--memdisk/setup.c51
4 files changed, 110 insertions, 73 deletions
diff --git a/memdisk/e820func.c b/memdisk/e820func.c
index d9c8465a..4d0ec150 100644
--- a/memdisk/e820func.c
+++ b/memdisk/e820func.c
@@ -30,7 +30,8 @@ void e820map_init(void)
{
nranges = 1;
asm volatile("cld ; rep ; stosl %0,%%es:(%1)"
- :: "a" (0), "S" (ranges), "c" (sizeof(ranges) >> 2));
+ :: "a" (0), "D" (ranges), "c" (sizeof(ranges) >> 2)
+ : "edi", "ecx");
ranges[1].type = -1;
}
diff --git a/memdisk/init.S16 b/memdisk/init.S16
index 955e8726..2e87d1dc 100644
--- a/memdisk/init.S16
+++ b/memdisk/init.S16
@@ -72,11 +72,7 @@ setup_move_size: .word 0 # Unused
code32_start: # here loaders can put a different
# start address for 32-bit code.
-#ifndef __BIG_KERNEL__
- .long 0x1000 # 0x1000 = default for zImage
-#else
.long 0x100000 # 0x100000 = default for big kernel
-#endif
ramdisk_image: .long 0 # address of loaded ramdisk image
# Here the loader puts the 32-bit
diff --git a/memdisk/memdisk.asm b/memdisk/memdisk.asm
index ddaf100b..6688f0ec 100644
--- a/memdisk/memdisk.asm
+++ b/memdisk/memdisk.asm
@@ -22,8 +22,6 @@
%define SECTORSIZE_LG2 9 ; log2(sector size)
%define SECTORSIZE (1 << SECTORSIZE_LG2)
-MyStack equ 1024
-
; Parameter registers definition; this is the definition
; of the stack frame.
%define P_DS word [bp+34]
@@ -65,12 +63,12 @@ Int13Start:
xor dl,[cs:DriveNo]
pop dx
js .nomatch ; If SF=0, we have a match here
+ jz .our_drive ; If ZF=1, we have an exact match
cmp dl,[cs:DriveNo]
- je .our_drive
jb .nomatch ; Drive < Our drive
dec dl ; Drive > Our drive, adjust drive #
.nomatch:
- jmp far [OldInt13]
+ jmp far [cs:OldInt13]
.our_drive:
mov [cs:Stack],esp
@@ -79,33 +77,36 @@ Int13Start:
mov [cs:Stack+4],ax
mov ax,cs
mov ss,ax
- mov sp,MyStack
+ mov sp,[cs:MyStack]
push ds
push es
mov ds,ax
mov es,ax
mov ax,[SavedAX]
pushad
- mov bp,sp
+ mov bp,sp ; Point BP to the entry stack frame
cmp ah,Int13FuncsMax
jae Invalid
xor al,al ; AL = 0 is standard entry condition
mov di,ax
- shr di,7
+ shr di,7 ; Convert AH to an offset in DI
call [Int13Funcs+di]
Done: ; Standard routine for return
- mov [LastStatus],ah
mov P_AX,ax
- cmp ah,1
DoneWeird:
- setnb al ; AL <- (AH > 0) ? 1 : 0 (CF)
- lds ebx,[Stack] ; DS:EBX <- Old stack pointer
- mov [ebx+4],al ; Low byte of old FLAGS -> arithmetric flags
+ mov [LastStatus],ah
+ and ah,ah
+
popad
pop es
pop ds
lss esp,[cs:Stack]
+
+ ; This sets the low byte (the arithmetric flags) of the
+ ; FLAGS on stack to either 00h (no flags) or 01h (CF)
+ ; depending on if AH was zero or not.
+ setnz [esp+4] ; Set CF iff error
iret
Reset:
@@ -117,14 +118,13 @@ Reset:
pop ds
lss esp,[cs:Stack]
and dl,80h ; Clear all but the type bit
- jmp far [OldInt13]
+ jmp far [cs:OldInt13]
Invalid:
mov ax,0100h ; Unsupported function
ret
GetDriveType:
- pop ax ; Drop return address
mov ah,[DriveNo]
shr ah,7
pushf
@@ -137,21 +137,14 @@ GetDriveType:
mov ax,[DiskSize+2]
mov P_CX,ax
.floppy:
- mov [LastStatus],byte 0 ; Success, but AH returns a value
- jmp short DoneWeird
+ pop ax ; Drop return address
+ xor ax,ax ; Success...
+ jmp short DoneWeird ; But don't stick it into P_AX
GetStatus:
mov ah,[LastStatus] ; Copy last status
ret
-CheckIfReady: ; These are always-successful noop functions
-Recalibrate:
-InitWithParms:
-DetectChange:
-success:
- xor ax,ax ; Always successful
- ret
-
Read:
call setup_regs
do_copy:
@@ -161,7 +154,7 @@ do_copy:
Write:
call setup_regs
- xchg esi,edi
+ xchg esi,edi ; Opposite direction of a Read!
jmp short do_copy
; These verify one sector only
@@ -171,7 +164,15 @@ Seek:
; Verify integrity; just bounds-check
Verify:
call setup_regs ; Returns error if appropriate
- jmp short success
+ ; And fall through to success
+
+CheckIfReady: ; These are always-successful noop functions
+Recalibrate:
+InitWithParms:
+DetectChange:
+success:
+ xor ax,ax ; Always successful
+ ret
GetParms:
; We need to get the "number of drives" from the BIOS
@@ -197,44 +198,46 @@ GetParms:
xor ax,ax
ret
- ; Convert a CHS address in CX/DH into an LBA in EAX
-chstolba:
- xor ebx,ebx
- mov bl,cl ; Sector number
+ ; Set up registers as for a "Read", and compares against disk size
+setup_regs:
+
+ ; Convert a CHS address in P_CX/P_DH into an LBA in eax
+ ; CH = cyl[7:0]
+ ; CL[0:5] = sector (1-based) CL[7:6] = cyl[9:8]
+ ; DH = head
+ movzx ecx,P_CX
+ movzx ebx,cl ; Sector number
and bl,3Fh
- dec bx
- mov si,dx
- mov ax,[Heads]
+ dec ebx ; Sector number is 1-based
+ movzx edi,P_DH ; Head number
+ movzx eax,word [Heads]
shr cl,6
xchg cl,ch ; Now CX <- cylinder number
- mul cx ; DX:AX <- AX*CX
- shr si,8 ; SI <- head number
- add ax,si
- adc dx,byte 0
- shl edx,16
- or eax,edx
+ mul ecx ; eax <- Heads*cyl# (edx <- 0)
+ add eax,edi
mul dword [Sectors]
add eax,ebx
- ret
-
- ; Set up registers as for a "Read", and compares against disk size
-setup_regs:
- call chstolba
- movzx edi,P_BX ; Get linear address of target buffer
- movzx ecx,P_ES
- shr ecx,4
- add edi,ecx
- movzx ecx,P_AL
- lea ebx,[eax+ecx]
+ ; Now eax = LBA
+
+ ;
+ ; setup_regs continues...
+ ;
+ ; Note: edi[31:16] and ecx[31:16] = 0 already
+ mov di,P_BX ; Get linear address of target buffer
+ mov cx,P_ES
+ shl ecx,4
+ add edi,ecx ; EDI = address to fetch to
+ movzx ecx,P_AL ; Sector count
mov esi,eax
- shr esi,SECTORSIZE_LG2
- add esi,[DiskBuf]
- cmp ebx,[DiskSize]
- jae .overrun
- shr ecx,SECTORSIZE_LG2-1
+ add eax,ecx
+ shl esi,SECTORSIZE_LG2
+ add esi,[DiskBuf] ; Get address in high memory
+ cmp eax,[DiskSize] ; Check the high mark against limit
+ ja .overrun
+ shl ecx,SECTORSIZE_LG2-1 ; Convert count to 16-bit words
ret
-.overrun: pop ax ; Drop return address
+.overrun: pop ax ; Drop setup_regs return address
mov ax,0400h ; Sector not found
ret
@@ -252,6 +255,10 @@ int15_e820:
mov ebx,E820Table
.renew:
add bx, byte 12 ; Advance to next
+ mov eax,[bx-4] ; Type
+ and eax,eax ; Null type?
+ jz .renew ; If so advance to next
+ mov [es:di+16],eax
mov eax,[bx-12] ; Start addr (low)
mov [es:di],eax
mov ecx,[bx-8] ; Start addr (high)
@@ -262,8 +269,6 @@ int15_e820:
sbb ecx,[bx-8]
mov [es:di+8],eax ; Length (low)
mov [es:di+12],ecx ; Length (high)
- mov eax,[bx-4] ; Type
- mov [es:di+16],eax
cmp dword [bx+8], byte -1 ; Type of next = end?
jne .notdone
xor ebx,ebx ; Done with table
@@ -401,6 +406,7 @@ Mover_src1: db 0, 0, 0 ; Low 24 bits of source addy
db 93h ; Access rights
db 00h ; Extended access rights
Mover_src2: db 0 ; High 8 bits of source addy
+ dw 0ffffh ; 64 K segment size
Mover_dst1: db 0, 0, 0 ; Low 24 bits of target addy
db 93h ; Access rights
db 00h ; Extended access rights
@@ -429,6 +435,9 @@ OldDosMem dw 0 ; Old position of DOS mem end
DriveNo db 0 ; Our drive number
DriveType db 0 ; Our drive type (floppies)
+MyStack dw 0 ; Offset of stack
+ dw 0 ; Padding
+
; End patch area
Stack dd 0 ; Saved SS:ESP on invocation
diff --git a/memdisk/setup.c b/memdisk/setup.c
index a2e71fba..d2cec95b 100644
--- a/memdisk/setup.c
+++ b/memdisk/setup.c
@@ -43,6 +43,8 @@ struct patch_area {
uint8_t driveno;
uint8_t drivetype;
+
+ uint16_t mystack;
};
/* This is the header in the boot sector/setup area */
@@ -105,7 +107,7 @@ rdz_16(uint32_t addr)
asm volatile("movw %%fs:%1,%0" : "=r" (data) : "m" (*(uint16_t *)addr));
return data;
}
-static inline uint8_t
+static inline uint32_t
rdz_32(uint32_t addr)
{
uint32_t data;
@@ -181,6 +183,8 @@ void __attribute__((noreturn)) die(void)
asm volatile("hlt");
}
+#define STACK_NEEDED 128 /* Number of bytes of stack */
+
/*
* Actual setup routine
* Returns the drive number (which is then passed in %dl to the
@@ -215,8 +219,17 @@ uint32_t setup(void)
geometry = get_disk_image_geometry(shdr->ramdisk_image, shdr->ramdisk_size);
+ printf("Disk is %s, %u K, C/H/S = %u/%u/%u\n",
+ geometry->driveno ? "hard disk" : "floppy",
+ geometry->sectors >> 1,
+ geometry->c, geometry->h, geometry->s);
+
+
+ puts("e820map_init ");
e820map_init(); /* Initialize memory data structure */
+ puts("get_mem ");
get_mem(); /* Query BIOS for memory map */
+ puts("parse_mem\n");
parse_mem(); /* Parse memory map */
printf("dos_mem = %#10x (%u K)\n"
@@ -251,7 +264,7 @@ uint32_t setup(void)
2 additional ranges plus the terminating range, over what
nranges currently show. */
- total_size = hptr->total_size + (nranges+3)*12;
+ total_size = hptr->total_size + (nranges+3)*12 + STACK_NEEDED;
printf("Total size needed = %u bytes\n", total_size);
if ( total_size > dos_mem ) {
@@ -262,10 +275,14 @@ uint32_t setup(void)
driveraddr = stddosmem - total_size;
driveraddr &= ~0x3FF;
+ /* Anything beyond the end is for the stack */
+ pptr->mystack = (uint16_t)(stddosmem-driveraddr);
+
printf("Old dos memory at 0x%05x (map says 0x%05x), loading at 0x%05x\n",
stddosmem, dos_mem, driveraddr);
/* Reserve this range of memory */
+ wrz_16(BIOS_BASEMEM, driveraddr >> 10);
insertrange(driveraddr, dos_mem-driveraddr, 2);
parse_mem();
@@ -281,8 +298,13 @@ uint32_t setup(void)
pptr->oldint13 = rdz_32(BIOS_INT13);
pptr->oldint15 = rdz_32(BIOS_INT15);
- /* Claim the memory and copy the driver into place */
- wrz_16(BIOS_BASEMEM, dos_mem >> 10);
+ /* Adjust the E820 table: if there are null ranges (type 0)
+ at the end, change them to type end of list (-1).
+ This is necessary for the driver to be able to report end
+ of list correctly. */
+ while ( nranges && ranges[nranges-1].type == 0 ) {
+ ranges[--nranges].type = -1;
+ }
/* Copy driver followed by E820 table */
asm volatile("pushw %%es ; "
@@ -294,16 +316,23 @@ uint32_t setup(void)
"rep ; movsl %%ds:(%%si), %%es:(%%di) ; "
"popw %%es"
:: "r" (driverseg),
- "g" ((uint16_t)((nranges+1)*3)), /* 3 dwords/range */
- "g" ((uint16_t)ranges),
+ "r" ((uint16_t)((nranges+1)*3)), /* 3 dwords/range */
+ "r" ((uint16_t)ranges),
"c" (bin_size >> 2),
"S" (&_binary_memdisk_bin_start),
- "D" (0));
+ "D" (0)
+ : "esi", "edi", "ecx");
/* Install the interrupt handlers */
+ printf("old: int13 = %08x int15 = %08x\n",
+ rdz_32(BIOS_INT13), rdz_32(BIOS_INT15));
+
wrz_32(BIOS_INT13, driverptr+hptr->int13_offs);
wrz_32(BIOS_INT15, driverptr+hptr->int15_offs);
+ printf("new: int13 = %08x int15 = %08x\n",
+ rdz_32(BIOS_INT13), rdz_32(BIOS_INT15));
+
/* Reboot into the new "disk" */
asm volatile("pushw %%es ; "
"xorw %%cx,%%cx ; "
@@ -312,9 +341,9 @@ uint32_t setup(void)
"movw $0x0201,%%ax ; "
"movw $0x7c00,%%bx ; "
"int $0x13 ; "
- "setc %0 ; "
- "popw %%es"
- : "=r" (status), "=a" (exitcode)
+ "popw %%es ; "
+ "setc %0 "
+ : "=rm" (status), "=a" (exitcode)
: "d" ((uint16_t)driveno)
: "ebx", "ecx", "edx", "esi", "edi", "ebp");
@@ -323,6 +352,8 @@ uint32_t setup(void)
die();
}
+ puts("Booting...\n");
+
/* On return the assembly code will jump to the boot vector */
return driveno;
}