OS debugging
OS debugging
I'd like to be able to step through my OS code from the bootloader and onward. Is there a way to do this? People suggested using emulators, although I'm having trouble with qemu, its strange, i get the error FATAL: INT 18: Boot Failure. The funny thing is this floppy disk Im using works on a regular computer. Anyone have any ideas? I appreciate any responses!
Re: OS debugging
well
if it dont work on a emu, then it is not good.
but try using BOCSH, it also include a program to cracft a image ( floppy)
have you "pointed" currectly in qemu ?
and do you have the boot segniture ?
KMT dk
if it dont work on a emu, then it is not good.
but try using BOCSH, it also include a program to cracft a image ( floppy)
have you "pointed" currectly in qemu ?
and do you have the boot segniture ?
KMT dk
well, what to say, to much to do in too little space.
when it goes up hill, increase work, when it goes straight, test yourself but when going down, slow down.
when it goes up hill, increase work, when it goes straight, test yourself but when going down, slow down.
Re: OS debugging
what do you mean by pointed? yes there is a boot signature. my boot loader will output Loading Boot Image and after that i receive the error
Re: OS debugging
good,
pointer
well
i assume you have compiled the source code, to a flat binary.
then you might have placed the code on a VFD (virtuel floppy drive), or "pointed" at the file(source file)
KMT dk
pointer
well
i assume you have compiled the source code, to a flat binary.
then you might have placed the code on a VFD (virtuel floppy drive), or "pointed" at the file(source file)
KMT dk
well, what to say, to much to do in too little space.
when it goes up hill, increase work, when it goes straight, test yourself but when going down, slow down.
when it goes up hill, increase work, when it goes straight, test yourself but when going down, slow down.
- Love4Boobies
- Member
- Posts: 2111
- Joined: Fri Mar 07, 2008 5:36 pm
- Location: Bucharest, Romania
Re: OS debugging
QEMU gives that exact same error message when INT 18H is invoked. It's meant to return control to the BIOS when a device is unbootable, but it's a software interrupt. Are you using a custom boot loader? It may be that your boot loader does something wrong (like, if you have a MBR, it may not have the partition table set right - or not set at all).
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
[ Project UDI ]
Re: OS debugging
heres the source to my bootloader
Code: Select all
;*************************************************************************
;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 ; files 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 "KERNEL BIN"
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
;*************************************************************************
- Love4Boobies
- Member
- Posts: 2111
- Joined: Fri Mar 07, 2008 5:36 pm
- Location: Bucharest, Romania
Re: OS debugging
Things I've noticed not to be right:
- Should have ORG 7C00H. You're mistaking segments with offsets. I also saw that you set all your segment registers to 7C00H later on, instead of 0000H. Besides, you don't even need all of them, you're just wasting precious bytes.
- You don't actually need to CLI and STI. "MOV SS,..." and the instruction after it (whichever that is) are executed atomically. Just make sure the next one is "MOV SP,..." and you'll save couple of bytes there.
- I also noticed you have JMPs to labels that have RETs. Something is terribly wrong there.
- You're trying to use some black magic there, pushing things on the stack and returning to the kernel (I didn't bother checking to see if you've pushed the right values there). I can't see why you'd wanna do that. All you need is a long jump.
- Why on earth is DriveNumber set to 00H (floppy). Besides the fact that this is what's causing your error, BIOS transfers control to the boot sector with the current drive passed in DL. Just be sure not to loose that value.
- Check again to see how the BIOS expects the CHS to be passed to it for CHS calls.
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
[ Project UDI ]
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: OS debugging
uhm, The ORG matches the loaded segments and is therefore correct (ds:0 points to start of the file, ds:7c00 points beyond)
- Firestryke31
- Member
- Posts: 550
- Joined: Sat Nov 29, 2008 1:07 pm
- Location: Throw a dart at central Texas
- Contact:
Re: OS debugging
You seem to forget that 0x07C0:0x0000 and 0x0000:0x7C00 end up being the same address. This means that his ORG 0 indicates offsets from the segment 0x07C0, which is perfectly valid. (Although I do prefer 0x0000:0x7C00 myself...)Love4Boobies wrote:Should have ORG 7C00H. You're mistaking segments with offsets. I also saw that you set all your segment registers to 7C00H later on, instead of 0000H. Besides, you don't even need all of them, you're just wasting precious bytes.
Owner of Fawkes Software.
Wierd Al wrote: You think your Commodore 64 is really neato,
What kind of chip you got in there, a Dorito?
- Love4Boobies
- Member
- Posts: 2111
- Joined: Fri Mar 07, 2008 5:36 pm
- Location: Bucharest, Romania
Re: OS debugging
7C00H is defined by the BIOS Boot Specification. I'm sorry, I didn't see right, I thought it was 7C00:0000H, not 07C0:0000H. My bad!
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
[ Project UDI ]
Re: OS debugging
You could use the worlds best debug code:
Code: Select all
;*******************
push ax
push es
xor ax,ax
mov es,ax
mov byte [es:0xB89E], "1"
int 0x16 ; await keypress
pop es
pop ax
;******************
; Some code here
;*******************
push ax
push es
xor ax,ax
mov es,ax
mov byte [es:0xB89E], "2"
int 0x16 ; await keypress
pop es
pop ax
;******************
; Some code here
;*******************
push ax
push es
xor ax,ax
mov es,ax
mov byte [es:0xB89E], "3"
int 0x16 ; await keypress
pop es
pop ax
;******************
; Some code here
;*******************
push ax
push es
xor ax,ax
mov es,ax
mov byte [es:0xB89E], "4"
int 0x16 ; await keypress
pop es
pop ax
;******************
; Some code here
;*******************
push ax
push es
xor ax,ax
mov es,ax
mov byte [es:0xB89E], "5"
int 0x16 ; await keypress
pop es
pop ax
;******************
; Some code here
;*******************
push ax
push es
xor ax,ax
mov es,ax
mov byte [es:0xB89E], "6"
int 0x16 ; await keypress
pop es
pop ax
;******************
; Some code here
;AND SO NO
Re: OS debugging
Shouldn't that write to the video memory be like this?
Code: Select all
;*******************
push ax
push es
xor ax,ax
mov es,ax
mov byte [es:0xB809E], "1"
int 0x16 ; await keypress
pop es
pop ax
Re: OS debugging
No it should be more like this:ru2aqare wrote:Shouldn't that write to the video memory be like this?
Code: Select all
;******************* push ax push es xor ax,ax mov es,ax mov byte [es:0xB809E], "1" int 0x16 ; await keypress pop es pop ax
Code: Select all
;*******************
push ax
push es
mov ax,0xB800
mov es,ax
mov byte [es:0x9E], "1"
xor ax,ax
int 0x16 ; await keypres
pop es
pop ax
-
- Member
- Posts: 116
- Joined: Wed Oct 22, 2008 2:21 am
- Location: Roma,Italy
Re: OS debugging
Very Funnykmtdk wrote:well
if it dont work on a emu, then it is not good.