Problem on real hardware

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
romfox
Member
Member
Posts: 50
Joined: Wed Nov 16, 2011 8:14 am

Problem on real hardware

Post by romfox »

Hi all,
After a long time trying to make it work by myself, I ask your help...
The problem : my OS works on Bochs, but doesn't work on a real computer.
My bootloader seems to work cause if I put a "jmp $" before the "jmp 0x8:BASE << 4" I can see my bootloader message (which is between kernel copy to RAM and protected mode activation, so it means my kernel is loaded).
But whithout that, my computer restart when it tries to jump to my Kernel.
I don't overwrite the BIOS normally, but probably I do something wrong.
My boot sector :

Code: Select all

%define BASE    0x100  ; 0x0100:0x0 = 0x1000
%define KSIZE   50     ; nombre de secteurs a charger

[BITS 16]
[ORG 0x0]

jmp start
%include "fn_boot.inc"
start:

; initialisation des segments en 0x07C0
    mov ax, 0x07C0
    mov ds, ax
    mov es, ax
    mov ax, 0x8000    
    mov ss, ax
    mov sp, 0xf000

; recuparation de l'unite de boot
    mov [bootdrv], dl    

; charger le noyau
    xor ax, ax
    int 0x13

    push es
initialise_disque: ; Initialise le lecteur de disque
    xor ax, ax
    int 0x13
    jc initialise_disque ; En cas d'erreur on recommence (sinon, de toute façon, on ne peut rien faire)
lire:
    mov ax, BASE ; ES:BX = BASE:0000
    mov es, ax
    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
; Toujours pas d'identifiant de disque, c'est toujours le même.
    int 0x13 ; Lit !
    jc lire ; En cas d'erreur, on recommence
    pop es

; initialisation du pointeur sur la GDT
    mov ax, gdtend    ; calcule la limite de GDT
    mov bx, gdt
    sub ax, bx
    mov word [gdtptr], ax

    xor eax, eax      ; calcule l'adresse lineaire de GDT
    xor ebx, ebx
    mov ax, ds
    mov ecx, eax
    shl ecx, 4
    mov bx, gdt
    add ecx, ebx
    mov dword [gdtptr+2], ecx

   mov si, msgDebut
   call print16            ; This messages is spawned by my computer

; passage en modep
    cli
    lgdt [gdtptr]    ; charge la gdt
    mov eax, cr0
    or  ax, 1
    mov cr0, eax        ; PE mis a 1 (CR0)

    jmp next
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    

   ; jmp $     if I do that I see my boot message


    jmp 0x8:0x1000    ; It restart my real computer & works in VMs

;--------------------------------------------------------------------
bootdrv:  db 0
msgDebut: db "Chargement du kernel", 13, 10, 0
;--------------------------------------------------------------------
gdt:
    db 0, 0, 0, 0, 0, 0, 0, 0
gdt_cs:
    db 0xFF, 0xFF, 0x0, 0x0, 0x0, 10011011b, 11011111b, 0x0
gdt_ds:
    db 0xFF, 0xFF, 0x0, 0x0, 0x0, 10010011b, 11011111b, 0x0
gdtend:
;--------------------------------------------------------------------
gdtptr:
    dw 0  ; limite
    dd 0  ; base
;--------------------------------------------------------------------

;; NOP jusqu'a 510
times 510-($-$$) db 144
dw 0xAA55
This is not a kernel problem cause a simple "jmp $" doesn't go executed.

Thanks a lot for reading my bad english.
User avatar
DavidCooper
Member
Member
Posts: 1150
Joined: Wed Oct 27, 2010 4:53 pm
Location: Scotland

Re: Problem on real hardware

Post by DavidCooper »

gdt:
db 0, 0, 0, 0, 0, 0, 0, 0
gdt_cs:
db 0xFF, 0xFF, 0x0, 0x0, 0x0, 10011011b, 11011111b, 0x0
gdt_ds:
db 0xFF, 0xFF, 0x0, 0x0, 0x0, 10010011b, 11011111b, 0x0
gdtend:
Try 11001111b instead of 11011111b. I can't remember what bit-4 actually does, but normally it's 0.
; passage en modep
cli
lgdt [gdtptr] ; charge la gdt
mov eax, cr0
or ax, 1
mov cr0, eax ; PE mis a 1 (CR0)

jmp next
next:
I don't know assembler well enough to know, but is that guaranteed to do a far jump? I can't see anything else wrong at the moment, but I'll have another look if you still can't get it to work.
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming
User avatar
DavidCooper
Member
Member
Posts: 1150
Joined: Wed Oct 27, 2010 4:53 pm
Location: Scotland

Re: Problem on real hardware

Post by DavidCooper »

I've just remembered something else - I didn't see any sign of you taking 1 away from the GDT size before doing the lgdt part.
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming
romfox
Member
Member
Posts: 50
Joined: Wed Nov 16, 2011 8:14 am

Re: Problem on real hardware

Post by romfox »

Thank you for helping me, I changed the bit but this is a free-for-use bit, yes I have correctly modified the size. But now it freezes after displaying the message on my real computer (probably at the "jmp") and still works on VMs...
I don't know for the far jump but I have readen that it's supposed to work.
And I am sure it worked before... Probably a beginner mistake but can't find it :(
User avatar
DavidCooper
Member
Member
Posts: 1150
Joined: Wed Oct 27, 2010 4:53 pm
Location: Scotland

Re: Problem on real hardware

Post by DavidCooper »

What are you booting from? If it's a floppy disk, you can't load 50 sectors in one go - you'd need to do 18 instead (or 17 for the first lot as you don't want the boot sector).

[Edit: moved an added question to a new post.]
Last edited by DavidCooper on Mon Dec 05, 2011 6:12 pm, edited 2 times in total.
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming
romfox
Member
Member
Posts: 50
Joined: Wed Nov 16, 2011 8:14 am

Re: Problem on real hardware

Post by romfox »

That's an external HDD, and I already tried to change the number of sectors to read...
I have tried a "jmp 0x8:0x1000" after "mov cr0, eax" and then init segments in the kernel but I still freeze after displaying the message, the computer no longer reboot but it doesn't work more :p
User avatar
DavidCooper
Member
Member
Posts: 1150
Joined: Wed Oct 27, 2010 4:53 pm
Location: Scotland

Re: Problem on real hardware

Post by DavidCooper »

How are you getting the message below printed?
msgDebut: db "Chargement du kernel", 13, 10, 0
From the form that's in, it looks as if you're going to be sending it to the screen via the BIOS, and yet you make it sound as if it works.

Could the problem be something you're doing after the jump? How about posting a little bit of that?
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming
romfox
Member
Member
Posts: 50
Joined: Wed Nov 16, 2011 8:14 am

Re: Problem on real hardware

Post by romfox »

I use the bios to print and I get this string printed yes.

This is my kernel : (dirty I know)

Code: Select all

%define IDTSIZE 50    ; Nombre d'interruptions
%define BASE 0x1000   

; -------------------------------------------------------------

[BITS 32]
[ORG 0x1000]

jmp debut

%include "fn.inc"

debut: 
    call clear
    mov esi, msgKernel01
    call print
    mov esi, msgKernel02
    call print

    lidt [idtptr]
    mov eax, int_clock             ; Init IRQ0
    mov word [idt+32*8], ax            
    mov word [idt+32*8+2], 0x08
    mov word [idt+32*8+4], 0x8e00
    shr eax, 16
    mov word [idt+32*8+6], ax

    mov eax, int_kbd               ; Init IRQ1
    mov word [idt+33*8], ax
    mov word [idt+33*8+2], 0x08
    mov word [idt+33*8+4], 0x8e00
    shr eax, 16
    mov word [idt+33*8+6], ax

    call remap_pic
 
    sti

    jmp $

; -------------------------------------------------------------
; IRQ0 : Timer
; -------------------------------------------------------------

int_clock:
    mov al, 0x20
    out 0x20, al
    iret

; -------------------------------------------------------------
; IRQ1 : Driver Clavier     A chaque fin de ligne la chaine est dans buff_cmd
; -------------------------------------------------------------

int_kbd:
    cli

.wait:
    in al, 0x64
    and al, 1
    jz .wait

    in al, 0x60

    cmp al, 224
    je .wait

    cmp al, 0x3f
    je .refresh

    cmp al, 0x0e
    je .backspace

    cmp al, 0x2a
    je .shift_enable

    cmp al, 0xf0
    jl .release    

    movzx ebx, byte [shift]     ; On converti
    call convert_scan           ; Caractère en ascii maintenant dans esi
    call putc                   ; On affiche

    movzx eax, byte [esi]       
    cmp eax, 0x0a             
    je .end_write

    mov edi, buff_cmd
    add edi, [buff_cmd_size]
    stosb
    add byte [buff_cmd_size], 1
    jmp .end  

.end:
    mov al, 0x20
    out 0x20, al
    sti
    iret 

.refresh:
    call clear
    jmp .end

.shift_enable:
    mov byte [shift], 1
    jmp .end

.shift_disable:
    mov byte [shift], 0
    jmp .end
    
.release:
    sub al, 0x80
    cmp al, 0x2a
    je .shift_disable
    jmp .end

; Backspace, seulement sur la meme ligne pour l'instant
.backspace:
    movzx eax, byte [posx]
    cmp eax, 1
    jl .end
    sub byte [posx], 1
    mov esi, buff_space
    call putc
    sub byte [posx], 1
    call move_cursor
    jmp .end
           
.help:
    mov esi, msgHelp
    call print
    jmp .end   

.end_write:
    movzx edx, byte [buff_cmd_size]
    cmp edx, 0
    je .end
    mov edi, buff_cmd
    add edi, [buff_cmd_size]
    stosb
    mov eax, 0
    stosb
    mov byte [buff_cmd_size], 0
    mov esi, cmd_help
    mov edi, buff_cmd
    mov ecx, 4
    call strncmp
    cmp eax, 0
    je .help
    jmp .end


; -------------------------------------------------------------

msgKernel01: db 'Kernel loaded...', 10, 13, 'Welcome to RomOS 0.1', 10, 0
msgKernel02: db 'Press F5 to refresh sreen.', 10, "Type 'help' for a list of commands availables.", 10, 0
msgHelp: db 'Here is a list of all commands availables : ', 10, 'help', 10, 0

buff_cmd:       times 0xff db 0
buff_cmd_size:  db 0
;--------------------------------------------------------------------

idt:                             ; idt est la table d'interruptions
    times (IDTSIZE*8) db 0       ; 8 * 50 octets aloués (taille_idt_descriptor * nb_interrupt)
        
idtptr:
    dw (IDTSIZE << 3) - 1  ; Nombre de vecteurs d'interruption * 8 - 1
    dd (BASE+idt-$$)    ;  Adresse de la table

; -------------------------------------------------------------

;; NOP jusqu'a 4096
 times 4096-($-$$) db 0x90
And all is working in VMs...

Edit : And a simple kernel doesn't go executed yet...
Last edited by romfox on Mon Dec 05, 2011 6:19 pm, edited 1 time in total.
User avatar
DavidCooper
Member
Member
Posts: 1150
Joined: Wed Oct 27, 2010 4:53 pm
Location: Scotland

Re: Problem on real hardware

Post by DavidCooper »

Before I read through that, I need to know if you're using the BIOS to print that message while in protected mode? It shouldn't be possible.
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming
romfox
Member
Member
Posts: 50
Joined: Wed Nov 16, 2011 8:14 am

Re: Problem on real hardware

Post by romfox »

No, in protected mode I'm writting to 0xB8000 :p
guyfawkes
Member
Member
Posts: 93
Joined: Mon Jul 18, 2011 9:47 am

Re: Problem on real hardware

Post by guyfawkes »

Have try something like this

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)

    jmp 0x8:next   ;<this
[BITS 32]           ;< this
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    

   ; jmp $     if I do that I see my boot message


    jmp 0x8:0x1000    ; It restart my real computer & works in VMs

I do not use nasm so unsure about simtex
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Problem on real hardware

Post by neon »

Hello,

gdt limit should be gdtend - gdt - 1, not gdtend - gdt. Unless I messed it (I cannot read the comments) your code appears to use the latter. The other software that sets gdt base appears correct, however.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
DavidCooper
Member
Member
Posts: 1150
Joined: Wed Oct 27, 2010 4:53 pm
Location: Scotland

Re: Problem on real hardware

Post by DavidCooper »

So I assume that it was a mistake when you said:-
I use the bios to print and I get this string printed yes.
[Edit: no it wasn't a mistake - I missed the bit that called "print" and the code that does the printing is hidden at the top as an %include.]

I still can't see the code that's doing the printing, but assuming the fault isn't there, something may be going wrong with the idt code and removing the message from the screen before you get a chance to see it. Could you try doing something really simple first to see if the kernel's being loaded - start the kernel code by sending few bytes directly to the screen and then follow that with a big delay loop. Try:-

mov al,65
mov ah,12 ;(both decimal)
mov edi,b8000h

then send it to the screen with a lodsw (I think that's the right mnemonics - I don't know because I always use machine code numbers directly: 102 171).

After that, use a delay loop like this:-

xor ecx,ecx
dec ecx

then use the loop instruction - I imagine you'd need to jump to a name for that, but I just use 226 254 which is the loop instruction followed by the jump distance back to the loop instruction again.

That should display a red "A" on the screen for a moment - certainly long enough to see it if this code runs.

Edit: confused myself with mnemonics and told OP to use a movsw instead of a lodsw.
Last edited by DavidCooper on Tue Dec 06, 2011 2:00 pm, edited 2 times in total.
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming
User avatar
DavidCooper
Member
Member
Posts: 1150
Joined: Wed Oct 27, 2010 4:53 pm
Location: Scotland

Re: Problem on real hardware

Post by DavidCooper »

I've got to disappear for many hours now, but that bit of test code I suggested you add to the top of the kernel should tell you if the jump's working. If it isn't working, you know where to look for the fault, but if it is working you'll know for certain that the fault is after the test code. I may have made the loop too long, so adjust it if necessary. You can move the test code lower down the kernel to see where it first fails, and by trying it in lots of different places it should be easy to isolate the point where an instruction is causing the machine to freeze/crash.

Note correction to previous post (lodsw, not movsw).
Last edited by DavidCooper on Mon Dec 05, 2011 6:59 pm, edited 1 time in total.
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming
romfox
Member
Member
Posts: 50
Joined: Wed Nov 16, 2011 8:14 am

Re: Problem on real hardware

Post by romfox »

I was talking about the boot message. Which is spawned by BIOS.
But my kernel's messages don't get spawned, I already have try a verry simple kernel wich directly write to the Video RAM =/

With

Code: Select all

mov cr0, eax

jmp 0x8:next
[BITS 32]
next:
mov ax, 0x10
mov ds, ax
[...]
jmp $
It breaks at "mov ax, 0x10" :s I note that using that I got by Bochs debugger : "Interrupt() : gate descriptor is not a valid sys seg
AND :

CPU protected mode:
CS.mode = 32 bit
SS.mode = 16 bit (?)"

Edit !
Last edited by romfox on Mon Dec 05, 2011 7:06 pm, edited 1 time in total.
Post Reply