Page 5 of 8
Re: Problem on real hardware
Posted: Wed Dec 07, 2011 12:19 pm
by Combuster
Can you post your current code, After all this whole lot of better and worse ideas I can't tell what you have, and I'd like to poke it onto a floppy drive and see what it actually does.
After 5 pages of effort I might even fix your code for you.
Re: Problem on real hardware
Posted: Wed Dec 07, 2011 12:29 pm
by romfox
Ok here is my current bootsector:
Code: Select all
%define BASE 0x100 ; 0x0100:0x0 = 0x1000
%define KSIZE 50 ; nombre de secteurs a charger
[BITS 16]
[ORG 0x7c00]
jmp 0x0:start
%include "fn_boot.inc"
start:
; initialisation des segments en 0x07c0
xor ax, ax
mov ds, ax
mov es, ax
mov fs, ax
mov ss, ax
mov sp, 0xf000
; recuparation de l'unite de boot
mov [bootdrv], dl
; affiche un msg
mov si, msgDebut
call print16
push es
push ds
initialise_disque: ; Initialise le lecteur de disque
xor ax, ax
mov dl, [bootdrv]
int 0x13
jc initialise_disque ; En cas d'erreur on recommence (sinon, de toute façon, on ne peut rien faire)
pop ds
push ds
lire:
mov ax, BASE
mov es, ax
mov [reg16], es
call print_reg16
xor bx, bx
mov ah, 2 ; Fonction 0x02 : chargement mémoire
mov al, KSIZE ; On lit KSIZE secteurs
xor ch, ch ; Premier cylindre (n° 0)
mov cl, 2 ; Premier secteur (porte le n° 2, le n° 1, on est dedans, et le n° 0 n'existe pas)
xor dh, dh ; Tête de lecture n° 0
mov dl, [bootdrv]
int 0x13 ; Lit !
jc lire ; En cas d'erreur, on recommence
pop ds
pop es
; passage en modep
cli
mov ax, 0
mov ds, ax
lgdt [gdtptr] ; charge la gdt
mov eax, cr0
or ax, 1
mov cr0, eax ; PE mis a 1 (CR0)
jmp 0x8:next
[BITS 32]
next:
mov ax, 0x10 ; segment de donne
mov ds, ax
mov fs, ax
mov gs, ax
mov es, ax
mov ss, ax
mov esp, 0x9F000
; Affichage d'un message par ecriture dans la RAM video
mov byte [0xB8140], 'H'
mov byte [0xB8141], 0x57
.wait:
in al, 0x64
and al, 1
jz .wait
jmp BASE << 4
;--------------------------------------------------------------------
bootdrv: db 0
msgDebut: db "Loading kernel...", 13, 10, 0
;--------------------------------------------------------------------
gdt:
db 0, 0, 0, 0, 0, 0, 0, 0
gdt_cs:
dd 0xffff, 0x00cf9a00
gdt_ds:
dd 0xffff, 0x00cf9200
gdtend:
;--------------------------------------------------------------------
gdtptr:
dw gdtend - gdt -1
dd gdt ; base
;--------------------------------------------------------------------
;; NOP jusqu'a 510
times 510-($-$$) db 144
dw 0xAA55
and fn_boot.inc:
Code: Select all
; -------------------------------------------------------------
; Fonction d'affichage qui utilise le BIOS
; -------------------------------------------------------------
print16:
push ax
push bx
.debut:
lodsb
or al, al ; zero=end of str
jz .end ; get out
mov ah, 0x0E
mov bl, 0xff
int 0x10
jmp .debut
.end:
pop bx
pop ax
ret
; -------------------------------------------------------------
; Fonction d'affichage qui utilise le BIOS
; -------------------------------------------------------------
print_reg16:
pusha
mov di, buff16
mov ax, [reg16]
mov si, hexch
mov cx, 4
.debut:
rol ax, 4
mov bx, ax
and bx, 0x0f
mov bl, [si+bx]
mov [edi], bl
inc di
dec cx
jnz .debut
mov si, buff16
call print16
popa
ret
reg16: dw 0
buff16: db '0000', 0
hexch: db '0123456789abcdef'
I don't post any kernel cause it doesn't jump to any one ^^.
But I try with that :
Code: Select all
[BIT 32]
[ORG 0x1000]
mov byte [0xB8140], 'K'
mov byte [0xB8141], 0x57
jmp $
=)
Re: Problem on real hardware
Posted: Wed Dec 07, 2011 12:32 pm
by guyfawkes
If i was you, i would take a peace of code from your stage 1 and write it to the jump address, then jump to it, if it works then you know that the original code is not being written there.
Example
Code: Select all
Mov cr0, eax
jmp 8:next
[BITS 32]
next:
mov ax,0x10
mov ds,ax
mov ss,ax
mov es,ax
mov gs,ax
mov fs,ax
; some code which init segments
mov byte [0xb8a00], 'H'
mov byte [0xb8a01], 0x57
mov esi,TestCode
mov edi,0x1000
mov ecx,TestCodeEnd-TestCode
rep movsb
jmp 0x1000
jmp $
[BITS 32]
TestCode:
mov byte [0xb8a00], 'T'
mov byte [0xb8a01], 0x57
jmp $
TestCodeEnd:
Note untested
See if the T gets printed.
Re: Problem on real hardware
Posted: Wed Dec 07, 2011 12:42 pm
by romfox
Using this it works so I think it's an int 0x13 problem but can't find it.
And can somebody explain me why does it work on Bochs and VirtualBox ?
Re: Problem on real hardware
Posted: Wed Dec 07, 2011 12:43 pm
by Muneer
Combuster wrote:What epic nonsense. The address is a completely independent type. Only the ORG directive for binary or the linker for ordered formats determine if the address will actually fit within 16 bits or n
oops. Sorry about that... I should have been thinking of something else. Although I knew that but it seems for a split second I got ORG and BITS confused.... Thanks for correcting.
Re: Problem on real hardware
Posted: Wed Dec 07, 2011 12:59 pm
by DavidCooper
Are you booting from an external USB hard drive? If so, you probably do need a BPB. I don't know, so see what others think. I've only ever booted from floppy disks, which I do via USB now, and with a BPB.
Re: Problem on real hardware
Posted: Wed Dec 07, 2011 1:01 pm
by guyfawkes
romfox wrote:Using this it works so I think it's an int 0x13 problem but can't find it.
And can somebody explain me why does it work on Bochs and VirtualBox ?
Emulators are not 100%, you will find many times that it works on emulators, but not real PC.
Eg: I am sure emulator enable A20, even if not in code.
So now you need to debug your (int 0x13) code, there's a chance its being written to the wrong address.
You can try writing a number to that address before (int 0x13) and try and read it back after.
One thing to NOTE do not try and read a number of sectors at a time, its buggy, read one sector at a time, but do it in a loop.
Re: Problem on real hardware
Posted: Wed Dec 07, 2011 1:04 pm
by DavidCooper
guyfawkes wrote:One thing to NOTE do not try and read a number of sectors at a time, its buggy, read one sector at a time, but do it in a loop.
There's no need to go that far, and at the moment it only needs to load one for the kernel to respond when jumped to. It isn't doing that, so it looks as if none of it's being loaded.
Re: Problem on real hardware
Posted: Wed Dec 07, 2011 1:08 pm
by DavidCooper
romfox wrote:And can somebody explain me why does it work on Bochs and VirtualBox ?
They aren't so fussy, but you'll find that real hardware can often be less fussy than VMs in other ways - you just have to keep modifying your code till it works on everything you have available to try it on, and then it should work on most of the machines out there.
Re: Problem on real hardware
Posted: Wed Dec 07, 2011 1:17 pm
by DavidCooper
Code: Select all
; affiche un msg
mov si, msgDebut
call print16
push es
push ds
You're still pushing segment registers after calling a BIOS routine which may have messed them up. It's unlikely to happen, but you shouldn't trust the BIOS to preserve anything other than SS and SP.
Re: Problem on real hardware
Posted: Wed Dec 07, 2011 1:30 pm
by Muneer
Hi
I come with good news. Your code worked like a charm in my PC (real hardware) only when I set USB Emulation to HDD and shows 0100 with a pink H. Also I think I had a similar problem trying to boot from a USB which when formatted in fat32 from ubuntu said 0x0B. This usb stick I tested with some time ago marked fat32 0x0C (LBA)...
When I set USB to Floppy Emulation. Only Kernel Loading is displayed
Re: Problem on real hardware
Posted: Wed Dec 07, 2011 1:33 pm
by DavidCooper
Sorry to travel back in time, but I don't want anyone to be confused by this stuff:-
HardCoder wrote:A quick read through the code revealed
Code: Select all
xor eax, eax ; calcule l'adresse lineaire de GDT -- EAX IS 0 NOW
xor ebx, ebx
mov ax, ds ; WHY DO YOU WANT THE VALUE OF DS
mov ecx, eax
shl ecx, 4
mov bx, gdt ; THE LABEL gdt IS 32 BITS IN SIZE. ONLY MUST DO MOV EBX,gdt
add ecx, ebx ; ADDING THE WRONG VALUE
mov dword [gdtptr+2], ecx
The code above takes the content of DS (which may have been corrupted earlier by the BIOS), multiplies it by 16 (by shifting) to turn it into an actual address, then adds the offset address of the gdt to it and ultimately calculates the correct address of the GDT - it's a complicated way to go about something which should be very simple (and that's now been put right in the latest version), but it worked in VMs because it's essentially right, apart from the possibility of DS becoming corrupted.
Code: Select all
; passage en modep
cli
lgdt [gdtptr] ; charge la gdt
mov eax, cr0
or ax, 1
mov cr0, eax ; PE mis a 1 (CR0) ; DS MUST BE ZERO BEFORE JUMPING TO PROTECTED MODE
jmp 0x8:next
DS needs to be correct for the lgdt instruction (which it will be unless the BIOS corrupted it), but it doesn't matter what it contains during the actual switch to protected mode, nor during the far jump immediately afterwards which loads CS with a protected mode segment.
Also
Code: Select all
; YOU HAVENT CHANGED YOUR CS SO IT IS GARBAGE AT BOOT TIME. EITHER THAT OR ORG 7C00
[ORG 0x0]
It didn't matter in this case, but it certainly isn't a bad idea to do a far jump early on to get 0 into CS.
Re: Problem on real hardware
Posted: Wed Dec 07, 2011 1:35 pm
by Muneer
Hi
I come with good news. Your code worked like a charm in my PC (real hardware) only when I set USB Emulation to HDD and shows 0100 with a pink H. Also I think I had a similar problem trying to boot from a USB which when formatted in fat32 from ubuntu said 0x0B. This usb stick I tested with some time ago marked fat32 0x0C (LBA)...
When I set USB to Floppy Emulation. Only Kernel Loading is displayed
EDIT: I made no changes to your code except padding the rest of the kernel with 512 bytes. Apart from that your code works
Re: Problem on real hardware
Posted: Wed Dec 07, 2011 1:50 pm
by guyfawkes
DavidCooper wrote:guyfawkes wrote:One thing to NOTE do not try and read a number of sectors at a time, its buggy, read one sector at a time, but do it in a loop.
There's no need to go that far, and at the moment it only needs to load one for the kernel to respond when jumped to. It isn't doing that, so it looks as if none of it's being loaded.
But he's trying to read more than one sector at a time
Code: Select all
mov ah, 2 ; Fonction 0x02 : chargement mémoire
mov al, KSIZE ; See here 50
xor ch, ch ; Premier cylindre (n° 0)
mov cl, 2 ; Premier secteur (porte le n° 2, le n° 1, on est dedans, et le n° 0 n'existe pas)
xor dh, dh ; Tête de lecture n° 0
mov dl, [bootdrv] ; Toujours pas d'identifiant de disque, c'est toujours le même.
int 0x13 ; Lit !
That is buggy on most BIOS, you should only read/write one sector at a time.
INT 13,2 - Read Disk Sectors
AH = 02
AL = number of sectors to read (1-128 dec.)
CH = track/cylinder number (0-1023 dec., see below)
CL = sector number (1-17 dec.)
DH = head number (0-15 dec.)
DL = drive number (0=A:, 1=2nd floppy, 80h=drive 0, 81h=drive 1)
ES:BX = pointer to buffer
AL should only ever have 1 in it.
Re: Problem on real hardware
Posted: Wed Dec 07, 2011 1:54 pm
by romfox
So I have to turn the emulation mode to HDD ? How can I do that ? (Still searching on google).
Edit : even reading 1 sector it doesnt work I would have say.