Re: Real machine vs bochs
Posted: Fri Feb 15, 2013 3:35 am
I meant that TS should put N into HiddenSectors field by hand because in his source this field holds 0.
The Place to Start for Operating System Developers
http://f.osdev.org/
So when you say it works in Bochs, you're actually working from an image rather than a real drive, and that means there's no guarantee at all that the physical disk you're using on real hardware is correctly organised. I can't actually find a way to make Bochs run a physical disk, but I have just run my OS off a physical disk in Qemu for the first time to see if Qemu can do this, and it can. So, if you can get your OS to run from an image in Qemu but it fails to run from a physical drive in Qemu, that should tell you something useful.Ahmed wrote:Now we are on to something !! No I did not account for any partitioning, i set up the USB using HxD the same way I set up a disk Image for Bochs! I am a newbie and I wasnt aware of the partition table thingy ( so that could very well explain why there are always zeros in the RAM)
No. The MBR's code typically searches the partition table for a partition that is marked as "active", then loads the first sector of that partition and passes control to it (essentially the VBR is "chainloaded" by the MBR).Ahmed wrote:1) Will the bios auto detect the VBR and load it @ 0x7C00 instead of the MBR ?
That looks like a default MBR (for floppy) or VBR (for partitioned devices) installed by Windows when it creates a FAT file system; which only really tells the user that the disk isn't bootable (e.g. in case they try to boot a non-bootable data disk). I don't know if you're displaying "sector 0" of a partition or if you're displaying sector 0 of a disk (I've never used DiskPart, but it's obvious there's no space for a partition table in there).Ahmed wrote:2) After going through the standard procedure with DiskPart this is what I found @ sector 0 using HxD:
It's possible for USB. See above what I said about hiding some sectors by BIOS. You should provide correct booting in both cases.Ahmed wrote:1) Will the bios auto detect the VBR and load it @ 0x7C00 instead of the MBR ?
To see all available sectors you should open PHYSICAL disk, not LOGICAL. Look at your dump. The partition starts at physical sector 0x80 (logical sector 0) because DiskPart put this value into HiddenSectors field. One "empty" sector between boot sector and FAT is a result of previous editing BPB+ structure by hand when you put 2 into ReservedSectors field. Bytes from disp 0x10 to 0x1F have very strange values. It looks as if they were placed not in own place2) After going through the standard procedure with DiskPart this is what I found @ sector 0 using HxD...
Code: Select all
[bits 16]
jmp main
;*********************************************
; BIOS Parameter Block
;*********************************************
bpbOEM db "ATLAM OS"
bpbBytesPerSector: DW 512
bpbSectorsPerCluster: DB 1
bpbReservedSectors: DW 2
bpbNumberOfFATs: DB 1
bpbRootEntries: DW 512
bpbTotalSectors: DW 0xFFFF
bpbMedia: DB 0xf8 ;; 0xF1
bpbSectorsPerFAT: DW 494
bpbSectorsPerTrack: DW 18
bpbHeadsPerCylinder: DW 2
bpbHiddenSectors: DD 0
bpbTotalSectorsBig: DD 0
DRIVE_NUMBER equ 7C24h
DRIVE_TYPE equ 7C3Eh
NUMBER_OF_HEADS equ 7C1Ah
NUMBER_OF_DRIVES equ 7C3Fh
SECTORS_PER_TRACK equ 7C18h
bsExtBootSignature: DB 0x29
bsSerialNumber: DD 0xa0a1a2a3
bsVolumeLabel: DB "MOS FLOPPY "
bsFileSystem: DB "FAT16 "
;*********************************************
; End of BIOS PARAMETER BLOCK
;*********************************************
;************************************************;
; Prints a string
;************************************************;
Print:
lodsb ; load next byte from string from SI to AL
or al, al ; Does AL=0?
jz PrintDone ; Yep, null terminator found-bail out
mov ah, 0eh ; Nope-Print the character
int 10h
jmp Print ; Repeat until null terminator found
PrintDone:
ret ; we are done, so return
;************************************************;
; Convert CHS to LBA
;************************************************;
ClusterLBA:
sub ax, 0x0002 ; zero base cluster number
xor cx, cx
mov cl, BYTE [bpbSectorsPerCluster] ; convert byte to word
mul cx
add ax, WORD [datasector] ; base data sector
ret
;************************************************;
; Failing to Load Proceedure
;************************************************;
FAILURE:
mov si, msgFailure
call Print
mov ah, 0x00
int 0x16 ; await keypress
int 0x19 ; warm boot computer
;************************************************;
; Convert LBA to CHS
; AX=>LBA Address to convert
;
; 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 [SECTORS_PER_TRACK] ; calculate
inc dl ; adjust for sector 0
mov BYTE [absoluteSector], dl
xor dx, dx ; prepare dx:ax for operation
div WORD [NUMBER_OF_HEADS] ; calculate
mov BYTE [absoluteHead], dl
mov BYTE [absoluteTrack], al
ret
;************************************************;
; Reads a series of sectors
; CX=>Number of sectors to read
; AX=>Starting sector
; ES:BX=>Buffer to read to
;************************************************;
ReadSectors:
.MAIN
mov di, 0x0005 ; five retries for error
.SECTORLOOP
push ax
push bx
push cx
call LBACHS ; convert starting sector to CHS
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 [DRIVE_NUMBER] ; 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, msgReadSuccess
call Print
pop cx
pop bx
pop ax
add bx, WORD [bpbBytesPerSector] ; queue next buffer
inc ax ; queue next sector
loop .MAIN ; read next sector
ret
;*********************************************
; Bootloader Entry Point
;*********************************************
main:
;----------------------------------------------------
; code located at 0000:7C00, adjust segment registers
;----------------------------------------------------
cli ; disable interrupts
mov ax, 0x07C0 ; setup registers to point to our segment
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
;----------------------------------------------------
; create stack
;----------------------------------------------------
mov ax, 0x0000 ; set the stack
mov ss, ax
mov sp, 0xFFFF
sti ; restore interrupts
;----------------------------------------------------
CLD
DiskParam:
push dx
push es
mov ah, 8
int 13h ; get drive parameters
mov [DRIVE_TYPE], bl
and cx, 3Fh ; maximum sector number
mov [SECTORS_PER_TRACK], cx
mov [NUMBER_OF_DRIVES], dl
movzx dx, dh ; maximum head number
add dx, 1
mov [NUMBER_OF_HEADS], dx
pop es
pop dx
mov [DRIVE_NUMBER], dl
LOAD:
xor cx,cx
xor ax,ax
xor bx,bx
mov ax, 0x0210 ; LBA of Sector to read
mov bx, 0x0440 ; Address to Load to
mov cx, 0x0002 ; Number of sectors to read
call ReadSectors
mov cx, 0x000D ; Counter String length
mov di,0x05A3 ; Expected String Location in RAM
mov si, String ; String requiring matching
repe cmpsb ; test for entry match
je KERNL
jmp FAILURE
KERNL:
mov si, msgConfirmString
call Print
jmp 0x07C0:0x0440
;*********************************************
; Messages Section
;*********************************************
String db "Searching for Operating System"
msgReadSuccess db 0x0D, 0x0A, "Krnl Rd Suc", 0x0D, 0x0A, 0x00
msgConfirmString db 0x0D, 0x0A, "Kernel Confirmed in Memory", 0x0D, 0x0A, 0x00
msgReadFail db 0x0D, 0x0A, "Krnl Rd Fld", 0x0D, 0x0A, 0x00
msgFailure db 0x0D, 0x0A, "ERR:Pres Key Rbt", 0x0A, 0x00
;*********************************************
; Data Section
;*********************************************
absoluteSector db 0x00
absoluteHead db 0x00
absoluteTrack db 0x00
datasector dw 0x0000
cluster dw 0x0000
;*********************************************
; Boot Sector Signature
;*********************************************
TIMES 510-($-$$) DB 0
DW 0xAA55
Code: Select all
org 7C00h
virtual
bs BS
end virtual
jmp short @f
nop
rb BS_SIZE-3
@@:
...
mov [bs.DriveNumber],dl
; or
mov [$$+BS.DriveNumber],dl
; if virtual block was not declared
It was just example. You can use a traditional technique as well:Ahmed wrote:org 7C00h ---> ok no problem here
...
Code: Select all
org 7C00h
jmp short @f
nop
OEMName rb 8
BytesPerSector dw ?
...
@@:
...
mov [DriveNumber],dl ; actually I use a stack to save local variables
Code: Select all
move 3
pass BS_SIZE-3
move 512-BS_SIZE
Code: Select all
struc BS
{
.Jump rb 3
.OEMName rb 8
.BytesPerSector dw ?
.SectorsPerCluster db ?
.ReservedSectors dw ?
.FATs db ?
.RootEntries dw ?
.TotalSectors16 dw ?
.Media db ?
.FATSize16 dw ?
.SPT dw ?
.Heads dw ?
.HiddenSectors dd ?
.TotalSectors32 dd ?
.DriveNumber db ?
.Reserved1 db ?
.BootSignature db ?
.VolumeID dd ?
.VolumeLabel rb 11
.FSType rb 8
}