1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
|
;; $Id$
;; -----------------------------------------------------------------------
;;
;; Copyright 1994-2002 H. Peter Anvin - All Rights Reserved
;;
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
;; Bostom MA 02111-1307, USA; either version 2 of the License, or
;; (at your option) any later version; incorporated herein by reference.
;;
;; -----------------------------------------------------------------------
;;
;; comboot.inc
;;
;; Common code for running a COMBOOT image
;;
; Looks like a COMBOOT image but too large
comboot_too_large:
mov si,err_comlarge
call cwritestr
jmp enter_command
;
; Load a COMBOOT image. A COMBOOT image is basically a DOS .COM file,
; except that it may, of course, not contain any DOS system calls. We
; do, however, allow the execution of INT 20h to return to SYSLINUX.
;
is_comboot_image:
and dx,dx
jnz comboot_too_large
cmp ax,0ff00h ; Max size in bytes
jae comboot_too_large
call comboot_setup_api
mov cx,comboot_seg
mov es,cx
mov bx,100h ; Load at <seg>:0100h
mov cx,[ClustPerMoby] ; Absolute maximum # of clusters
call getfssec
xor di,di
mov cx,64 ; 256 bytes (size of PSP)
xor eax,eax ; Clear PSP
rep stosd
mov word [es:0], 020CDh ; INT 20h instruction
; First non-free paragraph
mov word [es:02h], comboot_seg+1000h
; Copy the command line from high memory
mov cx,125 ; Max cmdline len (minus space and CR)
mov si,[CmdOptPtr]
mov di,081h ; Offset in PSP for command line
mov al,' ' ; DOS command lines begin with a space
stosb
comboot_cmd_cp: lodsb
and al,al
jz comboot_end_cmd
stosb
loop comboot_cmd_cp
comboot_end_cmd: mov al,0Dh ; CR after last character
stosb
mov al,126 ; Include space but not CR
sub al,cl
mov [es:80h], al ; Store command line length
mov [SavedSSSP],sp
mov [SavedSSSP+2],ss ; Save away SS:SP
mov ax,es
mov ds,ax
mov ss,ax
xor sp,sp
push word 0 ; Return to address 0 -> exit
jmp comboot_seg:100h ; Run it
; Proper return vector
comboot_return: cli ; Don't trust anyone
xor ax,ax
jmp comboot_exit
;
; Set up the COMBOOT API interrupt vectors. This is also used
; by the COM32 code.
;
comboot_setup_api:
mov di,4*0x20 ; DOS interrupt vectors
mov eax,comboot_return ; INT 20h = exit
stosd
mov ax,comboot_int21 ; INT 21h = DOS-compatible syscalls
stosd
mov ax,comboot_int22 ; INT 22h = proprietary syscalls
stosd
mov ax,comboot_bogus
mov cx,29 ; All remaining DOS vectors
rep stosd
ret
; INT 21h: generic DOS system call
comboot_int21: push ds
push cs
pop ds ; Set DS <- CS
and ah,ah ; 00 = return
je comboot_return
cmp ah,02h
jb comboot_getkeyecho ; 01 = get key with echo
je comboot_writechr ; 02 = writechr
cmp ah,08h ; 08 = get key w/o echo
je comboot_getkey
cmp ah,09h ; 09 = writestr
je comboot_writestr
cmp ah,0Bh ; 0B = check keyboard
je comboot_checkkey
cmp ah,30h ; 30 = check version
je comboot_checkver
cmp ah,4Ch ; 4C = return with status
je comboot_return
; Otherwise fall through to comboot_bogus
; Attempted to execute non-21h DOS system call
comboot_bogus: cli ; Don't trust anyone
mov ax,err_notdos
;
; Generic COMBOOT return to command line code
; AX -> message (if any)
; BX -> where to go next
;
comboot_exit:
mov bx,enter_command ; Normal return to command prompt
comboot_exit_special:
xor dx,dx
mov ds,dx
mov es,dx
lss sp,[SavedSSSP]
sti
cld
and ax,ax
je .nomsg
mov si,KernelCName
call cwritestr
xchg si,ax
call cwritestr
.nomsg: jmp bx
;
; INT 21h system calls
;
comboot_getkeyecho: ; 01 = get key with echo
call vgashowcursor
call getchar
call vgahidecursor
call writechr
jmp comboot_resume_ok
comboot_writechr: ; 02 = writechr
xchg ax,dx
call writechr
xchg ax,dx
jmp comboot_resume_ok
comboot_getkey: ; 08 = get key w/o echo
call vgashowcursor
call getchar
call vgahidecursor
jmp comboot_resume_ok
comboot_writestr: ; 09 = write string
pusha
push es
mov bp,sp
mov es,[bp-20] ; Old DS
mov si,dx
.loop: es lodsb
cmp al,'$' ; End string with $ - bizarre
je .done
call writechr
jmp short .loop
.done: pop es
popa
jmp comboot_resume_ok
comboot_checkkey: ; 0B = check keyboard status
call pollchar
setz al
dec al ; AL = 0FFh if present, 0 if not
jmp comboot_resume_ok
comboot_checkver: ; 30 = check DOS version
; We return 0 in all DOS-compatible version registers,
; but the high part of eax-ebx-ecx-edx spell "SYSLINUX"
mov eax,'SY' << 16
mov ebx,'SL' << 16
mov ecx,'IN' << 16
mov edx,'UX' << 16
;jmp comboot_resume_ok
;
; Resume comboot execution
;
comboot_resume_ok:
clc
comboot_resume:
pop ds
iret
comboot_apierr:
stc
jmp comboot_resume
;
; INT 22h - SYSLINUX-specific system calls
; System call number in ax
;
comboot_int22:
push ds
push cs
pop ds
cmp ax,int22_count
jae comboot_apierr
xchg ax,bx
add bx,bx
call [bx+int22_table]
jmp comboot_resume ; On return
;
; INT 22h AX=0000h Null system call
; INT 22h AX=0001h Get SYSLINUX version
;
comapi_get_version:
; Number of API functions supported
mov ax,int22_count
; SYSLINUX version
mov cx,(VER_MAJOR << 8)+VER_MINOR
; SYSLINUX derivative ID byte
mov dx,my_id
; For future use
xor bx,bx
push cs
pop es
; ES:SI -> version banner
mov si,syslinux_banner
; ES:DI -> copyright string
mov di,copyright_str
comapi_nop:
clc
ret
;
; INT 22h AX=0002h Write string
;
; Write null-terminated string in ES:BX
;
comapi_writestr:
push es
pop ds
mov si,ax
jmp writestr ; Write string from ES:BX
;
; INT 22h AX=0003h Run command
;
; Terminates the COMBOOT program and executes the command line in
; ES:BX as if it had been entered by the user.
;
comapi_run:
push es
push ds
pop es
pop ds
mov si,ax
mov di,command_line
.copyloop:
lodsb
stosb
and al,al
jnz .copyloop
xor ax,ax
mov bx,load_kernel ; Run a new kernel
jmp comboot_exit_special ; Terminate task, clean up
;
; INT 22h AX=0004h Run default command
;
; Terminates the COMBOOT program and executes the default command line
; as if a timeout had happened or the user pressed <Enter>.
;
comapi_run_default:
mov bx,auto_boot
jmp comboot_exit_special
;
; INT 22h AX=0005h Force text mode
;
; Puts the video in standard text mode
;
comapi_textmode:
call vgaclearmode
clc
ret
;
; INT 22h AX=0006h Open file
;
comapi_open:
push ds
push ds
push es
pop ds
pop es
mov di,InitRD
push di
call mangle_name
pop di
pop ds
call searchdir
jz .err
xchg eax,edx
shr eax,16
xchg ax,dx
mov cx,[ClustSize]
clc
ret
.err:
stc
ret
;
; INT 22h AX=0007h Read file
;
comapi_read:
xchg ax,bx
call getfssec
jnc .noteof
xor si,si ; SI <- 0 on EOF, CF <- 0
.noteof: ret
;
; INT 22h AX=0008h Close file
;
comapi_close:
; Do nothing for now. Eventually implement
; an internal API for this.
clc
ret
;
; INT 22h AX=0009h Call PXE stack
;
%if IS_PXELINUX
call far [PXENVEntry]
clc
ret
%else
stc ; Function not available
ret
%endif
align 2, db 0
int22_table:
dw comapi_nop ; 0000 null syscall
dw comapi_get_version ; 0001 get SYSLINUX version
dw comapi_writestr ; 0002 write string
dw comapi_run ; 0003 run specified command
dw comapi_run_default ; 0004 run default command
dw comapi_textmode ; 0005 force text mode
dw comapi_open ; 0006 open file
dw comapi_read ; 0007 read file
dw comapi_close ; 0008 close file
dw comapi_pxecall ; 0009 call PXE stack
int22_count equ ($-int22_table)/2
|