Made realloc work; the 32-bit process can now be resized to include bss and
stack.
This commit is contained in:
parent
967b46e98e
commit
1764c6baa2
|
@ -13,57 +13,73 @@
|
||||||
.sect .text
|
.sect .text
|
||||||
#define STACK_BUFFER 128 /* number of bytes to leave for stack */
|
#define STACK_BUFFER 128 /* number of bytes to leave for stack */
|
||||||
|
|
||||||
|
! g 18b to break at the retf before coming here
|
||||||
begtext:
|
begtext:
|
||||||
mov eax, 0x4c00
|
! On entry, the stub has cs and ds pointing at the 32-bit
|
||||||
int 0x21
|
! segment, but ss is still pointing at the 16-bit segment.
|
||||||
|
|
||||||
! Make sure we are running under MS-DOS 2 or above.
|
|
||||||
!
|
!
|
||||||
! While at it, also remember the actual DOS version, so that we know
|
! si:di memory handle of linear block
|
||||||
! whether DOS gives us the program's name in the environment
|
! ax: pmode code segment of stub
|
||||||
! segment. (DOS 3+ does; DOS 2.x does not.)
|
! dx: pointer to realloc routine
|
||||||
movb ah, 0x30
|
! fs: data segment (just a clone of the code segment)
|
||||||
int 0x21
|
|
||||||
cbw
|
|
||||||
cmpb al, 2
|
|
||||||
xchg bp, ax
|
|
||||||
jnc ok_sys
|
|
||||||
|
|
||||||
mov dx, bad_sys_msg
|
! Resize the segment to include the BSS.
|
||||||
dos_msg:
|
|
||||||
ret
|
|
||||||
|
|
||||||
ok_sys:
|
o16 cseg mov (realloc_ptr+4), ax
|
||||||
! Resize the program's memory control block (MCB) to cover only the
|
cseg mov (realloc_ptr+0), edx
|
||||||
! program's near code and data space. Use the starting sp value as
|
mov eax, endbss
|
||||||
! a guide to how much memory we can grab. Abort on any failure.
|
cseg callf (realloc_ptr)
|
||||||
!
|
|
||||||
! As a side effect, this also frees up any memory allocated to our
|
|
||||||
! program beyond 64 KiB. (The freed memory can possibly be used by
|
|
||||||
! e.g. child processes, in the future.)
|
|
||||||
!
|
|
||||||
! Also check that we have some space between the BSS end and the
|
|
||||||
! starting sp.
|
|
||||||
cmp sp, endbss+STACK_BUFFER
|
|
||||||
jb no_room
|
|
||||||
|
|
||||||
movb ah, 0x4a
|
|
||||||
mov bx, sp
|
|
||||||
movb cl, 4
|
|
||||||
shr bx, cl
|
|
||||||
inc bx
|
|
||||||
int 0x21
|
|
||||||
jc no_room
|
|
||||||
|
|
||||||
! Clear BSS.
|
! Clear BSS.
|
||||||
mov di, begbss
|
|
||||||
mov cx, endbss+1
|
mov edi, begbss
|
||||||
sub cx, di
|
mov ecx, endbss+1
|
||||||
shr cx, 1
|
sub ecx, edi
|
||||||
xor ax, ax
|
shr ecx, 1
|
||||||
|
xor eax, eax
|
||||||
cld
|
cld
|
||||||
rep stosw
|
rep stosw
|
||||||
|
|
||||||
|
! It's now safe to switch stacks.
|
||||||
|
|
||||||
|
cli
|
||||||
|
mov eax, ds
|
||||||
|
mov ss, eax
|
||||||
|
mov sp, .stack
|
||||||
|
sti
|
||||||
|
|
||||||
|
! Create a handle for low 1MB access.
|
||||||
|
|
||||||
|
o16 mov ax, 0x0000
|
||||||
|
o16 mov cx, 1
|
||||||
|
int 0x31 ! allocate LDT
|
||||||
|
mov es, ax
|
||||||
|
o16 mov bx, ax
|
||||||
|
o16 mov (.doshandle), bx
|
||||||
|
|
||||||
|
xor ecx, ecx
|
||||||
|
xor edx, edx
|
||||||
|
o16 mov ax, 0x0007
|
||||||
|
int 0x31 ! set base address to 0
|
||||||
|
o16 mov cx, 0x0010
|
||||||
|
o16 mov ax, 0x0008
|
||||||
|
int 0x31 ! set limit to 1MB
|
||||||
|
|
||||||
|
mov cx, ds
|
||||||
|
and cx, 3
|
||||||
|
shl cx, 5
|
||||||
|
or cx, 0xc093 ! 32-bit, big, data, r/w, expand-up
|
||||||
|
mov ax, 0x0009
|
||||||
|
int 0x31 ! set descriptor access rights
|
||||||
|
|
||||||
|
! Locate the PSP.
|
||||||
|
|
||||||
|
movb ah, 0x62
|
||||||
|
int 0x21
|
||||||
|
movzx ebx, bx
|
||||||
|
shl ebx, 4 ! convert to linear address
|
||||||
|
mov (.psp), ebx
|
||||||
|
|
||||||
! Get the size of the environment variables plus (if present) the
|
! Get the size of the environment variables plus (if present) the
|
||||||
! program name. Also count the number of environment variables.
|
! program name. Also count the number of environment variables.
|
||||||
xor di, di
|
xor di, di
|
||||||
|
@ -130,7 +146,7 @@ copy_env:
|
||||||
|
|
||||||
no_room:
|
no_room:
|
||||||
mov dx, no_room_msg
|
mov dx, no_room_msg
|
||||||
call dos_msg
|
!call dos_msg
|
||||||
movb al, -1
|
movb al, -1
|
||||||
jmp al_exit
|
jmp al_exit
|
||||||
|
|
||||||
|
@ -147,6 +163,11 @@ al_exit:
|
||||||
movb ah, 0x4c
|
movb ah, 0x4c
|
||||||
int 0x21
|
int 0x21
|
||||||
|
|
||||||
|
! This must be in the code segment due to bootstrap issues.
|
||||||
|
realloc_ptr:
|
||||||
|
.data2 0
|
||||||
|
.data4 0
|
||||||
|
|
||||||
! Define symbols at the beginning of our various segments, so that we can find
|
! Define symbols at the beginning of our various segments, so that we can find
|
||||||
! them. (Except .text, which has already been done.)
|
! them. (Except .text, which has already been done.)
|
||||||
|
|
||||||
|
@ -168,5 +189,12 @@ no_room_msg: .ascii 'No room$'
|
||||||
.comm .ignmask, 4
|
.comm .ignmask, 4
|
||||||
.comm _errno, 4
|
.comm _errno, 4
|
||||||
|
|
||||||
|
.comm .doshandle, 2
|
||||||
|
.comm .psp, 4
|
||||||
|
|
||||||
|
.sect .bss
|
||||||
|
.space 512
|
||||||
|
.stack:
|
||||||
|
|
||||||
! vim: ts=4 sw=4 et ft=asm
|
! vim: ts=4 sw=4 et ft=asm
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ name as
|
||||||
program {EM}/lib/ack/{PLATFORM}/as
|
program {EM}/lib/ack/{PLATFORM}/as
|
||||||
args - -o > <
|
args - -o > <
|
||||||
prep cond
|
prep cond
|
||||||
|
|
||||||
end
|
end
|
||||||
name led
|
name led
|
||||||
from .o.a
|
from .o.a
|
||||||
|
@ -66,6 +67,7 @@ name led
|
||||||
{PLATFORMDIR}/libc.a \
|
{PLATFORMDIR}/libc.a \
|
||||||
{PLATFORMDIR}/libem.a \
|
{PLATFORMDIR}/libem.a \
|
||||||
{PLATFORMDIR}/libend.a)
|
{PLATFORMDIR}/libend.a)
|
||||||
|
|
||||||
linker
|
linker
|
||||||
end
|
end
|
||||||
name cv
|
name cv
|
||||||
|
|
|
@ -51,6 +51,7 @@ exe_start:
|
||||||
xor di, di
|
xor di, di
|
||||||
xorb al, al
|
xorb al, al
|
||||||
mov cx, 0xffff
|
mov cx, 0xffff
|
||||||
|
cld
|
||||||
1:
|
1:
|
||||||
repne scasb ! find end of next string
|
repne scasb ! find end of next string
|
||||||
eseg cmpb (di), 0
|
eseg cmpb (di), 0
|
||||||
|
@ -90,8 +91,8 @@ exe_start:
|
||||||
xor cx, cx ! high offset
|
xor cx, cx ! high offset
|
||||||
xor dx, dx ! low offset
|
xor dx, dx ! low offset
|
||||||
int 0x21 ! lseek
|
int 0x21 ! lseek
|
||||||
mov (textlen+0), ax
|
mov (pmemlen+0), ax
|
||||||
mov (textlen+2), dx
|
mov (pmemlen+2), dx
|
||||||
|
|
||||||
! Initialise DPMI.
|
! Initialise DPMI.
|
||||||
|
|
||||||
|
@ -115,7 +116,7 @@ exe_start:
|
||||||
callf (pmode_switch)
|
callf (pmode_switch)
|
||||||
jc bad_dpmi
|
jc bad_dpmi
|
||||||
|
|
||||||
! We're now in protected mode. (0xa9)
|
! We're now in protected mode. (ae)
|
||||||
|
|
||||||
mov (psegcs), cs
|
mov (psegcs), cs
|
||||||
mov (psegds), ds
|
mov (psegds), ds
|
||||||
|
@ -127,14 +128,15 @@ exe_start:
|
||||||
int 0x31 ! allocate LDT
|
int 0x31 ! allocate LDT
|
||||||
jc bad_dpmi
|
jc bad_dpmi
|
||||||
mov es, ax
|
mov es, ax
|
||||||
|
mov (psegcs32), ax
|
||||||
|
|
||||||
mov cx, (textlen+0)
|
mov cx, (pmemlen+0)
|
||||||
mov bx, (textlen+2)
|
mov bx, (pmemlen+2)
|
||||||
mov ax, 0x0501
|
mov ax, 0x0501
|
||||||
int 0x31 ! allocate linear address
|
int 0x31 ! allocate linear address
|
||||||
jc bad_dpmi
|
jc bad_dpmi
|
||||||
mov (pmemhandle+0), si
|
mov (pmemhandle+0), di
|
||||||
mov (pmemhandle+2), di
|
mov (pmemhandle+2), si
|
||||||
|
|
||||||
mov dx, cx
|
mov dx, cx
|
||||||
mov cx, bx
|
mov cx, bx
|
||||||
|
@ -144,8 +146,8 @@ exe_start:
|
||||||
jc bad_dpmi
|
jc bad_dpmi
|
||||||
|
|
||||||
mov bx, es
|
mov bx, es
|
||||||
mov dx, (textlen+0)
|
mov dx, (pmemlen+0)
|
||||||
mov cx, (textlen+2)
|
mov cx, (pmemlen+2)
|
||||||
mov ax, 0x0008
|
mov ax, 0x0008
|
||||||
int 0x31 ! set segment limit
|
int 0x31 ! set segment limit
|
||||||
|
|
||||||
|
@ -157,7 +159,23 @@ exe_start:
|
||||||
mov ax, 0x0009
|
mov ax, 0x0009
|
||||||
int 0x31 ! set descriptor access rights
|
int 0x31 ! set descriptor access rights
|
||||||
|
|
||||||
! Load the program. (0xff)
|
! Allocate the data segment (as a simple clone of the code segment). (10e)
|
||||||
|
|
||||||
|
mov ax, 0x000a
|
||||||
|
mov bx, es
|
||||||
|
int 0x31
|
||||||
|
mov fs, ax
|
||||||
|
mov (psegds32), ax
|
||||||
|
|
||||||
|
mov cx, ax
|
||||||
|
and cx, 3
|
||||||
|
shl cx, 5
|
||||||
|
or cx, 0xc093 ! 32-bit, big, data, r/w, expand-up
|
||||||
|
mov bx, fs
|
||||||
|
mov ax, 0x0009
|
||||||
|
int 0x31 ! set descriptor access rights
|
||||||
|
|
||||||
|
! Load the program.
|
||||||
|
|
||||||
mov bx, (fh)
|
mov bx, (fh)
|
||||||
mov ax, 0x4200
|
mov ax, 0x4200
|
||||||
|
@ -179,6 +197,7 @@ exe_start:
|
||||||
|
|
||||||
o32 movzx ecx, ax ! number of bytes read
|
o32 movzx ecx, ax ! number of bytes read
|
||||||
o32 mov esi, transfer_buffer
|
o32 mov esi, transfer_buffer
|
||||||
|
cld
|
||||||
o32 rep movsb
|
o32 rep movsb
|
||||||
jmp 1b
|
jmp 1b
|
||||||
2:
|
2:
|
||||||
|
@ -191,12 +210,75 @@ exe_start:
|
||||||
|
|
||||||
! Jump to the new segment and enter 32-bit mode!
|
! Jump to the new segment and enter 32-bit mode!
|
||||||
|
|
||||||
o32 mov eax, (pmemhandle)
|
mov ax, (psegcs)
|
||||||
o32 movzx ebx, (rseg)
|
mov bx, (psegds)
|
||||||
|
mov cx, (rseg)
|
||||||
|
o32 mov edx, realloc
|
||||||
|
push es
|
||||||
|
pop ds
|
||||||
push es
|
push es
|
||||||
push 0
|
push 0
|
||||||
retf
|
retf
|
||||||
|
|
||||||
|
! ALL CODE ABOVE THIS POINT DISCARDED ON ENTRY TO 32-BIT CODE
|
||||||
|
! (it's reused as the 16-bit stack)
|
||||||
|
stack16:
|
||||||
|
|
||||||
|
! Helper routine which reallocates the linear block that the 32-bit code
|
||||||
|
! is running from. This can't happen from inside the 32-bit code itself
|
||||||
|
! because it might move.
|
||||||
|
!
|
||||||
|
! On entry, ds and ss are ignored. On exit, ds is set to the 32-bit segment.
|
||||||
|
! eax: new block size
|
||||||
|
realloc:
|
||||||
|
cseg mov ds, (psegds)
|
||||||
|
cli ! atomically switch stacks
|
||||||
|
o32 mov (dpmi_ebp), esp ! yes, saving esp into the ebp field
|
||||||
|
mov (dpmi_ss), ss
|
||||||
|
mov ss, (psegds)
|
||||||
|
mov sp, stack16
|
||||||
|
sti
|
||||||
|
pusha
|
||||||
|
|
||||||
|
o32 add eax, 1024*1024 - 1
|
||||||
|
o32 and eax, ~[1024*1024 - 1]
|
||||||
|
o32 mov (pmemlen), eax
|
||||||
|
mov cx, (pmemlen+0)
|
||||||
|
mov bx, (pmemlen+2)
|
||||||
|
mov di, (pmemhandle+0)
|
||||||
|
mov si, (pmemhandle+2)
|
||||||
|
mov ax, 0x0503
|
||||||
|
int 0x31 ! resize memory block
|
||||||
|
jc bad_dpmi
|
||||||
|
mov (pmemhandle+0), di
|
||||||
|
mov (pmemhandle+2), si
|
||||||
|
mov (pmemaddr+0), cx
|
||||||
|
mov (pmemaddr+2), bx
|
||||||
|
|
||||||
|
mov bx, (psegds32)
|
||||||
|
mov dx, (pmemlen+0)
|
||||||
|
mov cx, (pmemlen+2)
|
||||||
|
mov ax, 0x0008
|
||||||
|
int 0x31 ! set ds segment limit
|
||||||
|
jc bad_dpmi
|
||||||
|
mov dx, (pmemaddr+0)
|
||||||
|
mov cx, (pmemaddr+2)
|
||||||
|
mov ax, 0x0007
|
||||||
|
int 0x31 ! set ds linear address
|
||||||
|
jc bad_dpmi
|
||||||
|
mov bx, (psegcs32)
|
||||||
|
int 0x31 ! set cs linear address
|
||||||
|
jc bad_dpmi
|
||||||
|
|
||||||
|
popa
|
||||||
|
cli ! atomically switch stacks back
|
||||||
|
mov ss, (dpmi_ss)
|
||||||
|
o32 mov esp, (dpmi_ebp)
|
||||||
|
mov ds, (psegds32)
|
||||||
|
sti
|
||||||
|
|
||||||
|
o32 retf
|
||||||
|
|
||||||
bad_dpmi:
|
bad_dpmi:
|
||||||
mov si, bad_dpmi_msg
|
mov si, bad_dpmi_msg
|
||||||
jmp exit_with_error
|
jmp exit_with_error
|
||||||
|
@ -250,8 +332,6 @@ int21:
|
||||||
mov bx, (dpmi_ebx)
|
mov bx, (dpmi_ebx)
|
||||||
mov cx, (dpmi_ecx)
|
mov cx, (dpmi_ecx)
|
||||||
mov dx, (dpmi_edx)
|
mov dx, (dpmi_edx)
|
||||||
push (dpmi_flags)
|
|
||||||
popf
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
bad_dpmi_msg:
|
bad_dpmi_msg:
|
||||||
|
@ -260,7 +340,7 @@ no_file_msg:
|
||||||
.asciz "Couldn't open .exe"
|
.asciz "Couldn't open .exe"
|
||||||
no_dpmi_msg:
|
no_dpmi_msg:
|
||||||
.asciz "No DPMI host installed"
|
.asciz "No DPMI host installed"
|
||||||
.align 2
|
.align 4
|
||||||
text_top:
|
text_top:
|
||||||
|
|
||||||
exe_text_pages = [text_top - exe_header + 511] / 512
|
exe_text_pages = [text_top - exe_header + 511] / 512
|
||||||
|
@ -294,9 +374,12 @@ rseg: .space 2 ! real mode
|
||||||
pspseg: .space 2 ! real mode
|
pspseg: .space 2 ! real mode
|
||||||
psegcs: .space 2 ! protected mode 16-bit code segment
|
psegcs: .space 2 ! protected mode 16-bit code segment
|
||||||
psegds: .space 2 ! protected mode 16-bit data segment
|
psegds: .space 2 ! protected mode 16-bit data segment
|
||||||
|
psegcs32: .space 2 ! protected mode 32-bit code segment
|
||||||
|
psegds32: .space 2 ! protected mode 32-bit data segment
|
||||||
|
pmemaddr: .space 4 ! protected mode linear memory address
|
||||||
pmemhandle: .space 4 ! protected mode linear memory handle
|
pmemhandle: .space 4 ! protected mode linear memory handle
|
||||||
|
pmemlen: .space 4 ! protected mode linear memory length
|
||||||
fh: .space 2
|
fh: .space 2
|
||||||
textlen: .space 4
|
|
||||||
|
|
||||||
.space 128
|
.space 128
|
||||||
stack:
|
stack:
|
||||||
|
|
Loading…
Reference in a new issue