OSDev.org

The Place to Start for Operating System Developers
It is currently Wed Apr 17, 2024 7:02 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: bochs I/O apic write with len=2 (should be 4)
PostPosted: Tue Feb 26, 2019 2:51 pm 
Offline

Joined: Sat Feb 23, 2019 1:09 pm
Posts: 5
When running my OS in qemu, or just hardware, it runs fine, with no problems. However, when I run it in bochs, it prints nothing, and fails, with the error "00243442083p[IOAPIC] >>PANIC<< I/O apic write with len=2 (should be 4) at address 0x0000fec00020".

Image
(Text should be displayed, it does in qemu and hardware)

I stepped through in bochs to see where the error occurs:
Code:
<bochs:866>
Next at t=213053579
(0) [0x000000101278] 0008:0000000000101278 (unk. ctxt): cmp eax, edx              ; 39d0
<bochs:867>
Next at t=223053579
(0) [0x000000101270] 0008:0000000000101270 (unk. ctxt): mov word ptr ds:[eax], cx ; 668908
<bochs:868>
Next at t=233053579
(0) [0x000000101270] 0008:0000000000101270 (unk. ctxt): mov word ptr ds:[eax], cx ; 668908
<bochs:869>
Next at t=243053579
(0) [0x000000101278] 0008:0000000000101278 (unk. ctxt): cmp eax, edx              ; 39d0
<bochs:870>
00243442083p[IOAPIC] >>PANIC<< I/O apic write with len=2 (should be 4) at address 0x0000fec00020


It repeats those instructions loads of times, then errors. I'm not sure why, since I'm not even using the I/O APIC for interrupts (unless the APIC can be treated as the PIC until it is enabled). I believe the error is due to sending EOI to the PIC, because ever since I started handling interrupts, bochs stopped working. IRQ 0 is the only interrupt that has function, the others I just ignore.
This is how I send the EOI:
Code:
eoi:
    mov    al, 0x20
    out    0x20, al
    ret


The error also could be due to my ksleep function, as bochs panics whilst executing it (I think from the stepping above). I also made that around the same time bochs stopped working.

You can see any code on my git repository: https://github.com/chez4/burnsOS/tree/master/x86/src Files that are relevant: boot.asm kmain.c system.c


Top
 Profile  
 
 Post subject: Re: bochs I/O apic write with len=2 (should be 4)
PostPosted: Tue Feb 26, 2019 5:40 pm 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 1584
Hi,

I think the message is self explanatory. You're writing a word instead of a dword (IOAPIC registers are 32 bit wide). Just because it's MMIO, doesn't mean you can write to it at any offset with any granularity, you must write to the whole register at once.

If you use C (as I suspect from the disassembly), then you should use
Code:
*((uint32_t*)IOAPIC_regX) = X;
and *not*
Code:
*((uint16_t*)IOAPIC_regX) = X;

If you don't intentionally write to the IOAPIC as you say, then you probably have an out of bound indexing issue. Generate a symbol table text file from your code. If you're using elf, you can use
Code:
nm kernel.elf | grep -ve '^ ' | cut -d ' ' -f 1,3 >kernel.sym
(note there's a space in both strings). Otherwise it's just a simple text file, with hex addresses (without the "0x" prefix), a space, and a symbol name in each line. Example:
Code:
0000000000007C00 bootsector
0000000000100080 _start
0000000000100100 pic_eoi
0000000000100200 ksleep
...

Then load that file into bochs with
Code:
<bochs:0> ldsym global "kernel.sym"
After that bochs disassembler will tell you exactly in which function the IOAPIC write occurs (address 0000000000101278 looks like inside your kernel, or if not, then there's your problem: you're executing random garbage in memory).

Alternatively you could do
Code:
objdump -d kernel.elf | less
search for the address "1278:", and scroll up to see the function name.

Btw, IOAPIC is not the same as APIC, and no PIC cannot be used as APIC (nor as IOAPIC), but they can be used as PIC if emulation is enabled (which is usually the case for compatiblity).

Cheers,
bzt


Top
 Profile  
 
 Post subject: Re: bochs I/O apic write with len=2 (should be 4)
PostPosted: Wed Feb 27, 2019 2:03 pm 
Offline

Joined: Sat Feb 23, 2019 1:09 pm
Posts: 5
Thanks for the reply

After running objdump like you said, I could see that the 1278: address was in the vga_fill function, and by not calling it fixes the problem.
Here is the code for vga_fill:

Code:
void vga_fill(unsigned char colour)
{
    for (x = 0; x < 80; x++) {
        for (y = 0; y < 25; y++) {
            vga_text[y * 80 + x] = ' ' | ((colour | (colour << 4)) << 8);
        }
    }
}


I'm guessing i've done this bit wrong: vga_text[y * 80 + x], and y * 80 + x writes to some random address which so happens to be one of the IOAPIC registers.

I also noticed that none of the sleep functions I call seem to work in bochs.


Top
 Profile  
 
 Post subject: Re: bochs I/O apic write with len=2 (should be 4)
PostPosted: Wed Feb 27, 2019 10:13 pm 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 1604
With the given code, you can at most access 4000 bytes beyond the start of the vga_text array. Which means vga_text is the most likely culprit, probably not initialized. By my calculation, it must have been at least 0xfebff0c0 for you to get the error from the OP. Forgot to map the VGA memory?

_________________
Carpe diem!


Top
 Profile  
 
 Post subject: Re: bochs I/O apic write with len=2 (should be 4)
PostPosted: Thu Feb 28, 2019 6:20 am 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 1584
chez4 wrote:
After running objdump like you said, I could see that the 1278: address was in the vga_fill function, and by not calling it fixes the problem.
There you go, you can be sure now that the problem is in vga_fill. Good job!

I would recommend to generate the symbol map from your makefile anyway, it'll came very handy later. It's really helping when bochs debugger shows your function name. You can make bochs to automatically load it by adding this line to bochsrc
Code:
debug_symbols: file=kernel.sym, offset=0

chez4 wrote:
I also noticed that none of the sleep functions I call seem to work in bochs.
Bochs can be configured to "drop" clock cycles (so to speak) for performance reasons. I use
Code:
clock: sync=realtime, time0=local, rtc_sync=1
in the bochrc file which works for me (well, PIT is still not accurate, but close).

Cheers,
bzt


Top
 Profile  
 
 Post subject: Re: bochs I/O apic write with len=2 (should be 4)
PostPosted: Thu Feb 28, 2019 3:26 pm 
Offline

Joined: Sat Feb 23, 2019 1:09 pm
Posts: 5
bzt wrote:
Bochs can be configured to "drop" clock cycles (so to speak) for performance reasons. I use
Code:
clock: sync=realtime, time0=local, rtc_sync=1
in the bochrc file which works for me (well, PIT is still not accurate, but close).


Thanks, this fixed the sleep function :D , although sleeping is a bit weird and laggy, probably due to the PIT still not being accurate like you said.
It also for some reason fixed the vga_fill function. Not sure why.


Top
 Profile  
 
 Post subject: Re: bochs I/O apic write with len=2 (should be 4)
PostPosted: Fri Mar 01, 2019 2:44 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5137
chez4 wrote:
It also for some reason fixed the vga_fill function. Not sure why.

Sounds like it's something dependent on the speed of the emulated hardware. The first thing that comes to mind is IRQ handlers - they can change the CPU state when they run, and they'll have different timing depending on your emulator's configuration.

In fact...

Code:
global isr32
isr32:
    inc    dword [pit_clock]
    call   eoi
    iret

This ISR for handling IRQ0 doesn't save any registers. Will that call to "eoi" change any of them?

Code:
global eoi
eoi:
    mov    al, 0x20
    out    0x20, al
    ret

Oops!


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: SemrushBot [Bot] and 288 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group