|
;; $Id: com32.inc,v 1.1 2007-09-01 22:44:04 niro Exp $ |
|
1 |
;; ----------------------------------------------------------------------- |
;; ----------------------------------------------------------------------- |
2 |
;; |
;; |
3 |
;; Copyright 1994-2003 H. Peter Anvin - All Rights Reserved |
;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved |
4 |
;; |
;; |
5 |
;; This program is free software; you can redistribute it and/or modify |
;; This program is free software; you can redistribute it and/or modify |
6 |
;; it under the terms of the GNU General Public License as published by |
;; it under the terms of the GNU General Public License as published by |
26 |
; "mov ax,0x4cff; int 0x21" in 16-bit mode. This will abort the |
; "mov ax,0x4cff; int 0x21" in 16-bit mode. This will abort the |
27 |
; program with an error if run in 16-bit mode. |
; program with an error if run in 16-bit mode. |
28 |
; |
; |
29 |
pm_idt: equ 0x100000 |
|
30 |
pm_entry: equ 0x101000 |
; We need to make this a proper section rather |
31 |
|
; than using absolute numbers, in order to work |
32 |
|
; around a bug in GNU ld 2.17, which is still in |
33 |
|
; use as of this writing in the form of Debian |
34 |
|
; 4.0 (etch). |
35 |
|
bits 32 |
36 |
|
section .com32 exec write nobits align=16 |
37 |
|
pm_idt equ 0x100000 ; Needs to be absolute... |
38 |
|
resb 4096 |
39 |
|
pm_entry: ; Needs to not be... |
40 |
|
|
41 |
bits 16 |
bits 16 |
42 |
section .data |
section .data |
43 |
align 2, db 0 |
alignz 2 |
44 |
com32_pmidt: |
com32_pmidt: |
45 |
dw 8*256 ; Limit |
dw 8*256 ; Limit |
46 |
dd pm_idt ; Address |
dd pm_idt ; Address |
52 |
section .text |
section .text |
53 |
is_com32_image: |
is_com32_image: |
54 |
push si ; Save file handle |
push si ; Save file handle |
55 |
push dx ; File length held in DX:AX |
push eax ; Save file length |
|
push ax |
|
56 |
|
|
57 |
call make_plain_cmdline |
call make_plain_cmdline |
58 |
; Copy the command line into the low cmdline buffer |
; Copy the command line into the low cmdline buffer |
65 |
sub cx,si |
sub cx,si |
66 |
fs rep movsb |
fs rep movsb |
67 |
|
|
68 |
call highmemsize ; We need the high memory size... |
mov si,KernelCName |
69 |
|
mov di,Com32Name |
70 |
|
call strcpy |
71 |
|
|
72 |
call comboot_setup_api ; Set up the COMBOOT-style API |
call comboot_setup_api ; Set up the COMBOOT-style API |
73 |
|
|
74 |
mov edi,pm_entry ; Load address |
mov edi,pm_entry ; Load address |
75 |
pop eax ; File length |
pop eax ; File length |
76 |
pop si ; File handle |
pop si ; File handle |
77 |
xor dx,dx ; No padding |
xor dx,dx ; No padding |
78 |
|
mov bx,abort_check ; Don't print dots, but allow abort |
79 |
call load_high |
call load_high |
|
call crlf |
|
80 |
|
|
81 |
com32_start: |
com32_start: |
82 |
mov ebx,com32_call_start ; Where to go in PM |
mov ebx,com32_call_start ; Where to go in PM |
85 |
cli |
cli |
86 |
mov ax,cs |
mov ax,cs |
87 |
mov ds,ax |
mov ds,ax |
88 |
mov [SavedSSSP],sp |
mov [RealModeSSSP],sp |
89 |
mov [SavedSSSP+2],ss |
mov [RealModeSSSP+2],ss |
90 |
cld |
cld |
91 |
call a20_test |
call a20_test |
92 |
jnz .a20ok |
jnz .a20ok |
93 |
call enable_a20 |
call enable_a20 |
94 |
|
|
95 |
.a20ok: |
.a20ok: |
96 |
|
mov byte [bcopy_gdt.TSS+5],89h ; Mark TSS unbusy |
97 |
|
|
98 |
lgdt [bcopy_gdt] ; We can use the same GDT just fine |
lgdt [bcopy_gdt] ; We can use the same GDT just fine |
99 |
lidt [com32_pmidt] ; Set up the IDT |
lidt [com32_pmidt] ; Set up the IDT |
100 |
mov eax,cr0 |
mov eax,cr0 |
101 |
or al,1 |
or al,1 |
102 |
mov cr0,eax ; Enter protected mode |
mov cr0,eax ; Enter protected mode |
103 |
jmp 20h:.in_pm |
jmp PM_CS32:.in_pm |
104 |
|
|
105 |
bits 32 |
bits 32 |
106 |
.in_pm: |
.in_pm: |
107 |
xor eax,eax ; Available for future use... |
xor eax,eax ; Available for future use... |
108 |
mov fs,eax |
mov fs,eax |
109 |
mov gs,eax |
mov gs,eax |
110 |
|
lldt ax |
111 |
|
|
112 |
mov al,28h ; Set up data segments |
mov al,PM_DS32 ; Set up data segments |
113 |
mov es,eax |
mov es,eax |
114 |
mov ds,eax |
mov ds,eax |
115 |
mov ss,eax |
mov ss,eax |
116 |
|
|
117 |
|
mov al,PM_TSS ; Be nice to Intel's VT by |
118 |
|
ltr ax ; giving it a valid TR |
119 |
|
|
120 |
mov esp,[PMESP] ; Load protmode %esp if available |
mov esp,[PMESP] ; Load protmode %esp if available |
121 |
jmp ebx ; Go to where we need to go |
jmp ebx ; Go to where we need to go |
122 |
|
|
126 |
; |
; |
127 |
com32_call_start: |
com32_call_start: |
128 |
; |
; |
129 |
; Point the stack to the end of high memory |
; Point the stack to the end of (permitted) high memory |
130 |
; |
; |
131 |
mov esp,[word HighMemSize] |
mov esp,[word HighMemRsvd] |
132 |
|
xor sp,sp ; Align to a 64K boundary |
133 |
|
|
134 |
; |
; |
135 |
; Set up the protmode IDT and the interrupt jump buffers |
; Set up the protmode IDT and the interrupt jump buffers |
176 |
|
|
177 |
; Now everything is set up for interrupts... |
; Now everything is set up for interrupts... |
178 |
|
|
179 |
|
push dword Com32Name ; Module filename |
180 |
|
push dword [HighMemSize] ; Memory managed by Syslinux |
181 |
|
push dword com32_cfarcall ; Cfarcall entry point |
182 |
push dword com32_farcall ; Farcall entry point |
push dword com32_farcall ; Farcall entry point |
183 |
push dword (1 << 16) ; 64K bounce buffer |
push dword (1 << 16) ; 64K bounce buffer |
184 |
push dword (comboot_seg << 4) ; Bounce buffer address |
push dword (xfer_buf_seg << 4) ; Bounce buffer address |
185 |
push dword com32_intcall ; Intcall entry point |
push dword com32_intcall ; Intcall entry point |
186 |
push dword command_line ; Command line pointer |
push dword command_line ; Command line pointer |
187 |
push dword 5 ; Argument count |
push dword 8 ; Argument count |
188 |
sti ; Interrupts OK now |
sti ; Interrupts OK now |
189 |
call pm_entry ; Run the program... |
call pm_entry ; Run the program... |
190 |
; ... on return, fall through to com32_exit ... |
; ... on return, fall through to com32_exit ... |
197 |
cld |
cld |
198 |
mov [PMESP],esp ; Save exit %esp |
mov [PMESP],esp ; Save exit %esp |
199 |
xor esp,esp ; Make sure the high bits are zero |
xor esp,esp ; Make sure the high bits are zero |
200 |
jmp 08h:.in_pm16 ; Return to 16-bit mode first |
jmp PM_CS16:.in_pm16 ; Return to 16-bit mode first |
201 |
|
|
202 |
bits 16 |
bits 16 |
203 |
.in_pm16: |
.in_pm16: |
204 |
mov ax,18h ; Real-mode-like segment |
mov ax,PM_DS16 ; Real-mode-like segment |
205 |
mov es,ax |
mov es,ax |
206 |
mov ds,ax |
mov ds,ax |
207 |
mov ss,ax |
mov ss,ax |
220 |
mov es,ax |
mov es,ax |
221 |
mov fs,ax |
mov fs,ax |
222 |
mov gs,ax |
mov gs,ax |
223 |
lss sp,[SavedSSSP] ; Restore stack |
lss sp,[RealModeSSSP] ; Restore stack |
224 |
jmp bx ; Go to whereever we need to go... |
jmp bx ; Go to whereever we need to go... |
225 |
|
|
226 |
com32_done: |
com32_done: |
|
call disable_a20 |
|
227 |
sti |
sti |
228 |
jmp enter_command |
jmp enter_command |
229 |
|
|
246 |
jmp com32_enter_pm ; Go back to PM |
jmp com32_enter_pm ; Go back to PM |
247 |
|
|
248 |
; |
; |
249 |
; 16-bit system call handling code |
; 16-bit intcall/farcall handling code |
250 |
; |
; |
251 |
com32_sys_rm: |
com32_sys_rm: |
252 |
pop gs |
pop gs |
267 |
push es |
push es |
268 |
push fs |
push fs |
269 |
push gs |
push gs |
270 |
mov ebx,com32_sys_resume |
mov ebx,com32_syscall.resume |
271 |
|
jmp com32_enter_pm |
272 |
|
|
273 |
|
; |
274 |
|
; 16-bit cfarcall handing code |
275 |
|
; |
276 |
|
com32_cfar_rm: |
277 |
|
retf |
278 |
|
.return: |
279 |
|
mov sp,[cs:Com32SysSP] |
280 |
|
mov [cs:RealModeEAX],eax |
281 |
|
mov ebx,com32_cfarcall.resume |
282 |
jmp com32_enter_pm |
jmp com32_enter_pm |
283 |
|
|
284 |
; |
; |
333 |
com32_syscall: |
com32_syscall: |
334 |
cld |
cld |
335 |
|
|
336 |
movzx edi,word [word SavedSSSP] |
movzx edi,word [word RealModeSSSP] |
337 |
movzx ebx,word [word SavedSSSP+2] |
movzx ebx,word [word RealModeSSSP+2] |
338 |
sub edi,54 ; Allocate 54 bytes |
sub edi,54 ; Allocate 54 bytes |
339 |
mov [word SavedSSSP],di |
mov [word RealModeSSSP],di |
340 |
shl ebx,4 |
shl ebx,4 |
341 |
add edi,ebx ; Create linear address |
add edi,ebx ; Create linear address |
342 |
|
|
360 |
; On return, the 44-byte return structure is on the |
; On return, the 44-byte return structure is on the |
361 |
; real-mode stack, plus the 10 additional bytes used |
; real-mode stack, plus the 10 additional bytes used |
362 |
; by the target address (see above.) |
; by the target address (see above.) |
363 |
com32_sys_resume: |
.resume: |
364 |
movzx esi,word [word SavedSSSP] |
movzx esi,word [word RealModeSSSP] |
365 |
movzx eax,word [word SavedSSSP+2] |
movzx eax,word [word RealModeSSSP+2] |
366 |
mov edi,[esp+12*4] ; Dest regs |
mov edi,[esp+12*4] ; Dest regs |
367 |
shl eax,4 |
shl eax,4 |
368 |
add esi,eax ; Create linear address |
add esi,eax ; Create linear address |
373 |
mov cl,11 ; 44 bytes |
mov cl,11 ; 44 bytes |
374 |
rep movsd ; Copy register block |
rep movsd ; Copy register block |
375 |
|
|
376 |
add dword [word SavedSSSP],54 ; Remove from stack |
add dword [word RealModeSSSP],54 ; Remove from stack |
377 |
|
|
378 |
popad |
popad |
379 |
popfd |
popfd |
380 |
ret ; Return to 32-bit program |
ret ; Return to 32-bit program |
381 |
|
|
382 |
|
; |
383 |
|
; Cfarcall invocation. We copy the stack frame to the real-mode stack, |
384 |
|
; followed by the return CS:IP and the CS:IP of the target function. |
385 |
|
; |
386 |
|
com32_cfarcall: |
387 |
|
pushfd |
388 |
|
pushad |
389 |
|
|
390 |
|
cld |
391 |
|
mov ecx,[esp+12*4] ; Size of stack frame |
392 |
|
|
393 |
|
movzx edi,word [word RealModeSSSP] |
394 |
|
movzx ebx,word [word RealModeSSSP+2] |
395 |
|
mov [word Com32SysSP],di |
396 |
|
sub edi,ecx ; Allocate space for stack frame |
397 |
|
and edi,~3 ; Round |
398 |
|
sub edi,4*2 ; Return pointer, return value |
399 |
|
mov [word RealModeSSSP],di |
400 |
|
shl ebx,4 |
401 |
|
add edi,ebx ; Create linear address |
402 |
|
|
403 |
|
mov eax,[esp+10*4] ; CS:IP |
404 |
|
stosd ; Save to stack frame |
405 |
|
mov eax,com32_cfar_rm.return ; Return seg:off |
406 |
|
stosd |
407 |
|
mov esi,[esp+11*4] ; Stack frame |
408 |
|
mov eax,ecx ; Copy the stack frame |
409 |
|
shr ecx,2 |
410 |
|
rep movsd |
411 |
|
mov ecx,eax |
412 |
|
and ecx,3 |
413 |
|
rep movsb |
414 |
|
|
415 |
|
mov bx,com32_cfar_rm |
416 |
|
jmp com32_enter_rm |
417 |
|
|
418 |
|
.resume: |
419 |
|
popad |
420 |
|
mov eax,[word RealModeEAX] |
421 |
|
popfd |
422 |
|
ret |
423 |
|
|
424 |
bits 16 |
bits 16 |
425 |
|
|
426 |
section .bss |
section .bss1 |
427 |
alignb 4 |
alignb 4 |
428 |
|
RealModeSSSP resd 1 ; Real-mode SS:SP |
429 |
|
RealModeEAX resd 1 ; Real mode EAX |
430 |
PMESP resd 1 ; Protected-mode ESP |
PMESP resd 1 ; Protected-mode ESP |
431 |
Com32SysSP resw 1 ; SP saved during COM32 syscall |
Com32SysSP resw 1 ; SP saved during COM32 syscall |
432 |
|
|
433 |
|
section .uibss |
434 |
|
%if IS_SYSLINUX |
435 |
|
Com32Name resb FILENAME_MAX+2 |
436 |
|
%else |
437 |
|
Com32Name resb FILENAME_MAX |
438 |
|
%endif |
439 |
|
|
440 |
section .text |
section .text |