Author Topic: bootloading dos and or xp  (Read 40865 times)

Offline flyhigh427

  • Jr. Member
  • *
  • Posts: 60
bootloading dos and or xp
« on: July 16, 2011, 06:29:56 PM »
hi
i got this loader off the web and have been studing it and others.
this will load a **.bin file and works but i cant get it to load a **.sys file .
is there a different way to load a system file ,like dos 6.2  ?

thanks and gb
Code: [Select]

;*************************************************************************
;the ultimate boot-strap loader
;to load a file from a DOS FAT12 floppy as the OS
;*************************************************************************
[BITS 16]
[ORG 0x0000]
jmp     START
     
     OEM_ID                db "QUASI-OS"
     BytesPerSector        dw 0x0200
     SectorsPerCluster     db 0x01
     ReservedSectors       dw 0x0001
     TotalFATs             db 0x02
     MaxRootEntries        dw 0x00E0
     TotalSectorsSmall     dw 0x0B40
     MediaDescriptor       db 0xF0
     SectorsPerFAT         dw 0x0009
     SectorsPerTrack       dw 0x0012
     NumHeads              dw 0x0002
     HiddenSectors         dd 0x00000000
     TotalSectorsLarge     dd 0x00000000
     DriveNumber           db 0x00
     Flags                 db 0x00
     Signature             db 0x29
     VolumeID              dd 0xFFFFFFFF
     VolumeLabel           db "QUASI  BOOT"
     SystemID              db "FAT12   "
     
     START:
     ; code located at 0000:7C00, adjust segment registers
          cli
          mov     ax, 0x07C0
          mov     ds, ax
          mov     es, ax
          mov     fs, ax
          mov     gs, ax
     ; create stack
          mov     ax, 0x0000
          mov     ss, ax
          mov     sp, 0xFFFF
          sti
     ; post message
          mov     si, msgLoading
          call    DisplayMessage
     LOAD_ROOT:
     ; compute size of root directory and store in ‘cx’
          xor     cx, cx
          xor     dx, dx
          mov     ax, 0x0020                          ; 32 byte directory entry
          mul     WORD [MaxRootEntries]               ; total size of directory
          div     WORD [BytesPerSector]               ; sectors used by directory
          xchg    ax, cx
     ; compute location of root directory and store in ‘ax’
          mov     al, BYTE [TotalFATs]                ; number of FATs
          mul     WORD [SectorsPerFAT]                ; sectors used by FATs
          add     ax, WORD [ReservedSectors]          ; adjust for bootsector
          mov     WORD [datasector], ax               ; base of root directory
          add     WORD [datasector], cx
     ; read root directory into memory (7C00:0200)
          mov     bx, 0x0200                          ; copy root dir above bootcode
          call    ReadSectors
     ; browse root directory for binary image
          mov     cx, WORD [MaxRootEntries]           ; load loop counter
          mov     di, 0x0200                          ; locate first root entry
     .LOOP:
          push    cx
          mov     cx, 0x000B                          ; eleven character name
          mov     si, ImageName                       ; image name to find
          push    di
     rep  cmpsb                                       ; test for entry match
          pop     di
          je      LOAD_FAT
          pop     cx
          add     di, 0x0020                          ; queue next directory entry
          loop    .LOOP
          jmp     FAILURE
     LOAD_FAT:
     ; save starting cluster of boot image
          mov     si, msgCRLF
          call    DisplayMessage
          mov     dx, WORD [di + 0x001A]
          mov     WORD [cluster], dx                  ; file’s first cluster
     ; compute size of FAT and store in ‘cx’
          xor     ax, ax
          mov     al, BYTE [TotalFATs]                ; number of FATs
          mul     WORD [SectorsPerFAT]                ; sectors used by FATs
          mov     cx, ax
     ; compute location of FAT and store in ‘ax’
          mov     ax, WORD [ReservedSectors]          ; adjust for bootsector
     ; read FAT into memory (7C00:0200)
          mov     bx, 0x0200                          ; copy FAT above bootcode
          call    ReadSectors
     ; read image file into memory (0100:0000)
          mov     si, msgCRLF
          call    DisplayMessage
          mov     ax, 0x0100                          ; destination of image CS
          mov     es, ax
          mov     bx, 0x0000                          ; destination for image IP
          push    bx
     LOAD_IMAGE:
          mov     ax, WORD [cluster]                  ; cluster to read
          pop     bx                                  ; buffer to read into
          call    ClusterLBA                          ; convert cluster to LBA
          xor     cx, cx
          mov     cl, BYTE [SectorsPerCluster]        ; sectors to read
          call    ReadSectors
          push    bx
     ; compute next cluster
          mov     ax, WORD [cluster]                  ; identify current cluster
          mov     cx, ax                              ; copy current cluster
          mov     dx, ax                              ; copy current cluster
          shr     dx, 0x0001                          ;
     ;divide by two
          add     cx, dx                              ; sum for (3/2)
          mov     bx, 0x0200                          ; location of FAT in memory
          add     bx, cx                              ; index into FAT
          mov     dx, WORD [bx]                       ; read two bytes from FAT
          test    ax, 0x0001
          jnz     .ODD_CLUSTER
     .EVEN_CLUSTER:
          and     dx, 0000111111111111b               ; take low twelve bits
         jmp     .DONE
     .ODD_CLUSTER:
          shr     dx, 0x0004                          ; take high twelve bits
     .DONE:
          mov     WORD [cluster], dx                  ; store new cluster
          cmp     dx, 0x0FF0                          ; test for end of file
          jb      LOAD_IMAGE
     DONE:
          mov     si, msgCRLF
          call    DisplayMessage
          push    WORD 0x0100
          push    WORD 0x0000
          retf
     FAILURE:
          mov     si, msgFailure
          call    DisplayMessage
          mov     ah, 0x00
          int     0x16                                ; await keypress
          int     0x19                                ; warm boot computer
     
     ;*************************************************************************
     ; PROCEDURE DisplayMessage
     ; display ASCIIZ string at ds:si via BIOS
     ;*************************************************************************
     DisplayMessage:
          lodsb                                       ; load next character
          or      al, al                              ; test for NUL character
          jz      .DONE
          mov     ah, 0x0E                            ; BIOS teletype
          mov     bh, 0x00                            ; display page 0
          mov     bl, 0x07                            ; text attribute
          int     0x10                                ; invoke BIOS
          jmp     DisplayMessage
     .DONE:
          ret
     
     ;*************************************************************************
     ; PROCEDURE ReadSectors
     ; reads ‘cx’ sectors from disk starting at ‘ax’ into
     ;memory location ‘es:bx’
     ;*************************************************************************
     ReadSectors:
     .MAIN:
          mov     di, 0x0005                          ; five retries for error
     .SECTORLOOP:
          push    ax
          push    bx
          push    cx
          call    LBACHS
          mov     ah, 0x02                            ; BIOS read sector
          mov     al, 0x01                            ; read one sector
          mov     ch, BYTE [absoluteTrack]            ; track
          mov     cl, BYTE [absoluteSector]           ; sector
          mov     dh, BYTE [absoluteHead]             ; head
          mov     dl, BYTE [DriveNumber]              ; drive
          int     0x13                                ; invoke BIOS
          jnc     .SUCCESS                            ; test for read error
          xor     ax, ax                              ; BIOS reset disk
          int     0x13                                ; invoke BIOS
          dec     di                                  ; decrement error counter
          pop     cx
          pop     bx
          pop     ax
          jnz     .SECTORLOOP                         ; attempt to read again
          int     0x18
     .SUCCESS:
          mov     si, msgProgress
          call    DisplayMessage
          pop     cx
          pop     bx
          pop     ax
          add     bx, WORD [BytesPerSector]           ; queue next buffer
          inc     ax                                  ; queue next sector
          loop    .MAIN                               ; read next sector
          ret
     
     ;*************************************************************************
     ; PROCEDURE ClusterLBA
     ; convert FAT cluster into LBA addressing scheme
     ; LBA = (cluster - 2) * sectors per cluster
     ;*************************************************************************
     ClusterLBA:
          sub     ax, 0x0002                          ; zero base cluster number
          xor     cx, cx
          mov     cl, BYTE [SectorsPerCluster]        ; convert byte to word
          mul     cx
          add     ax, WORD [datasector]               ; base data sector
          ret
     
     ;*************************************************************************
     ; PROCEDURE LBACHS
     ; convert ‘ax’ LBA addressing scheme to CHS addressing scheme
     ; absolute sector = (logical sector / sectors per track) + 1
     ; absolute head   = (logical sector / sectors per track) MOD number of heads
     ; absolute track  = logical sector / (sectors per track * number of heads)
     ;*************************************************************************
     LBACHS:
          xor     dx, dx                              ; prepare dx:ax for operation
          div     WORD [SectorsPerTrack]              ; calculate
          inc     dl                                  ; adjust for sector 0
          mov     BYTE [absoluteSector], dl
          xor     dx, dx                              ; prepare dx:ax for operation
          div     WORD [NumHeads]                     ; calculate
          mov     BYTE [absoluteHead], dl
          mov     BYTE [absoluteTrack], al
          ret

     absoluteSector db 0x00
     absoluteHead   db 0x00
     absoluteTrack  db 0x00
     
     datasector  dw 0x0000
     cluster     dw 0x0000
     ImageName   db "IO  SYS"
     msgLoading  db 0x0D, 0x0A, "Loading Boot Image ", 0x0D, 0x0A, 0x00
     msgCRLF     db 0x0D, 0x0A, 0x00
     msgProgress db ".", 0x00
     msgFailure  db 0x0D, 0x0A, "ERROR : Press Any Key to Reboot", 0x00
     
          TIMES 510-($-$$) DB 0
          DW 0xAA55
     ;*************************************************************************



Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: bootloading dos and or xp
« Reply #1 on: July 16, 2011, 07:57:04 PM »
I can't confirm this at the moment, but I seem to recall that dos loads at (segment) 0x70, not 0x100 as you're doing. It would be easy to try, in any case...

Best,
Frank


Offline flyhigh427

  • Jr. Member
  • *
  • Posts: 60
Re: bootloading dos and or xp
« Reply #2 on: July 16, 2011, 08:18:22 PM »
;A Basic Boot Sector for DOS 2.0 to 6.22. This is non-viral!
;
;(C) 1995 American Eagle Publications, Inc. All Rights Reserved!

i found this but i havent got it to work yet

;This segment is where the first operating system file (IO.SYS) will be
;loaded and executed from. We don't know (or care) what is there, as long as
;it will execute at 0070:0000H, but we do need the address to jump to defined
;in a separate segment so we can execute a far jump to it.
DOS_LOAD        SEGMENT AT 0070H
                ASSUME CS:DOS_LOAD

                ORG 0

LOAD:                               ;Start of the first operating system program

DOS_LOAD        ENDS



MAIN            SEGMENT BYTE
                ASSUME CS:MAIN,DS:MAIN,SS:NOTHING



Offline flyhigh427

  • Jr. Member
  • *
  • Posts: 60
Re: bootloading dos and or xp
« Reply #3 on: July 17, 2011, 10:46:19 AM »
hey yall does each defferent file type load into a defferent segment?

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: bootloading dos and or xp
« Reply #4 on: July 17, 2011, 04:23:41 PM »
Not ordinarily. A bootsector has to load "something" at a known, fixed address - segment and offset. After that, the OS would select a (free) segment... could be selected by "file type", but usually not.

Best,
Frank


Offline flyhigh427

  • Jr. Member
  • *
  • Posts: 60
Re: bootloading dos and or xp
« Reply #5 on: July 17, 2011, 07:13:34 PM »
hey there all
i put mov ax, 0x0070 in one place and tryed it and it didnt work.
i also put it in push word 0x0070 and it didnt work.
the segments say use    0070:0000H ,,am i entering it right?


Code: [Select]

; read image file into memory (0100:0000)
          mov     si, msgCRLF
          call    DisplayMessage
          mov     ax, 0x0100                          ; destination of image CS
          mov     es, ax
          mov     bx, 0x0000                          ; destination for image IP
          push    bx
     LOAD_IMAGE:
          mov     ax, WORD [cluster]                  ; cluster to read
          pop     bx                                  ; buffer to read into
          call    ClusterLBA                          ; convert cluster to LBA
          xor     cx, cx
          mov     cl, BYTE [SectorsPerCluster]        ; sectors to read
          call    ReadSectors
          push    bx
     ; compute next cluster
          mov     ax, WORD [cluster]                  ; identify current cluster
          mov     cx, ax                              ; copy current cluster
          mov     dx, ax                              ; copy current cluster
          shr     dx, 0x0001                          ;
     ;divide by two
          add     cx, dx                              ; sum for (3/2)
          mov     bx, 0x0200                          ; location of FAT in memory
          add     bx, cx                              ; index into FAT
          mov     dx, WORD [bx]                       ; read two bytes from FAT
          test    ax, 0x0001
          jnz     .ODD_CLUSTER
     .EVEN_CLUSTER:
          and     dx, 0000111111111111b               ; take low twelve bits
         jmp     .DONE
     .ODD_CLUSTER:
          shr     dx, 0x0004                          ; take high twelve bits
     .DONE:
          mov     WORD [cluster], dx                  ; store new cluster
          cmp     dx, 0x0FF0                          ; test for end of file
          jb      LOAD_IMAGE
     DONE:
          mov     si, msgCRLF
          call    DisplayMessage
          push    WORD 0x0100
          push    WORD 0x0000
          retf




Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: bootloading dos and or xp
« Reply #6 on: July 17, 2011, 08:02:56 PM »
If you made both of those changes in that snippet, it "should" work if it's going to. As an alternative to the "push/push/retf", you should be able to use:

Code: [Select]
jmp 0x70:0

(in your post, you don't indicate that the "70" is hex) But they "should" do the same thing, so if one doesn't work, the other probably won't either.

One of the things that makes a bootsector "hard" is that it's hard to figure out what went wrong, if something does. One technique is to put 0xB800 in gs (or so), and do:

Code: [Select]
mov byte [gs:0], 'A'

at "critical" junctures in the code, incrementing "A" (and/or the offset - by two!) to see how far you got before things went haywire. Still not easy, especially as you're jumping into code you didn't write!

Best,
Frank


Offline flyhigh427

  • Jr. Member
  • *
  • Posts: 60
Re: bootloading dos and or xp
« Reply #7 on: July 17, 2011, 08:08:29 PM »
its finilly trying to load io.sys but then locks up

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: bootloading dos and or xp
« Reply #8 on: July 17, 2011, 09:18:57 PM »
Code: [Select]
     ImageName   db "IO  SYS"

Can't tell for sure how many spaces in this. "IO" should be padded out to 8, before the "SYS". "Should" be obvious if it's "not found".

Maybe the entrypoint to "io.sys" isn't zero? Can you compare a "known good" bootsector to see what it does?

Best,
Frank


Offline flyhigh427

  • Jr. Member
  • *
  • Posts: 60
Re: bootloading dos and or xp
« Reply #9 on: July 17, 2011, 09:30:25 PM »
that 11 charter thing had me puzzeled..but i got that one .

Offline flyhigh427

  • Jr. Member
  • *
  • Posts: 60
Re: bootloading dos and or xp
« Reply #10 on: July 17, 2011, 10:28:32 PM »
does fat12 and fat have anything to do with it?

Offline flyhigh427

  • Jr. Member
  • *
  • Posts: 60
Re: bootloading dos and or xp
« Reply #11 on: July 18, 2011, 03:01:30 AM »
ive been reading how dos works the breakdown of segment by segment ,but its something that sys.com writes in or loads first .

Offline flyhigh427

  • Jr. Member
  • *
  • Posts: 60
Re: bootloading dos and or xp
« Reply #12 on: July 18, 2011, 02:26:32 PM »
hey and morning all
line number 6 in first code is the  problem if im right .
because in the next set of code its beening put in a different place right?

Code: [Select]

Summary of what this thing does
(1)Copy Diskette Parameter Table which is pointed to by INT 1E.
(2)Alter the copy of the Diskette Parameter Table.
(3)Alter INT 1E to point to altered Diskette Parameter Table.
(4)Do INT 13 AH=00, disk reset call.
(5)Compute sector address of root directory.
(6)Read first sector of root directory into 0000:0500.
(7)Confirm that first two directory entries are for IO.SYS and MSDOS.SYS.
(8)Read first 3 sectors of IO.SYS into 0000:0700 (or 0070:0000).
(9)Leave some information in the registers and jump to IO.SYS at 0070:0000.

Code: [Select]
; read root directory into memory (7C00:0200)
          mov     bx, 0x0200                          ; copy root dir above bootcode
          call    ReadSectors
     ; browse root directory for binary image
          mov     cx, WORD [MaxRootEntries]           ; load loop counter
          mov     di, 0x0200                          ; locate first root entry


Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: bootloading dos and or xp
« Reply #13 on: July 18, 2011, 08:17:58 PM »
Well... "line 6" says that the first sector of the root directory is read to 0000:0500. The code shows (apparently) it being read to offset 200(hex). But we don't know what's in es. So it looks like a "different place", and that would be a problem. I can't imagine you're reading anything to 0000:0200, that would be in the middle of your Interrupt Vector Table. But I recently read something suggesting that dos did that! Google "AARD code". I have no idea whether that's what you're seeing or not. If so, it might account for some confusion.

I'm not sure I'm entirely clear on what you're trying to do. You've got a floppy with dos on it, right? Put there by "sys.com"? And instead of letting the bootsector load "io.sys", you want to replace that bootsector with one of your own that does the same thing? Am I "following the plot" so far?

Oh. I'm not. The code you posted (in a comment) says 7C00:0200. That seems improbable (but possible). I would think 07C0:0200 would be more sensible (right after your bootsector).

What (else) am I missing?

Best,
Frank


Offline flyhigh427

  • Jr. Member
  • *
  • Posts: 60
Re: bootloading dos and or xp
« Reply #14 on: July 18, 2011, 08:34:00 PM »
thanks frank it give me something to do,only way to learn is to start doing something