flat assembler
Message board for the users of flat assembler.

Index > OS Construction > Finding the Volume Descriptor

Author
Thread Post new topic Reply to topic
AnonymousUser



Joined: 25 Jul 2014
Posts: 32
AnonymousUser
I am creating a BootLoader that boots from a CD and I am having trouble discovering how to find the start of the root Directory on the Disk here is my boot code:
Code:
BITS   16

ORG  0x00

Start: jmp main


;Colors for text
%DEFINE TEAL 0x03
%DEFINE RED 0x04
%DEFINE PURPLE 0x05
COL: db 0
ROW:  db 0

;macro for print
%macro Print 2
pusha
    xor ax, ax
    xor dx, dx
    mov dh, BYTE[ROW];puts the row into the dh register
    mov dl, BYTE[COL]
    xor bx, bx
    mov bl, %2
    mov si, %1
    call cPrint
    mov BYTE[COL], dl
 ;saves the rows for the next time we need to print
popa
%endmacro

Print_ln:

pusha   
    mov dh, BYTE[ROW]          
    mov ah, 0x02            ;set cursor pos
    mov bh, 0x00            ;page 00
    inc dh                  ;row 00
    mov dl, 0x00            ;col. 00    
    int 0x10
    mov BYTE[ROW], dh
    mov BYTE[COL], 0
    popa


ret

cPrint:                   ; Routine: output string in SI to screen


 .top:
    ;Paramaters for Input 
    mov ah, 09h             ; Must be 9 to print color
    mov cx, 0x01            ;x position
    lodsb                   ; Get character from string
    test al, al
    je .done                ; If char is zero, end of string
    int 0x10                 ; Otherwise, print it

    mov ah, 0x02            ;set cursor position
    mov bh, 0x00            ;page
    inc dl      ;column
    int 0x10                ;changes the cursor position so the next char can be written at the new location
    jmp .top

 .done:
    ret

;clears the screen and sets the cursor position to the top left 
 clear:
    mov ah, 0x0F            ;get current video mode
    mov al, 0x00            ;reset register
    int 0x10                ;get video mode
    mov ah, 0x00            ;set video mode
    int 0x10                ;reset screen
    mov ah, 0x02            ;set cursor pos
    mov bh, 0x00            ;page 00
    mov dh, 0x00            ;row 00
    mov dl, 0x00            ;col. 00
    int 0x10                ;set pos
ret



;CMPSB compares the byte at [DS:SI] or [DS:ESI] with the byte at [ES:DI] 
;or [ES:EDI], 
;and sets the flags accordingly. It then increments or decrements (depending 
;on the direction flag: increments
; if the flag is clear, decrements if it is set) SI and DI (or ESI and EDI).
Read_Sectors:  
        ;/* Read the sector into memory. */

        .ForLoop:
            mov     ah,042h
            xor     al,al
            mov     si, DiskAddressPacket
            mov     dl, [CDDriveNumber]
            int     013h
        jnc    .Success     ; /* read error? */

        Print Read_Sector_Error_MSG, RED

        cli
        hlt

.Success:
        Print Progress_MSG , PURPLE
        inc WORD[DiskAddressPacket.SectorsToRead]

        loop .ForLoop

ret


main:

    cli
    mov ax, 0x07c0  ;adjust the segment registers
    mov ds, ax
    mov gs, ax
    mov fs, ax


Create_Stack:
    xor ax, ax
    mov es, ax
    mov ss, ax
    mov sp ,0x0FFFE
    sti
    mov es, 0x200

    mov     [CDDriveNumber],dl
    call clear


    Print W_MSG, TEAL;prints the loading message in colour
    call Print_ln

    LOAD_ROOT:
    ;first calculate the start of the Root directory
     mov WORD[DiskAddressPacket.Offset], 0x01000
     mov cx, 0x01
     call Read_Sectors

     call Print_ln
     Print READ_SUCCESS, TEAL
     call Print_ln




    cli
    hlt



Sector_Size: dw 512                     
CDDriveNumber: db 80h
CD_bytes_per_sect:         dw    0
CD_root_dir_size:          dd    0
CD_root_dir_sectors:       dw    0
CD_root_dir_start:         dd    0
CD_file_size:              dd    0
CD_file_sectors:           dw    0
CD_file_start:             dd    0
CD_desc_sector:            dd    0
CD_Signature:              db "\2CD001"
CD_FILE_VER:               db 0x01

;Disk Address Packet


DiskAddressPacket:          db 16,0 
.SectorsToRead:             dw 1                              ; Number of sectors to read (read size of OS) 
.Offset:                    dw 0                              ; Offset :0000 
.Segment:                   dw 0200h                          ; Segment 0200
.End:                       dq 16                             ; Sector 16 or 10h on CD-ROM 

RETURN: DB 0

W_MSG: db "Loading Z-Boot", 0
Stage2: db "STAGE2 BIN"
Read_Sector_Error_MSG: db "Error, failed to read sector",0
READ_SUCCESS: db "Sectors read in correctly",0
Progress_MSG: db ".",0
FILE_NOT_FOUND: db "Error, file not found",0
FOUND: db "Found", 0
times 2046 - ($ - $$) db 0; padd out the rest of the file to 0
DW 0xAA55
    

I saw some code that did something like this to find the Volume descriptor I have a feeling you need that to find the root directory but I can't put my finger on it here is the code that does that:
Code:
get_next_desc: 
        ;/* Read the sector in memory at 0000:1000. */
        mov     [desc_sector],eax
        mov     bx,01000h
        mov     cx,1
        call    read_sectors

        ;/* Check for the signature "\2CD001" at the beginning of the descriptor. */
        mov     si, cd_signature
        mov     di,01000h
        mov     cx,6
        cmpsb
        je      found_desc

        ;/* Check if we have looked in all the descriptors of volume. */
        cmp     byte [es:0x1000],0FFh
        jne     next_desc

        ;/* We looked in all sessions of the disk, and the OS image wasn't found.
        ;   We display an error message on the screen and then prompts the user to
         ;  press a key to restart the computer. */
        mov     si, msg_file_not_found
        call    print_string
        jmp     reboot

next_desc:
    

Here is what I use to assemble my code:
Code:
nasm ZerothStage.asm -o ZerothStage.bin

mkisofs -b ZerothStage.bin -no-emul-boot -o BootLoader.iso ./
    

_________________
Thanks in advance
Post 25 Jul 2014, 17:00
View user's profile Send private message Reply with quote
AnonymousUser



Joined: 25 Jul 2014
Posts: 32
AnonymousUser
Nevermind I got it apparently I needed to load the segment offset address from the DAP into ES:DI and look for the Volume descriptor there
here is what i used to solve it if anyone is interested.
Code:
        mov es, WORD[DiskAddressPacket.Segment]
        mov di, WORD[DiskAddressPacket.Offset]
        
        xor bx, bx
        .top
                mov al, BYTE[ES:DI+BX]
                cmp al, ' '
                je .Done
                mov ah, 0xE
                int 0x010
                inc bx
        jmp .top
        
        .Done:  
    
Post 25 Jul 2014, 19:09
View user's profile Send private message Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 559
smiddy
Have tried using FASM? Smile

Here's some code for comparison:

Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                                  ;;
;; Project          :   smiddyOS (CD-ROM Booter)                                    ;;
;; Author           :   smiddy                                                      ;;
;; Website          :                                                               ;;
;; Date             :   March 8, 2012                                               ;;
;; Quick Information:   Compact Disc bootloader beta to load bootable software.     ;;
;; Filename         :   cdboot2.asm                                                 ;;
;; Assembler Command:   Using FASMW IDE                                             ;;
;;                                                                                  ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                                  ;;
;; Useage: Using CDBOOT2.BIN as the boot loader from the created ISO from the       ;;
;;         CD-ROM creating CDROM.ASM from within FASMW IDE.                         ;;
;;                                                                                  ;;
;;         See CDROM.ASM for further details.                                       ;;
;;                                                                                  ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                                  ;;
;; v1.00  - Beta release; CD-ROM compatible booter, capable of booting bootable     ;;
;;          software, in this case SMIDDYOS.EXE. Change the file name to one you    ;;
;;          wish to load instead. The loader expects to be booted at 0060:0000      ;;
;;          (600h linear) and the bootable software gets loaded at 0200:0000        ;;
;;          (2000h linear) which is launched from 0202:0000 (2020h linear).         ;;
;;                                                                                  ;;
;;          Limitations include that the boot file needs to be in the root          ;;
;;          directory and the root directory can not be longer than one CD sector   ;;
;;          (2048 bytes) in size.                                                   ;;
;;                                                                                  ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;   format binary as "bin"               ; Tell FASM to make an BIN image (removed for ISO building)

   ORG 0

BootSector:                             ; Label in order to determine size of code for
                                        ; padding at the end.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Start Boot Procedure                                                             ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Begin:                                  ; Begining of instructions

    CLI                                 ; Turn off intterrupts
    mov ax,0060h                        ; Boot Segment (no need to copy there)
    mov ds,ax
    mov es,ax
    MOV [CDDriveNumber],DL              ; Save boot drive, right away
    MOV AX,7000h
    MOV DS,AX                           ; Segment of saved variables for SmiddyOS
    MOV BX,530h                         ; Offset of boot drive saved variable
    MOV [DS:BX],DL                      ; Save the boot drive for SmiddyOS use later
    MOV AX,60h
    MOV DS,AX                           ; Reset segment
    XOR AX,AX                           ; Zero out the stack segment
    MOV SS,AX
    MOV SP,5FEh                         ; 0000:05FE is the stack for the loader
    STI                                 ; Turn interrupts back on

    MOV SI,WelcomeMessage               ; Tell everyone hello
    CALL PrintString                    ; Print the welcome message
    MOV SI,TheEndOfTheLine              ; Go to the next line
    CALL PrintString

    mov si,DriveNumberReported
    call PrintString
    mov al,[CDDriveNumber]
    mov cl,8
    call ToHex
    mov si,HexBuffer
    call PrintString
    MOV SI,TheEndOfTheLine              ; Go to the next line
    CALL PrintString


    MOV AL,[CDDriveNumber]              ; Load drive number in for comparison
    CMP AL,0                            ; Compare to known BAD drive number for CD/DVD/BD
    JE Failure                          ; If it is, it failed.

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;; Get Status (Bootable CD-ROM)
    ;;
    ;; Call with: AX = 4B01H
    ;; DL = Drive number
    ;; DS:SI = Empty specification packet (needs to be 13h in size)
    ;;
    ;; Return: If Function Successful,
    ;; Carry Flag = Clear
    ;;
    ;; If Function Unsuccessful,
    ;; Carry Flag = Set
    ;; AX = Status code
    ;;
    ;; DS:SI = Specification packet filled
    ;;       Offset Size Description
    ;;       00h    db   size of packet in bytes (13h)
    ;;       01h    db   boot media type
    ;;                   Bit(s) Description
    ;;                   3-0    media type.
    ;;                   0000   no emulation.
    ;;                   0001   1.2M diskette.
    ;;                   0010   1.44M diskette.
    ;;                   0011   2.88M diskette.
    ;;                   0100   hard disk
    ;;                   Other reserved
    ;;                   5-4    reserved (0)
    ;;                   6      image contains ATAPI driver
    ;;                   7      image contains SCSI driver(s)
    ;;       02h    db   drive number
    ;;                   00h floppy image
    ;;                   80h bootable hard disk
    ;;                   81h-FFh nonbootable or no emulation drive
    ;;       03h    db   CD-ROM controller number
    ;;       04h    dd   Logical Block Address (LBA) of disk image to emulate
    ;;       08h    dw   device specification (same as boot media type plus)
    ;;                   (IDE) bit 0: Drive is slave instead of master
    ;;                   (SCSI)  bits 7-0: LUN and PUN
    ;;                   bits 15-8: Bus number
    ;;       0Ah    dw   segment of 3K buffer for caching CD-ROM reads
    ;;       0Ch    dw   load segment for initial boot image (if 0000h, load at segment 07C0h; only valid for INT 13h/AH=4Ch)
    ;;       0Eh    dw   number of 512-byte virtual sectors to load (only valid for INT 13h/AH=4Ch)
    ;;       10h    db   low byte of cylinder count (for INT 13/AH=08h)
    ;;       11h    db   sector count, high bits of cylinder count (for INT 13h/AH=08h)
    ;;       12h    db   head count (for INT 13h/AH=08h)
    ;;
    ;; Comments:
    ;;
    ;; The Function is used to get the status of the CD/DVD/BD. This function is called
    ;; first for "no emulation" booting of optical media. If the Function is successful,
    ;; the carry flag is clear, else carry flag is set and AX register returns status
    ;; code.
    ;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

GetBootedCDStatus:

    MOV DL,[CDDriveNumber]              ; Prepare to read CD-ROM, load boot drive
    MOV AH,4Bh                          ; Use function 4Bh
    MOV AL,1
    MOV SI,DiskResultsBuffer            ; Results buffer to load
    INT 13h                             ; Call Check Extensions Present?

    JC Failure                          ; Need to engage the Failure Procedure

    MOV AH,255                          ; Load proposed error code (255 is our failure code for drive number miss detected)
    MOV DL,[DiskResultsBuffer+2]        ; Load resultant drive information
    CMP [CDDriveNumber],DL              ; Compare to see if they are the same (they should be)
    JNE Failure                         ; If they are not, Failure

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;; More information can be gathered here if needed later, not needed at this time.
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;; Check INT 13h Extensions Present
    ;;
    ;; Call with: AH = 41H
    ;; DL = Drive number (80h - FFh; but we're interested in CDs for this exercise)
    ;; BX = 55AAh (Signature?)
    ;;
    ;; Return: If Function Successful,
    ;; Carry Flag = Clear
    ;; BX = AA55h if installed
    ;; AH = major version of extensions
    ;;    01h = 1.x
    ;;    20h = 2.0 / EDD-1.0
    ;;    21h = 2.1 / EDD-1.1
    ;;    30h = EDD-3.0
    ;; AL = internal use
    ;; CX = API subset support bitmap
    ;;      1 - Device Access using packet structure (INT 13h AH=42h-44h,47h,48h)
    ;;      2 - Drive Locking and Ejecting (INT 13h AH=45h,46h,48h,49h,INT 15h AH=52h)
    ;;      4 - Enhanced Disk Drive Support (INT 13h AH=48h,AH=4Eh)
    ;; DH = extension version (v2.0+ ??? -- not present in 1.x)
    ;;
    ;; If Function Unsuccessful,
    ;; Carry Flag = Set
    ;; AH = 01h (invalid function)
    ;;
    ;; Comments:
    ;;
    ;; The Function is used to see if INT 13h extensions are present (not really
    ;; needed if you can do the previous function, right?)
    ;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

GetINT13hExtenstions:

    MOV DL,[CDDriveNumber]              ; Prepare to read CD-ROM, load boot drive
    MOV AH,41h                          ; Use function 41h: Check Extensions Present
    MOV BX,55AAh                        ; Signature?
    INT 13h                             ; Call Check Extensions Present? (This makes no sense if you try INT 13h Function 4B01h, but details are
                                        ; provided upon return if CF isn't set)

    JC Failure                          ; Nope, get out of here...

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;; Extended Read Function
    ;;
    ;; Call with AH=42h
    ;; DL = drive number
    ;; DS:SI = Disk Address Packet (DAP)
    ;;       Offset Size Description
    ;;       00h    db   Size of packet (10h or 18h; we're using 10h here, see below)
    ;;       01h    db   Reserved (0)
    ;;       02h    dw   Number of sectors to read (max 007Fh for Phoenix EDD)
    ;;       04h    dd   Initial segment:offset where to load the read in sector(S)
    ;;       08h    dq   starting absolute sector number (for non-LBA devices, compute as (Cylinder*NumHeads + SelectedHead) * SectorPerTrack + SelectedSector - 1
    ;;       10h    dq   (EDD-3.0, optional) 64-bit flat address of transfer buffer; used if dd at 04h is FFFFh:FFFFh
    ;;
    ;; Return: If Function Successful,
    ;; Carry Flag = Clear
    ;; AH = 00h
    ;;
    ;; If Function Unsuccessful,
    ;; Carry Flag = Set
    ;; AH = Error code
    ;;
    ;; Error code:
    ;;   00h    successful completion
    ;;   01h    invalid function in AH or invalid parameter
    ;;   02h    address mark not found
    ;;   03h    disk write-protected
    ;;   04h    sector not found/read error
    ;;   05h    reset failed (hard disk)
    ;;   05h    data did not verify correctly (TI Professional PC)
    ;;   06h    disk changed (floppy)
    ;;   07h    drive parameter activity failed (hard disk)
    ;;   08h    DMA overrun
    ;;   09h    data boundary error (attempted DMA across 64K boundary or >80h sectors)
    ;;   0Ah    bad sector detected (hard disk)
    ;;   0Bh    bad track detected (hard disk)
    ;;   0Ch    unsupported track or invalid media
    ;;   0Dh    invalid number of sectors on format (PS/2 hard disk)
    ;;   0Eh    control data address mark detected (hard disk)
    ;;   0Fh    DMA arbitration level out of range (hard disk)
    ;;   10h    uncorrectable CRC or ECC error on read
    ;;   11h    data ECC corrected (hard disk)
    ;;   20h    controller failure
    ;;   31h    no media in drive (IBM/MS INT 13 extensions)
    ;;   32h    incorrect drive type stored in CMOS (Compaq)
    ;;   40h    seek failed
    ;;   80h    timeout (not ready)
    ;;   AAh    drive not ready (hard disk)
    ;;   B0h    volume not locked in drive (INT 13 extensions)
    ;;   B1h    volume locked in drive (INT 13 extensions)
    ;;   B2h    volume not removable (INT 13 extensions)
    ;;   B3h    volume in use (INT 13 extensions)
    ;;   B4h    lock count exceeded (INT 13 extensions)
    ;;   B5h    valid eject request failed (INT 13 extensions)
    ;;   B6h    volume present but read protected (INT 13 extensions)
    ;;   BBh    undefined error (hard disk)
    ;;   CCh    write fault (hard disk)
    ;;   E0h    status register error (hard disk)
    ;;   FFh    sense operation failed (hard disk)
    ;;
    ;; Initial DAP:
    ;;
    ;;   db 10h       - Initial Volume Descriptor, which has the important data we need
    ;;                  to get to the root directory where our OS is stored.
    ;;   db 0         - Unused, should be zero
    ;;   dw 1         - Number of sectors to read (initial one should be one for Volume Descriptor)
    ;;   dd 0200:0000 - Initial segment:offset where to load the read in sector(S)
    ;;   dq 16        - Starting sector to read in, then we need to get to the root directory
    ;;
    ;; Comments:
    ;;
    ;; This functions is called three times: Initially to get the Initial
    ;; Volume Descriptor so we can find the root directory; then it gets used
    ;; again to read in the root directory, so we can scan for SmiddyOS; finally
    ;; once we recognize SmiddyOS we load it and jump to it, if all goes as it
    ;; should "on a good day" as expected (this is done in FindSmiddyOS).
    ;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    MOV DL,[CDDriveNumber]              ; Set it up again
    MOV AH,42h                          ; Read from drive function
    MOV SI,DiskAddressPacket            ; Load SI with address of the Disk Address Packet
    INT 13h                             ; Call read sector from drive
    JC Failure                          ; Nope, hosed, get out

    MOV ES,[DiskAddressPacket.Segment]  ; This sets up so we can start analyzing the data
    MOV DI,[DiskAddressPacket.Offset]   ; This sets up so we can start analyzing the data

    MOV BX,40                           ; Load BX with Volume Label offset (Check CDROM.ASM or ISO 9660)

VolumeLabelLoop:

    MOV CL,[ES:DI+BX]                   ; Grab a letter
    CMP CL,' '                          ; Is it a space? (Assumes end of string is space, may run out)
    JE .VolumeLabelDone                 ; Yes, we are done

    MOV [VolumeLabel+BX-40],CL
    INC BX
    JMP VolumeLabelLoop                 ; Need to compare BX to length of Volume Label on CD (32?)

.VolumeLabelDone:

    MOV byte [VolumeLabel+BX-40],0      ; End the string

    MOV EAX,[ES:DI+158]                 ; LBA of root directory, where all things start.
    MOV [DiskAddressPacket.End],EAX     ; Load packet with new address on CD of the root directory
    MOV DL,[CDDriveNumber]              ; Set it up again
    MOV AH,42h                          ; Read from drive function
    MOV SI,DiskAddressPacket            ; Load SI with address of the Disk Address
                                        ;    Packet
    INT 13h                             ; Call read sector from drive

    JC Failure                          ; Nope, hosed, get out

    CALL FindSmiddyOS
    MOV AH,0FEh                         ; If the FindSmiddyOS makes it back here,
                                        ;   then the file was not found

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Failure: Displays failure with an error code number.                            ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Failure:

    mov AL,AH                           ; Put the error into lowest bits
    mov cl,8                            ; only 8 bits
    call ToHex                          ; Get what is in the XX to display

    MOV SI,FailureMessage               ; reboot message
    CALL PrintString
    mov si,HexBuffer
    CALL PrintString
    MOV SI,AddTheHAtTheEnd
    CALL PrintString
    MOV SI,TheEndOfTheLine
    CALL PrintString
    mov SI,PressAnyKeyMessage
    CALL PrintString
    MOV AH,0                            ; Reboot on error
    INT 16h                             ; BIOS GetKey
    INT 19h                             ; BIOS Reboot

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; FindSmiddyOS: Locates SmiddyOS in the root directory of the CD/DVD/BD and launchs  ;;
;;               it if it finds it.                                                   ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

NumberOfSectorsToRead:   dd 0

FindSmiddyOS:

    MOV ES,[DiskAddressPacket.Segment]
    MOV DI,[DiskAddressPacket.Offset]

    MOV SI,DriveDisplayMessage
    CALL PrintString

    CMP byte [VolumeLabel],0
    JE .NoLabel

    MOV SI,VolumeLabel
    CALL PrintString
    JMP .LabelDone

.NoLabel:

    MOV SI,HasNoLabel
    CALL PrintString

.LabelDone:

    MOV SI,TheEndOfTheLine
    CALL PrintString
    MOV SI,TheEndOfTheLine
    CALL PrintString

.GrabDirectoryEntry:

    MOV AL,[ES:DI]                      ; Length of the current directory entry
    MOV [DirectoryEntrySize],AL

    MOV EAX,[ES:DI+2]                   ; Starting sector of directory entry
    MOV [FileSector],EAX

    MOV EAX,[ES:DI+10]                  ; Size of directory entry on CD/DVD/BD
    MOV [FileSize],EAX

    MOV AL,[ES:DI+32]                   ; File's name length (see El Torito of ISO:9660 or CDROM.ASM)
    MOV [FileNameLength],AL

    XOR BX,BX                           ; Initialize BX
    XOR CX,CX                           ; Initialize CX
    MOV SI,DI
    ADD SI,33
    MOV BX,FileNameEntry
    MOV AL,[FileNameLength]
    CMP AL,1                            ; Check to see if a dot or dotdot entry
    JE .DotAndDotDotEntries

.LoopFileNameEntry:                     ; Capture the filename entry for later manipulation

    MOV AL,[ES:SI]
    MOV [DS:BX],AL
    INC BX
    INC CX
    INC SI
    XOR AX,AX
    MOV AL,[FileNameLength]
    CMP CX,AX
    JB .LoopFileNameEntry

    MOV byte [DS:BX],0
    JMP .FileNameEntryDisplay

.DotAndDotDotEntries:

    MOV AL,[FileEntryNumber]
    CMP AL,0
    JA .DoDotDotEntry
    MOV word [FileNameEntry],'.'        ; First directory entry
    MOV byte [FileNameEntry+1],0        ; End the string with a termination
    JMP .FileNameEntryDisplay

.DoDotDotEntry:

    MOV word [FileNameEntry],'..'       ; Second directory entry
    MOV byte [FileNameEntry+2],0        ; End the string with a termination

.FileNameEntryDisplay:

    MOV SI,FileNameEntry
    PUSH DI
    MOV DI,FileName
    CALL StringCompare
    POP DI
    JC .EndOfTheLine


    MOV EAX,[FileSector]
    MOV [DiskAddressPacket.End],EAX     ; Save the starting sector into DAP
    MOV EAX,[FileSize]
    XOR EDX,EDX
    MOV EBX,2048
    DIV EBX
    INC EAX
    MOV [NumberOfSectorsToRead],EAX     ; This is the absolute number of sectors
                                        ;   to be read.
    CMP AX,32
    JA .UpdateSectorsToRead
    MOV [DiskAddressPacket.SectorsToRead],AX  ; Save number of sectors to read
    JMP .PassedTheUpdate

.UpdateSectorsToRead:

    MOV [DiskAddressPacket.SectorsToRead],word 32
    SUB [NumberOfSectorsToRead],dword 32

.PassedTheUpdate:

.ReadTheSectorsLoop:

    MOV DL,[CDDriveNumber]              ; Set it up again
    MOV AH,42h                          ; Read from drive function
    MOV SI,DiskAddressPacket            ; Load SI with address of the Disk Address Packet
    INT 13h                             ; Call read sector from drive
    JC Failure                          ; Nope, hosed, get out

    CMP [NumberOfSectorsToRead], dword 0
    JE .StartTheOperatingSystem

    MOV EAX,[DiskAddressPacket.SectorsToRead]   ; Add sectors read (32) to it, for the new
                                                ;   starting sector
    ADD [DiskAddressPacket.End],EAX     ; Update sector to start reading from on CD/DVD/BD
    MOV EBX,2048
    MUL EBX                             ; Update EAX with amount of space used
    SHR EAX,4                           ; Shift it right to update the segment to load next
    ADD [DiskAddressPacket.Segment], AX ; Segment to load next in memory
    CMP [NumberOfSectorsToRead],dword 32 ; Is this still too big (greater than 64k barrier?
    JAE .UpdateSectorsToRead            ; If so, need to load another 32 sectors

    MOV EAX,[NumberOfSectorsToRead]     ; Else
    MOV [DiskAddressPacket.SectorsToRead],AX ; We load what is left
    MOV [NumberOfSectorsToRead],dword 0 ; Zero out this bad boi!
    JMP .ReadTheSectorsLoop

.StartTheOperatingSystem:


    MOV DL,[CDDriveNumber]              ; Drive into DL for booting

    JMP     0202h:0h                    ; Start SmiddyOS (For standard DOS executeable)

.EndOfTheLine:

    MOV SI,TheEndOfTheLine
    CALL PrintString

    XOR CX,CX                           ; Prepare CX to do math for DI
    MOV CL,[DirectoryEntrySize]         ; Get the size of the directory entry
    ADD DI,CX                           ; Add that size to the DI to get to the next record
    CMP byte [ES:DI],0                  ; Is the next entry = 0?
    JE .End                             ; If so, we're at the end of the directory, move on

    XOR CX,CX
    MOV BX,FileNameEntry

.ClearFileNameEntry:

    MOV byte [DS:BX],0                  ; Erase the begining of the
    INC BX
    INC CX
    CMP CX,254
    JB .ClearFileNameEntry
    MOV byte [DS:BX],0
    INC byte [FileEntryNumber]
    JMP .GrabDirectoryEntry             ; If not, we have more processing to do

.End:

    RET

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PrintString                                                                      ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PrintString:

    PUSHA                               ; Save Registers

.Loop:

    LODSB                               ; Load SI into AL, increment SI one byte
    OR AL,AL                            ; AL = 0?
    JZ .Done                            ; If yes, get out
    MOV AH,0Eh
    MOV BH,0
    MOV BL,7                            ; character attribute
    INT 10h                             ; Display character in AL
    JMP .Loop                           ; Do it again

.Done:

    POPA                                ; Replace registers

    RET

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ToHex
;; Loads HexBuffer with ASCII corresponding to 8, 16, or 32 bit interger in
;;    hex.
;; Requires interger in AL, AX, or EAX depending on bit size
;; Requires the number of bits in the CL
;; Returns a full buffer or an empty buffer on error
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ToHex:

    pusha

    MOV BX,0                    ; Load BX with pointer offset
    MOV [TheEAX],EAX            ; Save the EAX
    MOV [TheCL],CL              ; Save the CL
    CMP CL,8                    ; Check for 8 bits
    JNE .Check16
    JMP .Loop1                  ; Start loading the buffer

.Check16:

    CMP CL,10h                  ; Check for 16 bits
    JNE .Check32
    JMP .Loop1                  ; Start loading the buffer

.Check32:

    CMP CL,20h                  ; Check for 32 bits
    JNE .ErrorBits

.Loop1:

    MOV EAX,[TheEAX]            ; Reload EAX with the converter
    SUB CL,4                    ; Lower bit count by 4 bits
    SHR EAX,CL

    AND AL,0Fh
    ADD AL,'0'
    CMP AL,'9'
    JBE .LoadBuff1
    ADD AL,'A'-'0'-10           ; Convert to "A" to "F"

    JMP .LoadBuff1

.Loop2:
    MOV EAX,[TheEAX]            ; Reload EAX again
    SUB CL,4                    ; Lower bit count by 8 bits
    SHR EAX,CL
    AND AL,0Fh
    ADD AL,'0'
    CMP AL,'9'
    JBE .LoadBuff2
    ADD AL,'A'-'0'-10           ; Convert A,B,C,D,E,F

    JMP .LoadBuff2

.LoadBuff1:

    MOV [HexBuffer+BX],AL       ; Load buffer with AL
    INC BX                      ; Increment buffer pointer
    JMP .Loop2                  ; Do next byte

.LoadBuff2:

    MOV [HexBuffer+BX],AL       ; Load buffer with AL
    INC BX                      ; Increment buffer pointer
    CMP CL,0                    ; Check if we're done
    JNE .Loop1                  ; Do next Byte

.ErrorBits:

    MOV AL,0
    MOV [HexBuffer+BX],AL       ; End the string with a zero

    popa

    RET

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; StringCompare                                                                   ;;
;;                                                                                 ;;
;;    Compares the equality of two strings, loaded in SI and DI.                   ;;
;;                                                                                 ;;
;;    Sets the CF if not the same.                                                 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

StringCompare:

    PUSH SI                             ; Save ESI to be restored at the end
    PUSH DI                             ; Save EDI to be restored at the end

.Loop:

    MOV AL,[SI]                         ; Grab byte from ESI
    MOV BL,[DI]                         ; Grab byte from EDI
    CMP AL,BL                           ; Compare if they are equal
    JNE .NotEqual                       ; They aren't equal

    CMP AL,0                            ; Both bytes are null
    JE .Done

    INC DI                              ; Increment EDI
    INC SI                              ; Increment ESI
    JMP .Loop                           ; Start looping

.NotEqual:

    STC                                 ; Set the carry flag to indicate failure
    JMP .End

.Done:

    CLC                                 ; Clear the carry flag to indicate success

.End:

    POP DI                              ; Restore EDI before returning to caller
    POP SI                              ; Restore ESI before returning to caller

    RET

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; StringLength                                                                    ;;
;;                                                                                 ;;
;;    Checks the length of the string in the SI and returns it in the AX.          ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

StringLength:

    XOR EAX,EAX

.Loop:

    CMP byte [ESI+EAX],0
    JE .End

    INC EAX
    JMP .Loop

.End:

    RET

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Program Data                                                                     ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

DirectoryEntrySize:         db 0
FileSector:                 dd 0
FileSize:                   dd 0
FileNameLength:             db 0
FileNameEntry:              TIMES 255 db ' '
FileEntryNumber:            db 0
DriveDisplayMessage:        db 'Volume in drive: ',0  ; Get label from Primary Volume Descriptor (loaded first)
HasNoLabel:                 db 'no label',0
FileNamePointer:            dw 0

DataSector:                 DW 0
CDDriveNumber:              db 0
RootDirectorySector         dd 0

FileName:                   DB 'SMIDDYOS.EXE',0                ; FAT Filename, 8.3, or 11 characters

WelcomeMessage:             db 13,10,'smiddy OS CD boot v1.00',225,13,10,0   ; Version of CD-Boot
FailureMessage:             db 'Failure: ',0
DriveNumberReported:        db 'Drive number reported: ',0
PressAnyKeyMessage:         db 'Press any key to reboot...',13,10,0
AddTheHAtTheEnd:            db 'h',0
TheEndOfTheLine:            db 13,10,0                        ; Used to print the end of the line string
SizeOfPacketInBytes:        db 'The size of packet in bytes: ',0
BootMediaType:              db 'The boot media type: ',0
DriveNumberFromPacket:      db 'Drive number from packet: ',0
VolumeLabel:                TIMES 33 db 0                     ; Where the volume label is stored

DiskAddressPacket:          db 16,0
.SectorsToRead:             dw 1                              ; Number of sectors to read (read size of OS)
.Offset:                    dw 0                              ; Offset :0000
.Segment:                   dw 0200h                          ; Segment 0200: currerntly, will change to 0200:0000 for loading SmiddyOS
.End:                       dq 16                             ; Sector 16 or 10h on CD-ROM

DiskResultsBuffer:          times 30 db 0                     ; Return buffer from int 13h ah=48h
HexBuffer:                  DB 0,0,0,0,0,0,0,0,0              ; Buffer for hex text string
TheEAX:                     dd 0                              ; Saves EAX
TheCL:                      db 0


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 512 Byte Code Boot Signature                                                     ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

TIMES 2046-($-BootSector)   DB 0
                            DW 0AA55h           ; Bootloading sector signature (for CD/DVD/BD) I am not sure this is needed for optical media booting.

    
Post 26 Jul 2014, 01:00
View user's profile Send private message Reply with quote
AnonymousUser



Joined: 25 Jul 2014
Posts: 32
AnonymousUser
Well From what I gather FASM is not all that different from NASM at least not like GAS. And I have seen your code and It has helped me figure out a lot of things. But I am still confused with the volume descriptor and Have a lot of Questions. First How am I supposed to find the root directory how would I go about finding it and then sifting through it to find the next file to load the OS or to do a second stage bootloader? I have been looking everywhere for answers but the NASM forum can only help me so much and I am just starting out with OS DEV.
here is my full code just in case people need to build it:
Code:
BITS   16

ORG  0x00

Start: jmp main


;Colors for text
%DEFINE TEAL 0x03
%DEFINE RED 0x04
%DEFINE PURPLE 0x05
COL: db 0
ROW:  db 0

;macro for print
%macro Print 2
pusha
        xor ax, ax
        xor dx, dx
        mov dh, BYTE[ROW];puts the row into the dh register
        mov dl, BYTE[COL]
        xor bx, bx
        mov bl, %2
        mov si, %1
        call cPrint
        mov BYTE[COL], dl
 ;saves the rows for the next time we need to print
popa
%endmacro

Print_ln:

pusha   
        mov dh, BYTE[ROW]          
    mov ah, 0x02            ;set cursor pos
    mov bh, 0x00            ;page 00
    inc dh                      ;row 00
    mov dl, 0x00            ;col. 00    
        int 0x10
        mov BYTE[ROW], dh
        mov BYTE[COL], 0
        popa


ret

cPrint:                   ; Routine: output string in SI to screen


 .top:
        ;Paramaters for Input 
    mov ah, 09h             ; Must be 9 to print color
    mov cx, 0x01                        ;x position
    lodsb                   ; Get character from string
    test al, al
    je .done                ; If char is zero, end of string
    int 0x10                 ; Otherwise, print it

    mov ah, 0x02                        ;set cursor position
    mov bh, 0x00                        ;page
    inc dl              ;column
    int 0x10                            ;changes the cursor position so the next char can be written at the new location
    jmp .top

 .done:
    ret

;clears the screen and sets the cursor position to the top left 
 clear:
    mov ah, 0x0F            ;get current video mode
    mov al, 0x00            ;reset register
    int 0x10                ;get video mode
    mov ah, 0x00            ;set video mode
    int 0x10                ;reset screen
    mov ah, 0x02            ;set cursor pos
    mov bh, 0x00            ;page 00
    mov dh, 0x00            ;row 00
    mov dl, 0x00            ;col. 00
    int 0x10                ;set pos
ret




Read_Sectors:  
        ;/* Read the sector into memory. */
       
                .ForLoop:
                        mov     ah,042h
                        xor     al,al
                        mov     si, DiskAddressPacket
                        mov     dl, [CDDriveNumber]
                        int     013h
        jnc    .Success         ; /* read error? */

        Print Read_Sector_Error_MSG, RED
                
                cli
                hlt

.Success:
                Print Progress_MSG , PURPLE
                inc WORD[DiskAddressPacket.SectorsToRead]
                
        loop    .ForLoop
                call Print_ln
ret


main:

        cli
        mov ax, 0x07c0  ;adjust the segment registers
        mov ds, ax
        mov gs, ax
        mov fs, ax


Create_Stack:
        xor ax, ax
        mov es, ax
        mov ss, ax
        mov sp ,0x0FFFE
        sti
        
        mov     [CDDriveNumber],dl
        call clear


        Print W_MSG, TEAL;prints the loading message in colour
        call Print_ln
        

        ;First find the Signature of the CD 
        LOAD_SIGNATURE:
        mov cx, 0x04
        call Read_Sectors
        
        Print READ_SUCCESS, TEAL
        call Print_ln
        
        ;load the Volume descriptor to the Volume variable
        mov es, WORD[DiskAddressPacket.Segment]
        mov di, WORD[DiskAddressPacket.Offset]
        
        xor bx, bx
        .top:
                mov al, BYTE[ES:DI+BX]
                mov BYTE[VOLUME+BX], al
                
                inc bx
                cmp al, ' '
                je .Done
                jmp .top
        .Done:

        ;see if the Volume descriptor contains the Signature
        xor BX, BX
        add BX, 0x01
        xor cx, cx
        .toploop:
        xor ax, ax
        mov al, BYTE[VOLUME+BX] 
        cmp al, BYTE[CD_Signature+BX-1]
        je .FOUND_IT
        jmp .Done2
        inc CX
        .FOUND_IT:
        Print Progress_MSG, PURPLE
        inc BX

        jmp .toploop
        
        .Done2:
        cmp CX, 0
        jne FAIL
        call Print_ln
        
        Print FOUND_CD, TEAL
        jmp LOAD_ROOT
        FAIL:
        Print FILE_NOT_FOUND, RED
        
        ;Now Load the Root Directory from the Volume Descriptor
        LOAD_ROOT:
                mov es, WORD[DiskAddressPacket.Segment]
                mov di, WORD[DiskAddressPacket.Offset]
                
                call Print_ln
                MOV AL,[ES:DI]                      ; Length of the current directory entry 
                MOV [CD_dir_curr_size],AL 
                Print CD_dir_curr_size, TEAL
                call Print_ln
                
                MOV EAX,[ES:DI+2]                   ; Starting sector of directory entry 
                MOV [CD_root_dir_start],EAX 
                Print CD_root_dir_start, TEAL
                call Print_ln
                MOV EAX,[ES:DI+10]                  ; Size of directory entry on CD/DVD/BD 
                MOV [CD_root_dir_size],EAX 
                Print CD_root_dir_size, TEAL
                call Print_ln
                
                MOV AL,[ES:DI+32]                   ; File's name length (see El Torito of ISO:9660 or CDROM.ASM) 
                MOV [CD_FileNameLength],AL
                
                Print CD_FileNameLength, TEAL
                
                
                call Print_ln
                
                XOR BX,BX                           ; Initialize BX 
                XOR CX,CX                           ; Initialize CX 
                MOV SI,DI 
                
                
                
                
                
                
                
                
                
Sector_Size:                            dw        512                                           
CDDriveNumber:                          db        0x080
CD_bytes_per_sect:              dw    0
CD_root_dir_size:               dd    0
CD_root_dir_sectors:            dw    0
CD_root_dir_start:              dd    0
CD_file_size:                   dd    0
CD_file_sectors:                dw    0
CD_file_start:                  dd    0
CD_desc_sector:                 dd    0
CD_Signature:                           db    "CD001"
CD_FILE_VER:                            db    0x01
CD_FileNameLength:                      db        0x0
CD_dir_curr_size:                       db 0x0
joliet_signature:               db    025h,02Fh,045h
;Disk Address Packet
                                                                
                                                                        
DiskAddressPacket:          db 0x010,0                                            
.SectorsToRead:             dw 1                              ; Number of sectors to read (read size of OS) 
.Offset:                    dw 0                              ; Offset :0000 
.Segment:                   dw 0x0200                         ; Segment 0200
.End:                       dq 0x010                             ; Sector 16 or 10h on CD-ROM 

VOLUME: DB 0
                                                
W_MSG: db "Loading Z-Boot", 0
KERNEL: db "KRNL.BIN"
Read_Sector_Error_MSG: db "Error, failed to read sector",0
READ_SUCCESS: db "Sectors read correctly",0
Progress_MSG: db ".",0
FILE_NOT_FOUND: db "Error, file not found",0
FOUND_CD: db "Found the CD Signature", 0
times 2046 - ($ - $$) db 0; padd out the rest of the file to 0
DW 0xAA55; boot signature


    

Here is the link to the other discussion I had on the nasm forum:
http://forum.nasm.us/index.php?topic=1938.30
Post 26 Jul 2014, 04:19
View user's profile Send private message Reply with quote
AnonymousUser



Joined: 25 Jul 2014
Posts: 32
AnonymousUser
Wow I think I just figured it out thanks for posting your'e code I am still in working on it but I think I am really close Smile
here is my new code:
Code:
BITS   16

ORG  0x00

Start: jmp main


;Colors for text
%DEFINE TEAL 0x03
%DEFINE RED 0x04
%DEFINE PURPLE 0x05
COL: db 0
ROW:  db 0

;macro for print
%macro Print 2
pusha
        xor ax, ax
        xor dx, dx
        mov dh, BYTE[ROW];puts the row into the dh register
        mov dl, BYTE[COL]
        xor bx, bx
        mov bl, %2
        mov si, %1
        call cPrint
        mov BYTE[COL], dl
 ;saves the rows for the next time we need to print
popa
%endmacro

Print_ln:

pusha   
        mov dh, BYTE[ROW]          
    mov ah, 0x02            ;set cursor pos
    mov bh, 0x00            ;page 00
    inc dh                      ;row 00
    mov dl, 0x00            ;col. 00    
        int 0x10
        mov BYTE[ROW], dh
        mov BYTE[COL], 0
        popa


ret

cPrint:                   ; Routine: output string in SI to screen


 .top:
        ;Paramaters for Input 
    mov ah, 09h             ; Must be 9 to print color
    mov cx, 0x01                        ;x position
    lodsb                   ; Get character from string
    test al, al
    je .done                ; If char is zero, end of string
    int 0x10                 ; Otherwise, print it

    mov ah, 0x02                        ;set cursor position
    mov bh, 0x00                        ;page
    inc dl              ;column
    int 0x10                            ;changes the cursor position so the next char can be written at the new location
    jmp .top

 .done:
    ret

;clears the screen and sets the cursor position to the top left 
 clear:
    mov ah, 0x0F            ;get current video mode
    mov al, 0x00            ;reset register
    int 0x10                ;get video mode
    mov ah, 0x00            ;set video mode
    int 0x10                ;reset screen
    mov ah, 0x02            ;set cursor pos
    mov bh, 0x00            ;page 00
    mov dh, 0x00            ;row 00
    mov dl, 0x00            ;col. 00
    int 0x10                ;set pos
ret




Read_Sectors:  
        ;/* Read the sector into memory. */
       
                .ForLoop:
                        mov     ah,042h
                        xor     al,al
                        mov     si, DiskAddressPacket
                        mov     dl, [CDDriveNumber]
                        int     013h
        jnc    .Success         ; /* read error? */

        Print Read_Sector_Error_MSG, RED
                
                cli
                hlt

.Success:
                Print Progress_MSG , PURPLE
                inc WORD[DiskAddressPacket.SectorsToRead]
                
        loop    .ForLoop
                call Print_ln
ret
CHECK_DESC:
        Print CHECK_DESC_MSG, TEAL
        mov es, WORD[DiskAddressPacket.Segment]
        mov di, WORD[DiskAddressPacket.Offset]
        
        xor bx, bx
        .top:
                mov al, BYTE[ES:DI+BX]
                mov BYTE[VOLUME+BX], al
                
                inc bx
                cmp al, ' '
                je .Done
                jmp .top
        .Done:

        ;see if the Volume descriptor contains the Signature
        xor BX, BX; clear out bx
        add BX, 0x01;move into bx the offset
        xor cx, cx;clear out cx
        .toploop:
        xor ax, ax
        mov al, BYTE[VOLUME+BX] 
        cmp al, BYTE[CD_Signature+BX-1]
        je .FOUND_IT; Compare the letters Byte by Byte to see if they are the same
        jmp .Done2
        inc CX;increments if even one letter is wrong
        .FOUND_IT:
        Print Progress_MSG, PURPLE
        inc BX;Increments the offset
        
        jmp .toploop
        
        .Done2:
        cmp CX, 0;if signatures don't match then stop the system and print an error Message
        jne .FAIL
        call Print_ln
        
        Print FOUND_CD, TEAL
        jmp .Done3
        .FAIL:
        Print FILE_NOT_FOUND, RED
        cli
        hlt
        .Done3:
        call Print_ln
ret
READ_STAGE2:
        Print LOADING_STAGE2_MSG, TEAL
        call Print_ln
        mov es, [DiskAddressPacket.Segment]
        mov di, [DiskAddressPacket.Offset]
        
    xor BX, BX
        xor si, si 
        
    .top:
                
                MOV AL,[ES:DI+BX] ;starting address
                cmp AL,BYTE[STAGE2]
                je .Done
                cmp AL,BYTE[STAGE2]
                je .FAIL
                INC BX
        jmp .top
        
        .Done:
        Print Found_Possible_FILE, TEAL
        call Print_ln
        XOR SI, SI;Clear out for use
        ;INC BX
        ;INC SI
        xor cx, cx;clear out for use as counter

        .top2:
        
                MOV AL, [ES:DI+BX]
                MOV AH, 0xE
                int 0x010
                MOV AL, [ES:DI+BX]
                
                cmp AL, BYTE[STAGE2+SI]
                
                je .Success
                call Print_ln
                jmp .top
                .Success:
                        Print Progress_MSG, PURPLE
                        INC BX
                        INC SI  
                        INC CX
                                
        cmp CX, WORD[STAGE_2_LEN] 
        jne .top2
        
        
        Print File_Found, TEAL
        call Print_ln
        
        ADD DI, BX
        
        ;jump to where the file is located
        push WORD ES
        push WORD DI
        retf
        
        .FAIL:
        call Print_ln
        Print FILE_NOT_FOUND, RED
        cli
        hlt
        
        
ret


main:

        cli
        mov ax, 0x07c0  ;adjust the segment registers
        mov ds, ax
        mov gs, ax
        mov fs, ax


Create_Stack:
        xor ax, ax
        mov es, ax
        mov ss, ax
        mov sp ,0x0FFFE
        sti
        
        mov     [CDDriveNumber],dl
        call clear


        Print W_MSG, TEAL;prints the loading message in colour
        call Print_ln
        

        ;First find the Signature of the CD 
        Print Reading_Sectors, TEAL
        LOAD_SIGNATURE:
        mov cx, 0x04
        call Read_Sectors
        
        Print READ_SUCCESS, TEAL
        call Print_ln
        ;load the Volume descriptor to the Volume variable
        call CHECK_DESC
        ;Now Load the Root Directory from the Volume Descriptor
        LOAD_ROOT:
                ;Print Reading_Sectors, TEAL
                mov es, WORD[DiskAddressPacket.Segment]
                mov di, WORD[DiskAddressPacket.Offset]
                
                XOR BX, BX
                MOV BX, 40 ;move in the offset
                VolumeLabelLoop: 

                        MOV CL,[ES:DI+BX]                   ; Grab a letter 
                        CMP CL,' '                          ; Is it a space? (Assumes end of string is space, may run out) 
                        JE .VolumeLabelDone                 ; Yes, we are done 

                        MOV [VOLUME+BX-40],CL 
                        INC BX 
                        JMP VolumeLabelLoop                 ; Need to compare BX to length of Volume Label on CD (32?) 

                        .VolumeLabelDone: 

                                MOV byte [VOLUME+BX-40],0      ; End the string 

                                MOV EAX,[ES:DI+158]                 ; LBA of root directory, where all things start. 
                                MOV [DiskAddressPacket.End],EAX     ; Load packet with new address on CD of the root directory 
                        
                                xor cx, cx
                                mov cx, 0x01
                                Print Reading_Sectors, TEAL
                                call Read_Sectors                          ; Call read sector from drive 
                    
                                Print READ_SUCCESS, TEAL;if the program gets here it means it was a success
                                call Print_ln
LOAD_STAGE2:
        call READ_STAGE2
        .FAILURE:
        Print LOADING_STAGE2_FAILED, RED;if it gets here the jump failed
        call Print_ln   
                
                
                
                
Sector_Size:                            dw              512                                             
CDDriveNumber:                          db              0x080
CD_bytes_per_sect:              dw      0
CD_root_dir_size:               dd      0
CD_root_dir_sectors:            dw      0
CD_root_dir_start:              dd      0
CD_file_size:                   dd      0
CD_file_sectors:                dw      0
CD_file_start:                  dd      0
CD_desc_sector:                 dd      0
CD_Signature:                           db      "CD001"
CD_FILE_VER:                            db      0x01
CD_FileNameLength:                      db              0x0
CD_dir_curr_size:                       db              0x0
joliet_signature:               db      025h,02Fh,045h
Reading_Sectors:                        db              "Reading sectors", 0
CHECK_DESC_MSG:                         db              "Checking for CD Signature",0
LOADING_STAGE2_MSG:                     db              "Loading Stage 2 of boot loader",0
STAGE_2_LEN:                            db              0x0A
File_Found:                                     db              "File for Stage 2 of the bootloader was successfully loaded!!",0
LOADING_STAGE2_FAILED:          db      "Failed to load Stage 2 of the boot loader !!!!!",0
Found_Possible_FILE:            db              "Found Possible File",0
;Disk Address Packet
                                                        
                                                                        
DiskAddressPacket:          db 0x010,0                                            
.SectorsToRead:             dw 1                              ; Number of sectors to read (read size of OS) 
.Offset:                    dw 0                              ; Offset :0000 
.Segment:                   dw 0x0200                         ; Segment 0200
.End:                       dq 0x010                             ; Sector 16 or 10h on CD-ROM 

VOLUME: DB 0
                                                
W_MSG: db "Loading Z-Boot", 0
STAGE2: db "STAGE2.BIN"
Read_Sector_Error_MSG: db "Error, failed to read sector",0
READ_SUCCESS: db "Sectors read correctly!",0
Progress_MSG: db ".",0
FILE_NOT_FOUND: db "Error, file not found!",0
FOUND_CD: db "Found the CD Signature!", 0
times 2046 - ($ - $$) db 0; padd out the rest of the file to 0
DW 0xAA55; boot signature


    

Ok I found out that mkisofs copies the whole directory to the disk so Now all I have to do is find the File but that's proving to be a bit of a pickle when my current bootloader code runs it finds the file well I print out the name of the possible file and then if it isnt the correct one move on but It prints the file I want to jump to but the problem is it moves on it doesen't think it is the file any ideas on how to fix that?
Post 26 Jul 2014, 05:18
View user's profile Send private message Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 559
smiddy
Check the specifics of the filenames themselves, if you are not considering UPPER CASE or lower case, or a combination there of, you will not get a string comparison correctly and move on. I don't use mkisofs, but I suspect it is saving your file names to another standard, ISO 9660 (and El Torrito) are very specific about the letter case, on the disc, but there are other implementations, and those implementations need to also be considered, and I suspect that may be your problem, don't know.

I create an ISO from FASM code, at the specifications of ISO 9660, with El Torrito to boot my OS.

[reading your code now]
Yep, I cannot make heads or tails of your code, I don't know NASM's conventions. I cannot help there.
[/reading your code now]
Post 26 Jul 2014, 10:54
View user's profile Send private message Reply with quote
AnonymousUser



Joined: 25 Jul 2014
Posts: 32
AnonymousUser
Ok I figured out why it wasn't working correctly turns out I need to clear the screen and move onto the next page to actually see the Success Print. I also figured out how to jump to the file which I did or it looks like I did but it's not executing the code at the Adress any Idea as to why?
Code:
READ_STAGE2:
        Print LOADING_STAGE2_MSG, TEAL
        call Print_ln
        mov es, [DiskAddressPacket.Segment]
        mov di, [DiskAddressPacket.Offset]
        
    xor BX, BX
        xor si, si 
        
    .top:
                
                MOV AL,[ES:DI+BX] ;starting address
                cmp AL,BYTE[STAGE2]
                je .Done
                cmp AL,BYTE[STAGE2]
                je .FAIL
                INC BX
        jmp .top
        
        .Done:
        Print Found_Possible_FILE, TEAL
        call Print_ln
        XOR SI, SI;Clear out for use
        ;INC BX
        ;INC SI
        xor cx, cx;clear out for use as counter
        
        .top2:
                xor ax, ax
                
                MOV AL, BYTE[ES:DI+BX]
                
                cmp AL, BYTE[STAGE2+SI]
                
                je .Success
                call Print_ln
                jmp .top
                .Success:
                        
                        Print Progress_MSG, PURPLE
                                                
                        
                        INC BX
                        INC SI  
                        INC CX
        cmp CX, WORD[STAGE_2_LEN] 
        jne .top2
        call clear
        
        Print File_Found, TEAL
        call Print_ln
        SUB BX, 10
        ADD DI, BX
        
        Print Reading_Sectors, TEAL
    mov     eax, [ES:DI]
    mov     bx,0x0200
        mov     WORD[DiskAddressPacket.Segment], BX
        mov     WORD[DiskAddressPacket.Offset], 0 
    mov     cx, 0x04
    call    Read_Sectors

    mov     dl, [CDDriveNumber]
        xor     si,si
        
        Print READ_SUCCESS, TEAL
        call Print_ln
        
        
    ;/* Run the OS loader... */
    jmp    0x200:0x0000
        
        .FAIL:
        call Print_ln
        Print FILE_NOT_FOUND, RED
        cli
        hlt
        
        
ret
    

here is the Stage 2 code:
Code:
[BITS 16]
[ORG 0x500]

Start: jmp main

%DEFINE TEAL 0x03
%DEFINE RED 0x04
%DEFINE PURPLE 0x05
COL: db 0
ROW:  db 0
%macro Print 2
pusha
        xor ax, ax
        xor dx, dx
        mov dh, BYTE[ROW];puts the row into the dh register
        mov dl, BYTE[COL]
        xor bx, bx
        mov bl, %2
        mov si, %1
        call cPrint
        mov BYTE[COL], dl
 ;saves the rows for the next time we need to print
popa
%endmacro

Print_ln:

pusha   
        mov dh, BYTE[ROW]          
    mov ah, 0x02            ;set cursor pos
    mov bh, 0x00            ;page 00
    inc dh                      ;row 00
    mov dl, 0x00            ;col. 00    
        int 0x10
        mov BYTE[ROW], dh
        mov BYTE[COL], 0
        popa


ret

cPrint:                   ; Routine: output string in SI to screen


 .top:
        ;Paramaters for Input 
    mov ah, 09h             ; Must be 9 to print color
    mov cx, 0x01                        ;x position
    lodsb                   ; Get character from string
    test al, al
    je .done                ; If char is zero, end of string
    int 0x10                 ; Otherwise, print it

    mov ah, 0x02                        ;set cursor position
    mov bh, 0x00                        ;page
    inc dl              ;column
    int 0x10                            ;changes the cursor position so the next char can be written at the new location
    jmp .top

 .done:
    ret

;clears the screen and sets the cursor position to the top left 
 clear:
    mov ah, 0x0F            ;get current video mode
    mov al, 0x00            ;reset register
    int 0x10                ;get video mode
    mov ah, 0x00            ;set video mode
    int 0x10                ;reset screen
    mov ah, 0x02            ;set cursor pos
    mov bh, 0x01         ;page 00
    mov dh, 0x00            ;row 00
    mov dl, 0x00            ;col. 00
    int 0x10                ;set pos
        MOV BYTE[ROW], DH
        MOV BYTE[COL], DL
ret





main:           
;first stage of bootloader is loaded at the address 0x07c0:0x0FFFE
        ;second stage of bootloader is loaded at address 0x9000:0x0FFFF
        cli
        mov ax, 0x9000  ;adjust the segment registers
        mov ds, ax
        mov gs, ax
        mov fs, ax


Create_Stack:
        xor ax, ax
        mov es, ax
        mov ss, ax
        mov sp ,0x0FFFF
        sti
        
                       
        call Print_ln
        Print LOAD_SUCCESS, TEAL
        call Print_ln



        

LOAD_SUCCESS:   db "Stage 2 of the bootloader has loaded successfully!",0


    


Last edited by AnonymousUser on 27 Jul 2014, 01:34; edited 4 times in total
Post 26 Jul 2014, 19:10
View user's profile Send private message Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 559
smiddy
Kewl, you are on your way now! Smile
Post 26 Jul 2014, 20:14
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.