What is wrong on some PC with this 1st stage BL?

If you are new to OS Development, plan on spending some time here first before going into the other forums.

Moderator: Moderators

Post Reply
ehenkes
Posts: 34
Joined: Fri Jul 24, 2009 5:35 pm

What is wrong on some PC with this 1st stage BL?

Post by ehenkes » Wed Aug 19, 2009 10:57 am

To use an own BL is one of the great adventures in OS development, espacially if you want you OS running at all kinds of PC. I rearranged the BL of this demo, because I do not like org 0 and some of the variable names, but now on some modern PCs this BL does not start up:

Code: Select all

; boot.asm
[Bits 16]
org 0x7C00                             ; start address of bootloader
jmp entry_point                        ; jump to bootloader entry point

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Memory Management: 
; org                  7C00 (0x00007C00)
; data/extra segments     0
; stack segment        9000 (0x00090000)   
; root dir -> memory   7E00 (0x00007E00)
; boot2    -> memory    500 (0x00000500)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

%include "Fat12_BPB.inc"

;******************************************************************************
;	bootloader entry point
;******************************************************************************
entry_point:
    xor     ax, ax     		           ; set registers
    mov     ds, ax
    mov     es, ax
    mov     fs, ax
    mov     gs, ax
    
    mov     ax, 0x9000			       ; set the stack
    mov     ss, ax
    xor     sp, sp
          
    mov  [bootdevice], dl              ; store boot device
	mov si, msgLoading
    call print_string

Load_Root_Directory_Table:
    ; compute size of root directory and store in "cx"
    xor cx, cx
    xor dx, dx
    mov ax, 0x20                             ; 32 byte directory entry
    mul WORD [RootEntries]                   ; total size of directory
    div WORD [BytesPerSec]                   ; sectors used by directory
    xchg ax, cx
        
    ; compute location of root directory and store in "ax"
    mov al, BYTE [NumFATs]                    ; number of FATs
    mul WORD [FATSize]                        ; sectors used by FATs
    add ax, WORD [ReservedSec]                ; adjust for bootsector
    mov WORD [datasector], ax                 ; base of root directory
    add WORD [datasector], cx
          
    ; read root directory into memory (7E00h)
    mov bx, 0x7E00                            ; copy root dir above bootcode
    call ReadSectors

;******************************************************************************
;   Find stage2 bootloader
;******************************************************************************
    ; browse root directory for binary image
    mov cx, WORD [RootEntries]                ; load loop counter
    mov di, 0x7E00                            ; locate first root entry
.LOOP:
    push cx
    mov cx, 0xB                               ; name has 11 characters 
    mov si, ImageName                         ; look for this image name
    push di
    rep cmpsb                                 ; test for entry match
    pop di
    je Load_FAT
    pop cx
    add di, 0x20                              ; queue next directory entry
    loop .LOOP
    jmp FAILURE

;******************************************************************************
;   Load File Allocation Table (FAT)
;******************************************************************************
Load_FAT:
    ; save starting cluster of boot image
    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 [NumFATs]                  ; number of FATs
    mul WORD [FATSize]                      ; sectors used by FATs
    mov cx, ax

    ; compute location of FAT and store in "ax"
    mov ax, WORD [ReservedSec]              ; adjust for bootsector
          
    ; read FAT into memory (7E00h)
    mov bx, 0x7E00                          ; copy FAT above bootcode
    call ReadSectors

    ; read image file into memory (0500h)
    xor ax, ax
    mov es, ax                              ; destination for image
    mov bx, 0x0500                          ; destination for image
    push bx

;******************************************************************************
;   Load stage2 bootloader
;******************************************************************************
Load_Image:
    mov ax, WORD [cluster]                  ; cluster to read
    pop bx                                  ; buffer to read into
    call Convert_Cluster_to_LBA             ; convert cluster to LBA
    xor cx, cx
    mov cl, BYTE [SecPerClus]               ; 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, 1                               ; divide by two
    add cx, dx                              ; sum for (3/2)
    mov bx, 0x7E00                          ; location of FAT in memory
    add bx, cx                              ; index into FAT
    mov dx, WORD [bx]                       ; read two bytes from FAT
    test ax, 1
    jnz .ODD_CLUSTER
          
.EVEN_CLUSTER:
    and dx, 0000111111111111b               ; take low twelve bits
    jmp .DONE
         
.ODD_CLUSTER:
    shr dx, 4                               ; take high twelve bits
          
.DONE:
    mov WORD [cluster], dx                  ; store new cluster
    cmp dx, 0x0FF0                          ; test for EOF
    jb Load_Image
          
DONE:
    mov si, msgCRLF
    call print_string
	mov dl, [bootdevice]
    push WORD 0x0000
    push WORD 0x0500
    retf
          
FAILURE:
    mov si, msgFailure
    call print_string
    mov ah, 0x00
    int 0x16                                ; wait for keypress
    int 0x19                                ; warm boot reset


;******************************************************************************
;   Convert CHS to LBA
;   LBA = (cluster - 2) * sectors per cluster
;******************************************************************************
Convert_Cluster_to_LBA:
    sub ax, 2                               ; zero base cluster number
    xor cx, cx
    mov cl, BYTE [SecPerClus]               ; convert byte to word
    mul cx
    add ax, WORD [datasector]               ; base data sector
    ret

;******************************************************************************
;   Convert LBA to CHS
;   AX    LBA Address to convert
;
;   sector = (logical sector / sectors per track) + 1
;   head   = (logical sector / sectors per track) MOD number of heads
;   track  = logical sector / (sectors per track * number of heads)
;
;******************************************************************************
Convert_LBA_to_CHS:
    xor dx, dx                              ; prepare dx:ax for operation
    div WORD [SecPerTrack]                  ; calculate
    inc dl                                  ; adjust for sector 0
    mov BYTE [Sector], dl
    xor dx, dx                              ; prepare dx:ax for operation
    div WORD [NumHeads]                     ; calculate
    mov BYTE [Head], dl
    mov BYTE [Cylinder], al
    ret

;******************************************************************************
;   Reads sectors 
;   CX     Number of sectors to read
;   AX     Starting sector
;   ES:BX  Buffer to read to
;******************************************************************************
ReadSectors:
.NEXTSECTOR:
    mov di, 5                                ; five retries for error
.LOOP:
    push ax
    push bx
    push cx
    call Convert_LBA_to_CHS                  ; convert starting sector from LBA to CHS
	mov  ah, 2                               ; INT 0x13, AH=2 --> read in CHS mode
	mov  al, 1                               ; read one sector
	mov  ch, BYTE [Cylinder]                 ; track/cylinder
	mov  cl, BYTE [Sector]                   ; sector
	mov  dh, BYTE [Head]                     ; head
	mov  dl, BYTE [DriveNum]                 ; drive
	int  0x13                                
	jnc  .SUCCESS                            ; check read error
	xor  ax, ax                              ; INT 0x13, AH=0 --> reset floppy/hard disk
	int  0x13                                
	dec  di                                  ; decrement error counter
	pop  cx
	pop  bx
	pop  ax
	jnz  .LOOP                               ; read again
	int  0x18
.SUCCESS:
    mov  si, msgProgress
    call print_string
    pop  cx
    pop  bx
    pop  ax
    add  bx, WORD [BytesPerSec]              ; queue next buffer
    inc  ax                                  ; queue next sector
    loop .NEXTSECTOR                         ; read next sector
    ret
	
;******************************************************************************
;   Print String  
;	DS:SI   null-terminated string
;******************************************************************************
print_string:
    mov ah, 0x0E      ; BIOS function 0x0E: teletype
.loop:   
    lodsb             ; grab a byte from SI
    test al, al       ; NUL?
    jz .done          ; if the result is zero: get out
    int 0x10          ; else: print out the character
    jmp .loop
.done:
    ret	
	
;******************************************************************************
;	Parameters
;******************************************************************************
Sector         db 0
Head           db 0
Cylinder       db 0	
bootdevice     db 0
datasector     dw 0
cluster        dw 0
ImageName      db "BOOT2   SYS"
msgCRLF        db 0x0D, 0x0A, 0
msgProgress    db "*", 0
msgLoading     db "Loading Second Stage Bootloader", 0x0D, 0x0A, 0
msgFailure     db 0x0D, 0x0A, "BOOT2.SYS MISSING", 0x0D, 0x0A, 0
 
TIMES 510-($-$$) hlt                         ; fill bytes until boot signature
db 0x55                                      ; boot signature
db 0xAA                                      ; boot signature 

Code: Select all

%ifndef FAT12_BPB_INC
%define FAT12_BPB_INC

[BITS 16]

;##############################################################################
; "FAT 12" file system is build up by four areas at Floppy Disk:
; - Boot Sector (also called BIOS Parameter Block, BPB) 
; - File Allocation Table, FAT 
; - Root Directory
; - Subdirectories and Files

; boot sector info block

OperatingSystemName db "PrettyOS"      ;  8 byte
BytesPerSec         dw 512                            
SecPerClus          db 1                              
ReservedSec         dw 1                              
NumFATs             db 2                              
RootEntries         dw 224                            
TotSec              dw 2880                           
MediaType           db 0xF0
FATSize             dw 9                              
SecPerTrack         dw 18                             
NumHeads            dw 2                              
HiddenSec           dd 0
TotSec32            dd 0
DriveNum            db 0                              
Reserved            db 0
BootSig             db 0x29
VolumeSerialNum     dd 0xD00FC0DE      
VolumeLabel         db "PrettyOS   "   ; 11 byte
FileSys             db "FAT12   "      ;  8 byte
;##############################################################################

%endif
If you do not see the problem, where would you start to search?

Andyhhp
Moderator
Posts: 387
Joined: Tue Oct 23, 2007 10:05 am
Location: 127.0.0.1
Contact:

Re: What is wrong on some PC with this 1st stage BL?

Post by Andyhhp » Thu Aug 20, 2009 6:39 am

what happens when you try and boot it?

~Andrew
Image

Andyhhp
Moderator
Posts: 387
Joined: Tue Oct 23, 2007 10:05 am
Location: 127.0.0.1
Contact:

Re: What is wrong on some PC with this 1st stage BL?

Post by Andyhhp » Thu Aug 20, 2009 6:44 am

on second thoughts,

Code: Select all

 pop  ax
   jnz  .LOOP                               ; read again
   int  0x18
.SUCCESS:
    mov  si, msgProgress
    call print_string
what is that int 0x18 doing?
Image

ehenkes
Posts: 34
Joined: Fri Jul 24, 2009 5:35 pm

Re: What is wrong on some PC with this 1st stage BL?

Post by ehenkes » Thu Aug 20, 2009 8:02 am

This one (from 4) PC, which objects to boot process (whereas all the other three boot), tells me that there is "no bootable disk, press ... for reboot". I do not see the error possibility. Bootloading is a complex process, and you never know.

BIOS int 0x18: ROM BASIC loader
I have taken that from your original boot.asm from DEMO15. :o

With the FDC it is similar. Some PC work with it, other do not.

Andyhhp
Moderator
Posts: 387
Joined: Tue Oct 23, 2007 10:05 am
Location: 127.0.0.1
Contact:

Re: What is wrong on some PC with this 1st stage BL?

Post by Andyhhp » Thu Aug 20, 2009 8:09 am

I have taken that from your original boot.asm from DEMO15
Its not mine :P - Im just a mod on the forums!

RBIL lists int 0x18 as

Code: Select all

INT 18 - DISKLESS BOOT HOOK (START CASSETTE BASIC)
Desc:	called when there is no bootable disk available to the system
Notes:	very few PCs other than those produced by IBM contain BASIC in ROM, so
	  the action is unpredictable on compatibles; this interrupt often
	  reboots the system, and often has no effect at all
I must admit that I have never come across it before.
This one PC, which objects to boot process, tells me that there is "no bootable disk, press ... for reboot".
This means that either the drive you are using is broken or the bootloader signature is in the wrong place

~Andrew
Image

ehenkes
Posts: 34
Joined: Fri Jul 24, 2009 5:35 pm

Re: What is wrong on some PC with this 1st stage BL?

Post by ehenkes » Thu Aug 20, 2009 9:53 am

This means that either the drive you are using is broken or the bootloader signature is in the wrong place
I looked with a hex editor directly at the disk (in the floppy disk device of this PC): 0x55 0xAA at the right place (the same disk boots in other PCs). Looks like this: http://www.henkessoft.de/OS_Dev/Bilder/ ... Editor.PNG

Andyhhp
Moderator
Posts: 387
Joined: Tue Oct 23, 2007 10:05 am
Location: 127.0.0.1
Contact:

Re: What is wrong on some PC with this 1st stage BL?

Post by Andyhhp » Thu Aug 20, 2009 9:56 am

Which means there is a problem with the boot device itself.

Can you successfully boot anything else off it?
Image

ehenkes
Posts: 34
Joined: Fri Jul 24, 2009 5:35 pm

Re: What is wrong on some PC with this 1st stage BL?

Post by ehenkes » Thu Aug 20, 2009 10:10 am

Can you successfully boot anything else off it?
If I exchange my 1st stage BL with your original BL, then it works.

I have read the original message again:
"Loading Second Stage Bootloader " <-- this comes from

Code: Select all

    mov  [bootdevice], dl              ; store boot device
   mov si, msgLoading
    call print_string
Hence, it boots, but then ...

"Reboot and Select proper Boot device or Insert Boot Media in selected Boot device and press key"

(if you press key, then nothing happens, just a blinking cursor)

Could it be that the info in DL gets lost only at this PC?

At other PCs the same disk boots the kernel w/o problems (sometimes the fdc does not work as it should, but that is another story).

ehenkes
Posts: 34
Joined: Fri Jul 24, 2009 5:35 pm

Re: What is wrong on some PC with this 1st stage BL?

Post by ehenkes » Thu Aug 20, 2009 10:54 am

I found the solution:

mov ax, 0x9000 ; set the stack <--- wrong
As far as I see, this is in the root dir memory region (14 sectors; from 0x7E00 to 0x9A00)
http://www.henkessoft.de/OS_Dev/Bilder/ ... 2_Root.PNG :shock:

mov ax, 0x7C00 ; it works!

The open question: Why does this mistake hit only one PC?

Andyhhp
Moderator
Posts: 387
Joined: Tue Oct 23, 2007 10:05 am
Location: 127.0.0.1
Contact:

Re: What is wrong on some PC with this 1st stage BL?

Post by Andyhhp » Thu Aug 20, 2009 11:13 am

thats even more confusing now

you set the stack segment as 0x9000 which makes the linear address of the stack start from 0x90000 and work downwards.

reading 14 sectors from the disk starting at 0x0000:0x7C00 shouldnt hit the stack at all :S

How much ram have you got on this computer?
Image

ehenkes
Posts: 34
Joined: Fri Jul 24, 2009 5:35 pm

Re: What is wrong on some PC with this 1st stage BL?

Post by ehenkes » Thu Aug 20, 2009 4:11 pm

I tried to put the stack below the boot sector at linear 0x7C00, but you are right its stack segment times 0x10. Thus, I was content with this ss = 0x9000. 8)
RAM is 2 GB.

Andyhhp
Moderator
Posts: 387
Joined: Tue Oct 23, 2007 10:05 am
Location: 127.0.0.1
Contact:

Re: What is wrong on some PC with this 1st stage BL?

Post by Andyhhp » Thu Aug 20, 2009 4:12 pm

which still doesnt answer the question as to why it wont boot :S
Image

ehenkes
Posts: 34
Joined: Fri Jul 24, 2009 5:35 pm

Re: What is wrong on some PC with this 1st stage BL?

Post by ehenkes » Thu Aug 20, 2009 7:32 pm

Yes, that is irritating, but at a tester partner there was the same effect. :?

Post Reply