Core:SYSLINUX: ldlinux.asm converted to C
[profile/ivi/syslinux.git] / core / ldlinux.asm
1 ; -*- fundamental -*- (asm-mode sucks)
2 ; ****************************************************************************
3 ;
4 ;  ldlinux.asm
5 ;
6 ;  A program to boot Linux kernels off an MS-DOS formatted floppy disk.  This
7 ;  functionality is good to have for installation floppies, where it may
8 ;  be hard to find a functional Linux system to run LILO off.
9 ;
10 ;  This program allows manipulation of the disk to take place entirely
11 ;  from MS-LOSS, and can be especially useful in conjunction with the
12 ;  umsdos filesystem.
13 ;
14 ;   Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
15 ;   Copyright 2009 Intel Corporation; author: H. Peter Anvin
16 ;
17 ;  This program is free software; you can redistribute it and/or modify
18 ;  it under the terms of the GNU General Public License as published by
19 ;  the Free Software Foundation, Inc., 53 Temple Place Ste 330,
20 ;  Boston MA 02111-1307, USA; either version 2 of the License, or
21 ;  (at your option) any later version; incorporated herein by reference.
22 ;
23 ; ****************************************************************************
24
25 %ifndef IS_MDSLINUX
26 %define IS_SYSLINUX 1
27 %endif
28 %include "head.inc"
29
30 ;
31 ; Some semi-configurable constants... change on your own risk.
32 ;
33 my_id           equ syslinux_id
34 FILENAME_MAX_LG2 equ 6                  ; log2(Max filename size Including final null)
35 FILENAME_MAX    equ (1<<FILENAME_MAX_LG2) ; Max mangled filename size
36 NULLFILE        equ 0                   ; First char space == null filename
37 NULLOFFSET      equ 0                   ; Position in which to look
38 retry_count     equ 16                  ; How patient are we with the disk?
39 %assign HIGHMEM_SLOP 0                  ; Avoid this much memory near the top
40 LDLINUX_MAGIC   equ 0x3eb202fe          ; A random number to identify ourselves with
41
42 MAX_OPEN_LG2    equ 6                   ; log2(Max number of open files)
43 MAX_OPEN        equ (1 << MAX_OPEN_LG2)
44
45 SECTOR_SHIFT    equ 9
46 SECTOR_SIZE     equ (1 << SECTOR_SHIFT)
47
48 DIRENT_SHIFT    equ 5
49 DIRENT_SIZE     equ (1 << DIRENT_SHIFT)
50
51 ROOT_DIR_WORD   equ 0x002F
52
53 ;
54 ; The following structure is used for "virtual kernels"; i.e. LILO-style
55 ; option labels.  The options we permit here are `kernel' and `append
56 ; Since there is no room in the bottom 64K for all of these, we
57 ; stick them in high memory and copy them down before we need them.
58 ;
59                 struc vkernel
60 vk_vname:       resb FILENAME_MAX       ; Virtual name **MUST BE FIRST!**
61 vk_rname:       resb FILENAME_MAX       ; Real name
62 vk_appendlen:   resw 1
63 vk_type:        resb 1                  ; Type of file
64                 alignb 4
65 vk_append:      resb max_cmd_len+1      ; Command line
66                 alignb 4
67 vk_end:         equ $                   ; Should be <= vk_size
68                 endstruc
69
70 ;
71 ; File structure.  This holds the information for each currently open file.
72 ;
73                 struc open_file_t
74 file_sector     resd 1                  ; Sector pointer (0 = structure free)
75 file_bytesleft  resd 1                  ; Number of bytes left
76 file_left       resd 1                  ; Number of sectors left
77                 resd 1                  ; Unused
78                 endstruc
79
80 ;
81 ; Structure for codepage files
82 ;
83                 struc cp
84 .magic          resd 2                  ; 8-byte magic number
85 .reserved       resd 6                  ; Reserved for future use
86 .uppercase      resb 256                ; Internal upper-case table
87 .unicode        resw 256                ; Unicode matching table
88 .unicode_alt    resw 256                ; Alternate Unicode matching table
89                 endstruc
90
91 %ifndef DEPEND
92 %if (open_file_t_size & (open_file_t_size-1))
93 %error "open_file_t is not a power of 2"
94 %endif
95 %endif
96
97 ; ---------------------------------------------------------------------------
98 ;   BEGIN CODE
99 ; ---------------------------------------------------------------------------
100
101 ;
102 ; Memory below this point is reserved for the BIOS and the MBR
103 ;
104                 section .earlybss
105 trackbufsize    equ 8192
106 trackbuf        resb trackbufsize       ; Track buffer goes here
107                 ; ends at 2800h
108
109                 section .bss16
110                 alignb 4
111 FAT             resd 1                  ; Location of (first) FAT
112 RootDirArea     resd 1                  ; Location of root directory area
113 RootDir         resd 1                  ; Location of root directory proper
114 DataArea        resd 1                  ; Location of data area
115 RootDirSize     resd 1                  ; Root dir size in sectors
116 TotalSectors    resd 1                  ; Total number of sectors
117 ClustSize       resd 1                  ; Bytes/cluster
118 ClustMask       resd 1                  ; Sectors/cluster - 1
119 CopySuper       resb 1                  ; Distinguish .bs versus .bss
120 ClustShift      resb 1                  ; Shift count for sectors/cluster
121 ClustByteShift  resb 1                  ; Shift count for bytes/cluster
122
123 ;               global syslinux_cfg_buffer
124 ;syslinux_cfg_buffer resb 28         ; the syslinux config file name buffer, used by vfat_load_config
125
126                 alignb open_file_t_size
127                 global Files
128 Files           resb MAX_OPEN*open_file_t_size
129
130 ;
131 ; Common bootstrap code for disk-based derivatives
132 ;
133 %include "diskstart.inc"
134
135
136
137 ;
138 ; Now, everything is "up and running"... patch kaboom for more
139 ; verbosity and using the full screen system
140 ;
141                 ; E9 = JMP NEAR
142                 mov di,kaboom.patch
143                 mov al,0e9h
144                 stosb
145                 mov ax,kaboom2-2
146                 sub ax,di
147                 stosw
148
149 ;
150 ; Now we're all set to start with our *real* business.  First load the
151 ; configuration file (if any) and parse it.
152 ;
153 ; In previous versions I avoided using 32-bit registers because of a
154 ; rumour some BIOSes clobbered the upper half of 32-bit registers at
155 ; random.  I figure, though, that if there are any of those still left
156 ; they probably won't be trying to install Linux on them...
157 ;
158 ; The code is still ripe with 16-bitisms, though.  Not worth the hassle
159 ; to take'm out.  In fact, we may want to put them back if we're going
160 ; to boot ELKS at some point.
161 ;
162
163 ;
164 ; Load configuration file
165 ;
166                 pm_call load_config
167                 jz no_config_file
168
169 ;
170 ; Now we have the config file open.  Parse the config file and
171 ; run the user interface.
172 ;
173 %include "ui.inc"
174
175                 section .text16
176
177 ;
178 ; close_dir:
179 ;            Deallocates a directory structure (pointer in SI)
180 ;            Assumes CS == DS.
181 ;
182 close_dir:
183                 and si,si
184                 jz .closed
185                 mov dword [si],0                ; First dword == file_sector
186                 xor si,si
187 .closed:        ret
188
189
190
191 ;
192 ;
193 ; kaboom2: once everything is loaded, replace the part of kaboom
194 ;          starting with "kaboom.patch" with this part
195
196 kaboom2:
197                 mov si,err_bootfailed
198                 call writestr
199                 cmp byte [kaboom.again+1],18h   ; INT 18h version?
200                 je .int18
201                 call getchar
202                 call vgaclearmode
203                 int 19h                 ; And try once more to boot...
204 .norge:                 jmp short .norge        ; If int 19h returned; this is the end
205 .int18:
206                 call vgaclearmode
207                 int 18h
208 .noreg: jmp short .noreg        ; Nynorsk
209
210
211
212 ;
213 ; unmangle_name: Does the opposite of mangle_name; converts a DOS-mangled
214 ;                filename to the conventional representation.  This is needed
215 ;                for the BOOT_IMAGE= parameter for the kernel.
216 ;                NOTE: A 13-byte buffer is mandatory, even if the string is
217 ;                known to be shorter.
218 ;
219 ;                DS:SI -> input mangled file name
220 ;                ES:DI -> output buffer
221 ;
222 ;                On return, DI points to the first byte after the output name,
223 ;                which is set to a null byte.
224 ;
225 unmangle_name:  call strcpy
226                 dec di                          ; Point to final null byte
227                 ret
228
229         
230
231 ; -----------------------------------------------------------------------------
232 ;  Common modules
233 ; -----------------------------------------------------------------------------
234
235 %include "common.inc"           ; Universal modules
236 %include "plaincon.inc"         ; writechr
237 %include "writestr.inc"         ; String output
238 %include "writehex.inc"         ; Hexadecimal output
239 %include "localboot.inc"        ; Disk-based local boot
240
241 ; -----------------------------------------------------------------------------
242 ;  Begin data section
243 ; -----------------------------------------------------------------------------
244
245                 section .data16
246 copyright_str   db ' Copyright (C) 1994-'
247                 asciidec YEAR
248                 db ' H. Peter Anvin et al', CR, LF, 0
249 err_bootfailed  db CR, LF, 'Boot failed: please change disks and press '
250                 db 'a key to continue.', CR, LF, 0
251 syslinux_cfg1   db '/boot'                      ; /boot/syslinux/syslinux.cfg
252 syslinux_cfg2   db '/syslinux'                  ; /syslinux/syslinux.cfg
253 syslinux_cfg3   db '/'                          ; /syslinux.cfg
254 config_name     db 'syslinux.cfg', 0            ; syslinux.cfg
255
256 ;
257 ; Config file keyword table
258 ;
259 %include "keywords.inc"
260
261 ;
262 ; Extensions to search for (in *forward* order).
263 ;
264 exten_table:    db '.cbt'               ; COMBOOT (specific)
265                 db '.bss'               ; Boot Sector (add superblock)
266                 db '.bs', 0             ; Boot Sector
267                 db '.com'               ; COMBOOT (same as DOS)
268                 db '.c32'               ; COM32
269 exten_table_end:
270                 dd 0, 0                 ; Need 8 null bytes here
271
272 ;
273 ; Misc initialized (data) variables
274 ;
275 %ifdef debug                            ; This code for debugging only
276 debug_magic     dw 0D00Dh               ; Debug code sentinel
277 %endif
278
279                 alignz 4
280 BufSafe         dw trackbufsize/SECTOR_SIZE     ; Clusters we can load into trackbuf
281 BufSafeBytes    dw trackbufsize         ; = how many bytes?
282 %ifndef DEPEND
283 %if ( trackbufsize % SECTOR_SIZE ) != 0
284 %error trackbufsize must be a multiple of SECTOR_SIZE
285 %endif
286 %endif