Goto sanos source index
;
; cdemboot.asm
;
; CD-ROM 1.44 MB Floppy Emulation Boot sector
;
; Copyright (C) 2002 Michael Ringgaard. All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions
; are met:
;
; 1. Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; 2. Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; 3. Neither the name of the project nor the names of its contributors
; may be used to endorse or promote products derived from this software
; without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
; SUCH DAMAGE.
;
OSLDRSEG equ 0x9000
OSLDRBASE equ (OSLDRSEG * 16)
OSLDRSTART equ 8
OSLDRSIZE equ 32
; The image is the first 512K of the 1.44 MB emulated floppy device. The first
; sector of the image is the boot sector.
IMGSTART equ 1
IMGSEG equ 0x7E0
IMGSIZE equ (512 * 2) - 1
ORG 0x7c00
BITS 16
SECTION .text
; Entry point for initial bootstap code
boot:
jmp short start
nop
nop
db 'SANOS '
ldrsize dw OSLDRSIZE
ldrstrt dd OSLDRSTART
start:
; Setup initial environment
jmp 0:start1
start1:
cli
mov ax, cs
mov ds, ax
mov ss, ax
mov sp, 0x7c00
sti
; Save boot drive
mov [bootdrv], dl
; Display boot message
mov si, bootmsg
call print
readimg:
; Get boot drive geometry
mov dl, [bootdrv]
mov ah, 8
xor di, di
mov es, di
int 0x13
and cl, 0x3F
mov byte [sectors], cl
inc dh
mov byte [heads], dh
; Load disk image from emulated floppy
loadnext:
xor eax, eax
mov ax, [sectno] ; eax = image sector number
mov bx, ax
shl bx, 5 ; 512/16 segments per sector
add bx, IMGSEG
mov es, bx ; es = segment for next image sector
mov di, IMGSIZE
sub di, ax ; di = number of image sectors left to read
mov cx, [sectno] ; make sure we do not cross a 64KB boundary
and cx, 0x7F
neg cx
add cx, 0x80
cmp cx, di
jg loadnext1
mov di, cx
loadnext1:
mov ebx, IMGSTART ; eax = LBA of next image sector
add eax, ebx
call readsectors
mov ax, [sectno] ; update next image sector to read
add ax, di
mov [sectno], ax
cmp ax, IMGSIZE
jnz loadnext
; Copy os loader from ram boot image
push ds
mov cx, [ldrsize] ; cx = number of bytes to copy
shl cx, 9 ; convert from sectors to bytes
mov eax, [ldrstrt] ; ds = loader start segment
shl eax, 5 ; convert from sectors to segments
add eax, 0x7c0
mov ds, ax
mov ax, OSLDRSEG ; es = loader segment
mov es, ax
xor di, di
xor si, si
cld ; copy os loader from boot image
rep movsb
pop ds
; Call real mode entry point in os loader
mov ax, OSLDRSEG
mov ds, ax
add ax, [0x16] ; cs
push ax
push word [0x14] ; ip
mov dl, 0xFD ; boot drive (0xFD for CD emulation)
mov ebx, 0x7C00 ; RAM disk image
retf
; Read sectors from boot drive
; input:
; eax = LBA
; di = maximum sector count
; es = segment for buffer
; output:
; di = sectors read
readsectors:
; Convert LBA to CHS
cdq ; edx = 0
movzx ebx, word [sectors]
div ebx ; eax = track, edx = sector - 1
mov cx, dx ; cl = sector - 1, ch = 0
inc cx ; cl = sector number
xor dx, dx
mov bl, [heads]
div ebx
mov dh, dl ; head
mov dl, [bootdrv] ; boot drive
xchg ch, al ; ch = low 8 bits of cylinder number, al = 0
shr ax, 2 ; al[6:7] = high two bits of cylinder, ah = 0
or cl, al ; cx = cylinder and sector
; Determine number of sectors to read
mov al, cl
mov ah, 0
add ax, di ; ax = last sector to xfer
cmp ax, [sectors]
jbe readall
mov ax, [sectors] ; read to end of track
inc ax
sub al, cl
push ax
jmp read
readall:
mov ax, di ; we can read all sectors
push ax
jmp read
readagain:
pusha
mov al, '#' ; print # to mark errror
call printchar
mov ax, 0 ; reset disk system
mov dx, 0
int 0x13
popa
read:
mov ah, 2 ; read sector using bios
xor bx, bx
int 0x13
jc readagain
pop di
ret
; Print string to console
; si = ptr to first character of a null terminated string
print:
push ax
cld
nextchar:
mov al, [si]
cmp al, 0
je printdone
call printchar
inc si
jmp nextchar
printdone:
pop ax
ret
; Print a single character to the console
; al = character to be printed
printchar:
mov ah, 0x0e
int 0x10
ret
; Variables
sectno dw 0
sectors dw 0
heads dw 0
bootdrv db 0
; Message strings
bootmsg:
db 'Loading boot image from CD-ROM... ', 0
; Boot signature
times 510-($-$$) db 0
dw 0xAA55