Page 1 of 1

debugging on a real pc [FIXED]

Posted: Thu Feb 22, 2007 10:50 am
by GLneo
hi all, well my kernel just got some basic paging and it works on all emulators i can find, but it crashes on real PC's ? Normally i can move a "jmp $" around and compile and emulate in 20 sec and find the problem command and find the bug. now I'm going to have to do some debugging on a real PC, which may take 10 min to make a floppy disk, shutdown my pc, boot, and get windows back up to the point where i can compile and start the process over, i was thinking i could use my keyboard LED's and hotkeys to move stuff around but i was wondering if any of you have come up with a cool way to debug on a real PC with no text display?

thx!

Posted: Thu Feb 22, 2007 10:58 am
by muisei
Try with a 'print' function.Print something before and after every operator and you'll see where is the problem.

Update:I've read somewhere for debugging methot using serial com port, but for the purpose you'll need a second PC.

Posted: Thu Feb 22, 2007 11:28 am
by Combuster
without text display is rather difficult: i normally would poke bytes into video memory to see where things lock up.

That means you either find a different way of outputting. Some crazy ideas include doing knight rider on your keyboard or playing your favorite song on the pc speaker and see where it stops/hangs.

In the meantime, have you tried virtual machines instead of emulators. They save you from the slow reboot cycle... Also, you might find a spare box useful

Also, i have a garbage stub in my kernel that sets all memory to 0xCCs (credits to Brendan for the idea) which causes a lot of extra bugs to appear in emulators that normally only show on real hardware.

Posted: Thu Feb 22, 2007 11:39 am
by Dex
You use this:

Code: Select all

mov   byte [es:0xB809E], "1"
;some code
mov   byte [es:0xB809E], "2"
;some code
mov   byte [es:0xB809E], "3"
;some code
mov   byte [es:0xB809E], "4"
;some code
From pmode
Or this

Code: Select all

beep:
       pushad
        call  Sound
        call  DeLay
        call  NoSound
        popad
        ret

 ;----------------------------------------------------;
 ; Sound                                              ;
 ;----------------------------------------------------;
Sound:
        mov   bx,[Hz]
        mov   ax,0x34dd
        mov   dx,0x0012
        cmp   dx,bx
        jnc   Done1
        div   bx
        mov   bx,ax
        in    al,0x61
        test  al,3
        jnz   A99
        or    al,3
        out   0x61,al
        mov   al,0xb6
        out   0x43,al
A99:
        mov   al,bl
        out   0x42,al
        mov   al,bh
        out   0x42,al
Done1:
        ret
 ;----------------------------------------------------;
 ; NoSound                                            ;
 ;----------------------------------------------------;
NoSound:
        in    al,0x61
        and   al,11111100b
        out   0x61,al
        ret

 ;----------------------------------------------------;
 ; DeLay.                                          ;
 ;----------------------------------------------------;
DeLay:
        mov   ecx,0xffff                                  ; Mov ecx, number of loops
BusyDelay:                                           
        nop                                             ; Do a null operation(xchg ax,ax)
        nop                                             ; Do a null operation(xchg ax,ax)
        nop                                             ; Do a null operation(xchg ax,ax)
        nop                                             ; Do a null operation(xchg ax,ax)
        loop  BusyDelay                             
        ret
You will need to get key press before calling beeps, you can than count the beeps.

Posted: Thu Feb 22, 2007 4:45 pm
by GLneo
i would like to try the garbage memory idea, how do i do that in 16 bit asm ( in my boot loader )

thx

Posted: Thu Feb 22, 2007 5:59 pm
by Combuster
you can only trash parts of the lower memory from real mode...

untested:

Code: Select all

; destroyed regs: ax cx dx si di
; destroyed segregs: es
mov si, 0x0800
mov dx, 18      ;18 32k blocks
mov al, 0xcc    ;garbage
cld
loop:
mov es, si      ;load segment to fill
xor di, di
mov cx, 0x8000
rep stosb       ;fill with 0xcc's
add si, 0x800   ;go to next 32k block
dec dx
jnz loop
;if I counted correct, its 29 bytes
this should trash 00008000-00098000 (and thus leaving the locations where the bios keeps its stuff untouched)

Posted: Mon Feb 26, 2007 11:13 am
by GLneo
ok, after getting two computers together, which sped things up a bit, i have isolated the problem:

Code: Select all

 SECTION .text
 start:
;     mov esp, _K_stack
     mov edi, bss
     mov ecx, bsslength
     xor eax, eax
     cld
     rep stosd
     call _main_code
     jmp $
             

Code: Select all

void main_code()
{
    unsigned int start, end;
    asm("rdtsc\n":"=a"(start):);
//    logo();
    cls();
    start_computer();......
when i put a "jmp $" before "call _main_code" the real pc locks up( which is good becouse execution got to the "jmp $" ) but if i put "for(;;);" after " void main_code()" it reboots ( meaning the problem is before it got to "for(;;);"), does any one know why this jump would work on bochs and qemu but not on a real pc???

thx!

Posted: Mon Feb 26, 2007 11:16 am
by uglyoldbob
Why is the code setting up your stack commented out? That would cause that problem in a heartbeat (C/C++ use the stack for local variables and arguments. No stack = fail to execute properly)

Posted: Tue Feb 27, 2007 9:58 am
by GLneo
it's commented out because _K_stack is an array in my .bss and my stack during startup it grows tough my .data and kills my kernel... so now i just "mov esp, 090000h" in my boot sector, but thx for the try!

Posted: Tue Feb 27, 2007 10:15 am
by deadmutex
Hmm that's strange... Are you sure that '_main_code' is a valid address?

Posted: Tue Feb 27, 2007 11:01 am
by Candy
uglyoldbob wrote:Why is the code setting up your stack commented out? That would cause that problem in a heartbeat (C/C++ use the stack for local variables and arguments. No stack = fail to execute properly)
Actually, on a fairly modern computer, it'll reboot a lot faster than a heartbeat.

Posted: Tue Feb 27, 2007 12:05 pm
by GLneo
how would i check if '_main_code' is a valid address, it must be sorta valid it works on bochs + qemu, also is 090000h a good place for my stack?

Posted: Thu Mar 01, 2007 7:53 am
by Kenny
I had a similar error to this when I first started mixing C and assembly, I finally tracked down the cause of my problem to the "for ( ; ; )" command itself.

I found, by using a disassembler (ndisasm) on my compiled C kernel, that my compiler wasn't putting in a relative jump for the infinite loop, it was putting in an absolute jump to a specific memory location.

With a little more digging, I realised that I was compiling the C code for one base location, then loading it somewhere else in memory by accident.

When the processor jumped into the C code, the infinite loop jump was jumping to an unexpected offset in memory, and the real computer triple-faulted and reset.

I'm afraid this wouldn't explain why the emulators worked correctly though.

Hope this helps

Posted: Thu Mar 01, 2007 10:05 am
by GLneo
well i think i found the problem, the PC i was doing a lot of testing on is bad at booting ( it wont boot Slackware 11.0 ) but i found some more PC's and it seems the PC's i was trying it on were just bad at booting,

thanks for everyones help!