Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Release 1.0
[palacios.git] / misc / test_vm / src / geekos / fd_boot_bak.asm
1 ; -*- fundamental -*-
2 ; Boot sector for GeekOS
3 ; Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
4 ; Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
5 ; $Revision: 1.1 $
6
7 ; This is free software.  You are permitted to use,
8 ; redistribute, and modify it as specified in the file "COPYING".
9
10 ; Loads setup code and a program image from sectors 1..n of a floppy
11 ; and executes the setup code (which will in turn execute
12 ; the program image).
13
14 ; Some of this code is adapted from Kernel Toolkit 0.2
15 ; and Linux version 2.2.x, so the following copyrights apply:
16
17 ; Copyright (C) 1991, 1992 Linus Torvalds
18 ; modified by Drew Eckhardt
19 ; modified by Bruce Evans (bde)
20 ; adapted for Kernel Toolkit by Luigi Sgro
21
22 %include "defs.asm"
23
24 ; Pad to desired offset from start symbol.
25 ;    Usage: Pad_From_Symbol offset, symbol
26 %macro Pad_From_Symbol 2
27         times (%1 - ($ - %2)) db 0
28 %endmacro
29
30 ; ----------------------------------------------------------------------
31 ; The actual code
32 ; ----------------------------------------------------------------------
33
34 [BITS 16]
35 [ORG 0x0]
36
37 BeginText:      ; needed to calculate padding bytes to fill the sector
38
39         ; Copy the boot sector into INITSEG.
40         mov     ax, BOOTSEG
41         mov     ds, ax                  ; source segment for string copy
42         xor     si, si                  ; source index for string copy
43         mov     ax, INITSEG
44         mov     es, ax                  ; destination segment for string copy
45         xor     di, di                  ; destination index for string copy
46         cld                             ; clear direction flag
47         mov     cx, 256                 ; number of words to copy
48         rep     movsw                   ; copy 512 bytes
49
50         jmp     INITSEG:after_move
51
52 after_move:
53         ; Now we're executing in INITSEG
54
55
56         ; We want the data segment to refer to INITSEG
57         ; (since we've defined variables in the same place as the code)
58         mov     ds, ax                  ; ax still contains INITSEG
59
60         ; Put the stack in the place where we were originally loaded.
61         ; By definition, there is nothing important there now.
62         mov     ax, 0
63         mov     ss, ax
64         mov     sp, (BOOTSEG << 4) + 512 - 2
65
66
67 load_setup:
68         ; Load the setup code.
69         mov     ax, word [setupStart]
70         mov     word [sec_count], ax
71         add     ax, [setupSize]
72         mov     word [max_sector], ax
73 .again:
74         mov     ax, [sec_count]
75         push    ax                      ; 1st param to ReadSector (log sec num)
76         push    word SETUPSEG           ; 2nd param to ReadSector (seg base)
77         sub     ax, [setupStart]        ; convert to 0-indexed
78         shl     ax, 9                   ; multiply by 512
79         push    ax                      ;  ...to get 3rd param (byte offset)
80
81         ; read the sector from the floppy
82         call    ReadSector
83         add     sp, 6                   ; clear 3 word params
84
85         ; on to next sector
86         inc     word [sec_count]
87
88         ; are we done?
89         mov     bx, word [max_sector]
90         cmp     word [sec_count], bx
91         jl      .again
92
93 load_kernel:
94         ; Load the kernel image from sectors KERN_START_SEC..n of the
95         ; floppy into memory at KERNSEG.  Note that there are 128 sectors
96         ; per 64K segment.  So, when figuring out which segment to
97         ; load the sector into, we shift right by 7 bits (which is
98         ; equivalent to dividing by 128).
99
100         ; Figure out start sector and max sector
101
102         mov     ax, word [kernelStart]
103         mov     word [sec_count], ax
104         add     ax, word [kernelSize]
105         mov     word [max_sector], ax
106 .again:
107         mov     ax, [sec_count]         ; logical sector on the floppy
108 ;       mov     dx, ax
109 ;       call    PrintHex
110 ;       call    PrintNL
111         push    ax                      ; 1st param to ReadSector (log sec num)
112         sub     ax, [kernelStart]       ; convert to 0-indexed
113         mov     cx, ax                  ; save in cx
114         shr     ax, 7                   ; divide by 128
115         shl     ax, 12                  ;  ...and multiply by 0x1000
116         add     ax, KERNSEG             ;  ...to get base relative to KERNSEG
117 ;       mov     dx, ax
118 ;       call    PrintHex
119 ;       call    PrintNL
120         push    ax                      ; 2nd param to ReadSector (seg base)
121         and     cx, 0x7f                ; mod sector by 128
122         shl     cx, 9                   ;  ...and multiply by 512
123         push    cx                      ; to get offset in segment (3rd parm)
124 ;       mov     dx, cx
125 ;       call    PrintHex
126 ;       call    PrintNL
127
128
129         ; read the sector from the floppy
130         call    ReadSector
131         add     sp, 6                   ; clear 3 word params
132
133
134         ; on to next sector
135         inc     word [sec_count]
136
137         ; have we loaded all of the sectors?
138         mov     bx, word [max_sector]
139         cmp     word [sec_count], bx
140         jl      .again
141
142 load_vm:
143         ; Load the guest image starting at 1MB
144         ; floppy into memory at KERNSEG.  Note that there are 128 sectors
145         ; per 64K segment.  So, when figuring out which segment to
146         ; load the sector  into, we shift right by 7 bits (which is
147         ; equivalent to dividing by 128).
148
149         ; Figure out start sector and max sector
150         mov     ax, word [vmStart]
151         mov     word [sec_count], ax
152         add     ax, word [vmSize]
153         mov     word [max_sector], ax
154 .again2:
155
156         mov     ax, [sec_count]         ; logical sector on the floppy
157         push    ax                      ; 1st param to ReadSector (log sec num)
158
159 ;       mov     dx, ax
160 ;       call    PrintHex
161 ;       call    PrintNL
162
163         mov     ax, VMSEG               ;  ...to get base relative to VMSEG
164         push    ax                      ; 2nd param to ReadSector (seg base)
165         
166 ;       mov     dx, ax          ; 
167 ;       call    PrintHex
168 ;       call    PrintNL
169
170         mov     ax, 2000h               ; Always write at the start of the segment
171         push    ax              ; 3rd parameter
172
173 ;       mov     dx, ax
174 ;       call    PrintHex
175 ;       call    PrintNL
176
177         ; read the sector from the floppy
178         call    ReadSector
179         add     sp, 6                   ; clear 3 word params
180
181         push    VMSEG
182         pop     es
183
184 ;       mov     dx, word [es:2000h] ;
185 ;       call    PrintHex
186 ;       call    PrintNL
187         
188         
189
190 ; execute bios call
191
192         push    cx
193         push    si
194         push    bx
195         push    es              ; 
196
197         push    cs
198         pop     es
199         mov     si, bootsect_gdt
200         mov     ah, 87h
201
202         mov     cx, 100h
203
204         int     0x15
205         
206         adc     ax, 0
207
208 ;       mov     dx, ax  
209 ;       call    PrintHex
210 ;       call    PrintNL
211
212
213
214         pop     es              ;
215         pop     bx
216         pop     si
217         pop     cx
218         
219         ; on to next sector
220         inc     word [sec_count]
221
222
223         ; update the low->high copy table for the bios
224 ;       mov     ax, word [bootsect_src_base] ;
225 ;       add     ax, 512
226 ;       mov     dx,ax;
227 ;       call    PrintHex
228 ;       adc     byte [bootsect_src_base+2], 0
229 ;       mov     word [bootsect_src_base],ax
230
231         mov     ax, word [bootsect_dst_base] ;
232         add     ax, 512
233         adc     byte [bootsect_dst_base+2], 0
234         mov     word [bootsect_dst_base],ax
235         
236         ; have we loaded all of the sectors?
237
238         mov     bx, word [max_sector]
239         cmp     word [sec_count], bx
240
241
242 .stall
243 ;       jmp     .skip
244         jl      .again2
245
246 .skip
247         ; Now we've loaded the setup code and the kernel image.
248         ; Jump to setup code.
249         jmp     SETUPSEG:0
250
251 ; Read a sector from the floppy drive.
252 ; This code (and the rest of this boot sector) will have to
253 ; be re-written at some point so it reads more than one
254 ; sector at a time.
255 ;
256 ; Parameters:
257 ;     - "logical" sector number   [bp+8]
258 ;     - destination segment       [bp+6]
259 ;     - destination offset        [bp+4]
260 ReadSector:
261         push    bp                      ; set up stack frame
262         mov     bp, sp                  ; "
263         pusha                           ; save all registers
264
265 %if 0
266 ; debug params
267         mov     dx, [bp+8]
268         call    PrintHex
269         call    PrintNL
270         mov     dx, [bp+6]
271         call    PrintHex
272         call    PrintNL
273         mov     dx, [bp+4]
274         call    PrintHex
275         call    PrintNL
276 %endif
277
278         ; Sector = log_sec % SECTORS_PER_TRACK
279         ; Head = (log_sec / SECTORS_PER_TRACK) % HEADS
280         mov     ax, [bp+8]              ; get logical sector number from stack
281         xor     dx, dx                  ; dx is high part of dividend (== 0)
282         mov     bx, SECTORS_PER_TRACK   ; divisor
283         div     bx                      ; do the division
284         mov     [sec], dx               ; sector is the remainder
285         and     ax, 1                   ; same as mod by HEADS==2 (slight hack)
286         mov     [head], ax
287
288         ; Track = log_sec / (SECTORS_PER_TRACK*HEADS)
289         mov     ax, [bp+8]              ; get logical sector number again
290         xor     dx, dx                  ; dx is high part of dividend
291         mov     bx, SECTORS_PER_TRACK*2 ; divisor
292         div     bx                      ; do the division
293         mov     [track], ax             ; track is quotient
294
295 %if 0
296 ; debugging code
297         mov     dx, [sec]
298         call    PrintHex
299         call    PrintNL
300         mov     dx, [head]
301         call    PrintHex
302         call    PrintNL
303         mov     dx, [track]
304         call    PrintHex
305         call    PrintNL
306 %endif
307
308         ; Now, try to actually read the sector from the floppy,
309         ; retrying up to 3 times.
310
311         mov     [num_retries], byte 0
312
313 .again:
314         mov     ax, [bp+6]              ; dest segment...
315         mov     es, ax                  ;   goes in es
316         mov     ax, (0x02 << 8) | 1     ; function = 02h in ah,
317                                         ;   # secs = 1 in al
318         mov     bx, [track]             ; track number...
319         mov     ch, bl                  ;   goes in ch
320         mov     bx, [sec]               ; sector number...
321         mov     cl, bl                  ;   goes in cl...
322         inc     cl                      ;   but it must be 1-based, not 0-based
323         mov     bx, [head]              ; head number...
324         mov     dh, bl                  ;   goes in dh
325         xor     dl, dl                  ; hard code drive=0
326         mov     bx, [bp+4]              ; offset goes in bx
327                                         ;   (es:bx points to buffer)
328         ; Call the BIOS Read Diskette Sectors service
329         int     0x13
330         
331         ; If the carry flag is NOT set, then there was no error
332         ; and we're done.
333         jnc     .done
334
335         ; Error - code stored in ah
336         mov     dx, ax
337         call PrintHex
338         inc     byte [num_retries]
339         cmp     byte [num_retries], 3
340         jne     .again
341
342         ; If we got here, we failed thrice, so we give up
343         mov     dx, 0xdead
344         call    PrintHex
345 .here:  jmp     .here
346
347 .done:
348         popa                            ; restore all regisiters
349         pop     bp                      ; leave stack frame
350         ret
351
352 ; Include utility routines:
353 ;%include "util.asm"
354 ; REPLACED WITH FOLLOWING WHICH MUST BE COMPILED 16 FOR USE IN THIS CODE
355 PrintHex:
356         pusha
357         mov   cx, 4             ; 4 hex digits
358 .PrintDigit:
359         rol   dx, 4             ; rotate so that lowest 4 bits are used
360         mov   ax, 0E0Fh         ; ah = request, al = mask for nybble
361         and   al, dl
362         add   al, 90h           ; convert al to ascii hex (four instructions)
363         daa                     ; I've spent 1 hour to understand how it works..
364         adc   al, 40h
365         daa
366         int   10h
367         loop  .PrintDigit
368         popa
369         ret
370
371 ; Print a newline.
372 PrintNL:                        ; print CR and NL
373         push    ax
374         mov     ax, 0E0Dh       ; CR
375         int     10h
376         mov     al, 0Ah         ; LF
377         int     10h
378         pop     ax
379         ret
380
381
382
383 ; ----------------------------------------------------------------------
384 ; Variables
385 ; ----------------------------------------------------------------------
386
387 ; These are used by ReadSector
388 head: dw 0
389 track: dw 0
390 sec: dw 0
391 num_retries: db 0
392
393 ; Used for loops reading sectors from floppy
394 sec_count: dw 0
395 max_sector: dw 0
396
397
398
399
400 bootsect_gdt:
401         dw      0,0,0,0
402         dw      0,0,0,0
403 bootsect_src:
404         dw      0xffff                
405 bootsect_src_base:
406         db      0,0x20,0x08             ;       ! base = 0x082000 
407         db      0x93            ;       ! typbyte
408         dw      0               ;       ! limit16,base24 =0
409 bootsect_dst:
410         dw      0xffff
411 bootsect_dst_base:
412         db      0,0,0x10        ;       ! base = 0x100000
413         db      0x93            ;       ! typbyte
414         dw      0               ;       ! limit16,base24 =0
415         dw      0,0,0,0         ;       ! BIOS CS
416         dw      0,0,0,0         ;       ! BIOS DS
417
418
419 ; Padding to make the PFAT Boot Record sit just before the BIOS signature.
420 ;Pad_From_Symbol PFAT_BOOT_RECORD_OFFSET, BeginText
421
422 ; PFAT boot record
423 ; Describes how to load the setup program and kernel.
424 ; The default values are appropriate for creating a boot
425 ; floppy by concatenating the boot sector, setup program,
426 ; and kernel image.  The buildFat program will change
427 ; these values if the boot floppy is formatted as a PFAT
428 ; filesystem.
429         dw      0
430         dw      0
431
432         dw      0
433         dw      0
434
435         dw      0
436         dw      0
437
438         dw      0
439         dw      0
440
441         dw      0
442         dw      0
443
444 ;; part of pfat boot record
445 setupStart:             
446         dw      1                       ; by default, setup is at first sector  
447
448 ;; part of pfat boot record
449 setupSize:
450         dw      NUM_SETUP_SECTORS       ; number of sectors in setup
451
452 ;; part of pfat boot record
453 kernelStart:
454         dw      1+NUM_SETUP_SECTORS     ; default start sector for kernel
455
456 ;; part of pfat boot record
457 kernelSize:
458         dw      NUM_KERN_SECTORS
459
460         ;; part of pfat boot record
461 vmStart:
462         dw      1+NUM_SETUP_SECTORS+NUM_KERN_SECTORS
463         ;; part of pfat boot record
464
465 vmSize:
466         dw      NUM_VM_KERNEL_SECTORS
467
468
469         ; Finish by writing the BIOS signature to mark this as
470 ; a valid boot sector.
471 Pad_From_Symbol BIOS_SIGNATURE_OFFSET, BeginText
472 Signature   dw 0xAA55   ; BIOS controls this to ensure this is a boot sector