Well, this old Pentium 4 computer does seems to have an IOAPIC, as seen in the dmesg log: [ 0.015459] Freeing SMP alternatives: 24k freed [ 0.015506] ACPI: Core revision 20120320 [ 0.019020] ftrace: allocating 22322 entries in 44 pages [ 0.031186] Enabling APIC mode: Flat. Using 1 I/O APICs [ 0.031562] ..TIMER: vector=0x30 apic1=0 pin1=0 apic2=-1 pin2=-1 [ 0.031997] ..MP-BIOS bug: 8254 timer not connected to IO-APIC [ 0.031997] ...trying to set up timer (IRQ0) through the 8259A ... [ 0.031997] ..... (found apic 0 pin 0) ... [ 0.042985] ....... works. [ 0.042988] CPU0: Intel(R) Pentium(R) 4 CPU 2.26GHz stepping 04 [ 0.043996] Performance Events: Netburst events, Netburst P4/Xeon PMU driver. [ 0.043996] ... version: 0 [ 0.043996] ... bit width: 40 [ 0.043996] ... generic registers: 18 [ 0.043996] ... value mask: 000000ffffffffff [ 0.043996] ... max period: 0000007fffffffff [ 0.043996] ... fixed-purpose events: 0 [ 0.043996] ... event mask: 000000000003ffff [ 0.044304] NMI watchdog: enabled on all CPUs, permanently consumes one hw-PMU counter. [ 0.044410] Brought up 1 CPUs [ 0.044415] Total of 1 processors activated (4517.85 BogoMIPS). [ 0.045127] devtmpfs: initialized
Although "[ 0.031997] ..MP-BIOS bug: 8254 timer not connected to IO-APIC" suggest some problem with it.
Up to now, by adding some Console::print in bootstrap.cpp (Nova): extern "C" NORETURN void bootstrap() { static mword barrier;
Cpu::init(); Console::print("Cpu::init done in bootstrap"); // Create idle EC Ec::current = new Ec (Pd::current = &Pd::kern, 0, Ec::idle, Cpu::id); Space_obj::insert_root (Sc::current = new Sc (&Pd::kern, Cpu::id, Ec::current));
// Barrier: wait for all ECs to arrive here for (Atomic::add (barrier, 1UL); barrier != Cpu::online; pause()) ; Console::print("about to Msr::write"); Msr::write<uint64>(Msr::IA32_TSC, 0); Console::print("will create root task"); // Create root task if (Cpu::bsp) { Hip::add_check(); Ec *root_ec = new Ec (&Pd::root, NUM_EXC + 1, &Pd::root, Ec::root_invoke, Cpu::id, 0, USER_ADDR - 2 * PAGE_SIZE, 0); Sc *root_sc = new Sc (&Pd::root, NUM_EXC + 2, root_ec, Cpu::id, Sc::default_prio, Sc::default_quantum); root_sc->remote_enqueue(); } Console::print("Scheduling"); Sc::schedule(); }
I do see my "Scheduling" when booting. But I don't understand which code is executed next.
Ok... I understand it is not a interesting computer to use Nova on.
On Mon, 21 Jan 2013 13:46:53 -0500 Paul Dufresne (PD) wrote:
PD> Well, this old Pentium 4 computer does seems to have an IOAPIC [...] PD> Although "[ 0.031997] ..MP-BIOS bug: 8254 timer not connected to PD> IO-APIC" suggest some problem with it.
Interesting. Let's see...
PD> // Create root task PD> if (Cpu::bsp) { PD> Hip::add_check(); PD> Ec *root_ec = new Ec (&Pd::root, NUM_EXC + 1, &Pd::root, Ec::root_invoke, Cpu::id, 0, USER_ADDR - 2 * PAGE_SIZE, 0); PD> Sc *root_sc = new Sc (&Pd::root, NUM_EXC + 2, root_ec, Cpu::id, Sc::default_prio, Sc::default_quantum); PD> root_sc->remote_enqueue(); PD> } PD> Console::print("Scheduling"); PD> Sc::schedule(); PD> } PD> PD> I do see my "Scheduling" when booting. But I don't understand which PD> code is executed next.
Sc::schedule() invokes the scheduler and selects the next thread to run. In this case, execution should continue in Ec::root_invoke(), and if you hit ret_user_sysexit() at the bottom of that function, then you're entering user mode, indicating the hypervisor has successfully booted.
PD> Ok... I understand it is not a interesting computer to use Nova on.
It could be that after returning to user mode, we're never getting an interrupt that takes us back into the hypervisor. You can verify that, by booting just the hypervisor without any other modules. You should see one message saying the bootstrap EC died ("No ELF").
Furthermore, if you enabled "spinner" on the hypervisor command line, you should see blue spinner activity once every second. If the blue spinner doesn't increment, you have an interrupt problem.
Cheers, Udo
Ok... will try to see what I can make with these new info.
I was reading a bit about IO-APIC and Local APIC. Frankly, it does goes above my head (not fully understanding, not so much interested).
At this site: http://osdev.berlios.de/pic.html I am reading something that looks like could be related to my computer:
"Oh did I say one more thing? There's more. Some motherboards have a thingy that you must write to redirect the interrupts from the 8259's to the IOAPIC. This is done by writing 0x70 to port 0x22 and 0x01 to port 0x23. Also, you may want to disable the 8259's completely. I do this by writing 0xFF to ports 0x21 and 0xA1. So I disable the 8259's first, then program the IOAPIC, then write the ICMR (0x22,0x23) ports to accept IOAPIC interrupts."
Maybe this motherboard need the: outb 0x70, 0x22 outb 0x01, 0x23 ?
Don't know if Linux is aware of that and try it.
On Mon, 21 Jan 2013 14:54:23 -0500 Paul Dufresne (PD) wrote:
PD> "Oh did I say one more thing? There's more. Some motherboards have a PD> thingy that you must write to redirect the interrupts from the 8259's PD> to the IOAPIC. This is done by writing 0x70 to port 0x22 and 0x01 to PD> port 0x23. Also, you may want to disable the 8259's completely. I do PD> this by writing 0xFF to ports 0x21 and 0xA1. So I disable the 8259's PD> first, then program the IOAPIC, then write the ICMR (0x22,0x23) ports PD> to accept IOAPIC interrupts."
I don't think that applies to your chipset at all.
Cheers, Udo
How do I change "timeout 0" of Grub? I found menu.lst in my build.nova32/var/run/hello/boot/grub but it seems to be generated and changing it seems to make no change.
Hi Paul,
please have a look at 'base-nova/run/env'. The 'menu.lst' file is generated by the 'build_boot_image' procedure each time when the run tool is executed (when issuing 'make run/...').
Cheers Norman
On 01/21/2013 10:13 PM, Paul Dufresne wrote:
How do I change "timeout 0" of Grub? I found menu.lst in my build.nova32/var/run/hello/boot/grub but it seems to be generated and changing it seems to make no change.
The result of testing with just the hypervisor seems the same on both of my computer: -I see the Killed EC: ... (No ELF) -spinner spin (actually at least on my Pentium 4, a cyan, a blue and a yellow text digit counting) down the screen
Oh, I think I *may* begin to understand a bit better what is going on... and to feel a bit dumb. ... and still confused.
Basically, I was expecting to see on the screen in my computer, what I was seeing in QEMU on my Linux.
So I was expecting to see things like: Hypervisor does not feature VMX Hypervisor does not feature SVM Hypervisor info page contains 13 memory descriptors: detected physical memory: 0x0000000000000000 - size: 0x9f400 use physical memory: 0x0000000000000000 - size: 0x9f000 detected physical memory: 0x0000000000100000 - size: 0x17efe000 use physical memory: 0x0000000000100000 - size: 0x17efe000 map multi-boot module: physical 0x018b6000 -> [0x00188000-0x00210230) - core map multi-boot module: physical 0x0193f000 -> [0x00213000-0x00213266) - config
on my screen when testing the iso file, but I now think this is what is sent to the serial line that is shown in the terminal window of Linux.
Also I tried to use "make run/hello" which use base/include/base/printf.h functions (PDBG) but I now think they send their output to serial line too.
When debuging Nova, I was adding some Nova's Console::print that seems to go to screen. So debugging was going fine.
I find a bit strange that Genode's printf does not map to Nova's Console::print however. I guess that it what I would have expected.
Now I am asking myself what function I should use in Genode, to send output to screen rather than serial line?
I would expect Genode to stop using -nographic with QEMU, and use the screen rather than the serial line... supposing that my hypothesis about what is going on is right.
Hi Paul,
On Tue, Jan 22, 2013 at 01:48:27AM -0500, Paul Dufresne wrote:
I would expect Genode to stop using -nographic with QEMU, and use the screen rather than the serial line... supposing that my hypothesis about what is going on is right.
Genode uses serial line for PDBG() and friends per default. Many of our demos, scenarios, or even test cases use the screen often switching the graphics card from VGA text into flat framebuffer modes. In this case, all debug messages would be lost for humans and also our run-script-based automatic testing. You may see PDBG(), which uses Genode's LOG session as an equivalent to Linux's syslog in the simplest case. The LOG session is implemented by core, which uses a simple builtin UART driver or kernel debugger facilities depending on the platform used.
On the other hand, the LOG session can also be implemented by servers and a parent (e.g., init) can route a child's request for LOG to that server. Example LOG providers are
* demo/src/server/nitlog opens a nitpicker window for LOG messages * os/src/server/terminal_log redirects LOG messages to a Terminal
Please refer to the following run scripts
* os/run/demo.run * gems/run/terminal_log.run * ports-foc/run/two_linux.run (only on Fiasco.OC)
Regards
Hi Paul,
the best way is to go as posted by Christian Helmuth some minutes ago.
If you for any case need debugging support during the early bootstrap phase (or you don't have a serial connector as on newer machines), for base-nova there is a patch [0] (last commit) which also prints all log messages to the screen as long as your setup is running in vga text mode.
Regards,
Alexander Boettcher.
[0] https://github.com/alex-ab/genode/commits/experimental_vga_console.
On 22.01.2013 07:48, Paul Dufresne wrote:
Oh, I think I *may* begin to understand a bit better what is going on... and to feel a bit dumb. ... and still confused.
Basically, I was expecting to see on the screen in my computer, what I was seeing in QEMU on my Linux.
So I was expecting to see things like: Hypervisor does not feature VMX Hypervisor does not feature SVM Hypervisor info page contains 13 memory descriptors: detected physical memory: 0x0000000000000000 - size: 0x9f400 use physical memory: 0x0000000000000000 - size: 0x9f000 detected physical memory: 0x0000000000100000 - size: 0x17efe000 use physical memory: 0x0000000000100000 - size: 0x17efe000 map multi-boot module: physical 0x018b6000 -> [0x00188000-0x00210230) - core map multi-boot module: physical 0x0193f000 -> [0x00213000-0x00213266) - config
on my screen when testing the iso file, but I now think this is what is sent to the serial line that is shown in the terminal window of Linux.
Also I tried to use "make run/hello" which use base/include/base/printf.h functions (PDBG) but I now think they send their output to serial line too.
When debuging Nova, I was adding some Nova's Console::print that seems to go to screen. So debugging was going fine.
I find a bit strange that Genode's printf does not map to Nova's Console::print however. I guess that it what I would have expected.
Now I am asking myself what function I should use in Genode, to send output to screen rather than serial line?
I would expect Genode to stop using -nographic with QEMU, and use the screen rather than the serial line... supposing that my hypothesis about what is going on is right.
Master Visual Studio, SharePoint, SQL, ASP.NET, C# 2012, HTML5, CSS, MVC, Windows 8 Apps, JavaScript and much more. Keep your skills current with LearnDevNow - 3,200 step-by-step video tutorials by Microsoft MVPs and experts. ON SALE this month only -- learn more at: http://p.sf.net/sfu/learnnow-d2d _______________________________________________ Genode-main mailing list Genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Ok, thanks for the answers! I finally did it: search and find my serial null-modem cable. Which was simply, after all, in one of the drawer of the desk where the computer was. ;-)
Good news 1) hello tutorial works fine
Good news 2) I understand much better why make run/demo do not work on this computer Short answer: [init -> pci_drv] PCI driver started I/O memory [0,1000) not available Local MMIO mapping failed! [init -> vesa_drv] C++ runtime: Genode::Parent::Service_denied [init -> vesa_drv] void* abort(): abort called
I guess vesa_drv refused the service to the client because it needed PCI to work.
As the long answer, I am attaching the log file to this message.
Hello Paul,
On Tue, Jan 22, 2013 at 11:44:12AM -0500, Paul Dufresne wrote:
Good news 2) I understand much better why make run/demo do not work on this computer Short answer: [init -> pci_drv] PCI driver started I/O memory [0,1000) not available Local MMIO mapping failed! [init -> vesa_drv] C++ runtime: Genode::Parent::Service_denied [init -> vesa_drv] void* abort(): abort called
I guess vesa_drv refused the service to the client because it needed PCI to work.
For me, it looks like your VESA BIOS tries to access physical page 0, which is not available. This fact is also logged in the following lines
:io_mem_alloc: Allocator 16165c dump: Block: [0009f000,00100000) size=00061000 avail=00061000 max_avail=00061000 Block: [00400000,01800000) size=01400000 avail=01400000 max_avail=01400000 Block: [018b6000,01e66000) size=005b0000 avail=005b0000 max_avail=005b0000 Block: [1fcf0000,1fd00000) size=00010000 avail=00010000 max_avail=e0181000 Block: [1fe80000,00001000) size=e0181000 avail=e0181000 max_avail=e0181000 => mem_size=3787071488 (3611 MB) / mem_avail=3787071488 (3611 MB)
The region [0,1000) is missing. I don't know why this happens as base-nova/src/core/platform.cc states in line 360
/* needed as I/O memory by the VESA driver */ _io_mem_alloc.add_range(0, 0x1000); _core_mem_alloc.phys_alloc()->remove_range(0, 0x1000);
Maybe Alexander can shed some light on this?
Greets
Well, the cause of my problem seems to be: static int map_code_area(void) { int err; Ram_dataspace_capability ds_cap; void *dummy; printf("map_code_area will map_io_mem\n"); /* map page0 */ if ((err = Framebuffer_drv::map_io_mem(0x0, PAGESIZE, false, &dummy))) { printf("map_io_mem error"); PERR("Could not map page zero"); return err; } printf("map_code_area succeede map_io_mem\n");
It looks like Framebuffer_drv::map_io_mem(0x0, PAGESIZE, false, &dummy) never return and cause: int main(): --- start init --- int main(): transferred 484 MB to init int main(): --- init created, waiting for exit condition --- [init] Could not open file "ld.lib.so" [init -> pci_drv] PCI driver started modified [init -> pci_drv] PCI begin by Paul [init -> vesa_drv] VESA begin main [init -> vesa_drv] VESA will init [init -> vesa_drv] VESA init beginning [init -> vesa_drv] x86emu::init will now call map_code_area [init -> vesa_drv] map_code_area will map_io_mem I/O memory [0,1000) not available Local MMIO mapping failed! [init -> launchpad] Could not open file "ld.lib.so" [init -> launchpad] Could not open file "config" [init -> timer] Timer::Timeout_scheduler::Timeout_scheduler(Platform_timer*, Ger [init -> vesa_drv] C++ runtime: Genode::Parent::Service_denied [init -> launchpad] Could not obtain config file [init -> vesa_drv] void* abort(): abort called [init -> pci_drv] PCI will announce myself [init -> pci_drv] PCI will sleep forever now [init -> ps2_drv] Using keyboard with scan code set 2.
Oops, I now see I forgot the \n at the end of printf("map_io_mem error"); making it not flushing output to serial. So I am not sure map_io_mem does not return.
Hi,
I think you're right with the source code triggering the error, but must slightly adjust your investigation...
On Tue, Jan 22, 2013 at 10:52:58PM -0500, Paul Dufresne wrote:
It looks like Framebuffer_drv::map_io_mem(0x0, PAGESIZE, false, &dummy) never return and cause:
It does return and it does it in an exceptional fashion ;-)
[...]
[init -> vesa_drv] map_code_area will map_io_mem I/O memory [0,1000) not available Local MMIO mapping failed! [init -> launchpad] Could not open file "ld.lib.so" [init -> launchpad] Could not open file "config" [init -> timer] Timer::Timeout_scheduler::Timeout_scheduler(Platform_timer*, Ger [init -> vesa_drv] C++ runtime: Genode::Parent::Service_denied [init -> launchpad] Could not obtain config file [init -> vesa_drv] void* abort(): abort called
Oops, we got an exception that was not caught. This aborts vesa_drv on a failing session request. In this case, the IO MEM session is denied by core's service, because the requested region is not available. Please have a look into base/include/parent/parent.h which declares Parent::session() and the Service_denied exception.
For further investigation, you may set 'bool verbose = true' in
base/src/core/io_mem_session_component.cc:25
This enables logging of all requests to the IO MEM service in core.
Greets
Hello Paul,
On 22.01.2013 23:59, Christian Helmuth wrote:
For me, it looks like your VESA BIOS tries to access physical page 0, which is not available. This fact is also logged in the following lines
:io_mem_alloc: Allocator 16165c dump: Block: [0009f000,00100000) size=00061000 avail=00061000 max_avail=00061000 Block: [00400000,01800000) size=01400000 avail=01400000 max_avail=01400000 Block: [018b6000,01e66000) size=005b0000 avail=005b0000 max_avail=005b0000 Block: [1fcf0000,1fd00000) size=00010000 avail=00010000 max_avail=e0181000 Block: [1fe80000,00001000) size=e0181000 avail=e0181000 max_avail=e0181000
This line looks suspicious. The start address is ok, but the end address isn't. It seems to have been wrapped. So, I would expect something like:
Block: [1fe80000,ffffffff) size=e0180000 avail=e0180000 max_avail=e0180000 Block: [00000000,00001000) size=1000 avail=1000 max_avail=1000
It looks like that the allocator merged the 2 blocks into one, just a guess ...
Mmh, please apply following patch and post the output in order to understand what lead to the problem.
=> mem_size=3787071488 (3611 MB) / mem_avail=3787071488 (3611 MB)
The region [0,1000) is missing. I don't know why this happens as base-nova/src/core/platform.cc states in line 360
/* needed as I/O memory by the VESA driver */ _io_mem_alloc.add_range(0, 0x1000); _core_mem_alloc.phys_alloc()->remove_range(0, 0x1000);
Maybe Alexander can shed some light on this?
With the patch we know hopefully more ...
Cheers,
Alexander Boettcher.
Hi! This 0-1000 address you are trying to give VESA... this is virtual memory? I was asking because when I did read that one of the goal about 2013.2 release was: * IOMMU support on NOVA I remember to have read that IOMMU is often found on motherboard having PCI express. This one is AGP I think. So it might well not have IOMMU.
Anyway I applied the patch and I am attaching it to this message.
Ah no, I think I can guess (all my understanding is rather fuzzy). This 0-1000 thing, is my old real mode interrupt table (256 entries, of 4 bytes each).
Well, I am surprised to see how this x86emu can be coded in user mode. But I find strange that so much assembler seems to need to be emulated, I was expecting that vm86 mode would make all that unnecessary.
Hello Paul,
thanks for your traces ! I could reproduce with your log the issue. Can you please give the following patch a try, whether it works for you too ?
On 23.01.2013 12:45, Paul Dufresne wrote:
This 0-1000 address you are trying to give VESA... this is virtual memory?
No, the driver is requesting the physical page at address zero.
I was asking because when I did read that one of the goal about 2013.2 release was:
- IOMMU support on NOVA
I remember to have read that IOMMU is often found on motherboard having PCI express. This one is AGP I think. So it might well not have IOMMU.
The issue has nothing to do with the IOMMU. Beside that, the IOMMU support of the NOVA kernel shipped with Genode is disabled and would have to be enabled explicitly to take any effect.
Cheers,
Alex.
Anyway I applied the patch and I am attaching it to this message.
Master Visual Studio, SharePoint, SQL, ASP.NET, C# 2012, HTML5, CSS, MVC, Windows 8 Apps, JavaScript and much more. Keep your skills current with LearnDevNow - 3,200 step-by-step video tutorials by Microsoft MVPs and experts. ON SALE this month only -- learn more at: http://p.sf.net/sfu/learnnow-d2d
Genode-main mailing list Genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
My current guess is that you don't use virtual 8086 mode but rather, emulate it in protected mode (as user code) mostly to call (euh run, much as an assembler interpreter) Vesa BIOS int 0x10 to set video mode and ask it where it has put the framebuffer.
avl.diff applied.
Much better, from there it should be easy to change video mode depth to an available one: [init -> vesa_drv] Found: VESA BIOS version 3.0 [init -> vesa_drv] OEM: Brookdale-G Graphics Chip Accelerated VGA BIOS [init -> vesa_drv] graphics mode 1024x768@...64... not supported [init -> vesa_drv] Supported mode list [init -> vesa_drv] 0x109 132x25@...167... [init -> vesa_drv] 0x10a 132x43@...167... [init -> vesa_drv] 0x10b 132x50@...167... [init -> vesa_drv] 0x10c 132x60@...167... [init -> vesa_drv] 0x101 640x480@...168... [init -> vesa_drv] 0x103 800x600@...168... [init -> vesa_drv] 0x105 1024x768@...168... [init -> vesa_drv] 0x111 640x480@...64... [init -> vesa_drv] Searching in default vesa modes [init -> vesa_drv] Could not set vesa mode 1024x768@...64... [init -> nitpicker] C++ runtime: Genode::Parent::Service_denied [init -> nitpicker] void* abort(): abort called
Thanks, that is quite fun to see a problem like this being fixed by exchanging emails! I guess you don't want the full log. But if you want it, just ask for it.
Ok, I added a config element for the vesa driver in my demo.run file: append_if [have_spec vesa] config { <start name="vesa_drv"> <config width="640" height="480" depth="16" buffered="no" /> <resource name="RAM" quantum="1M"/> <provides><service name="Framebuffer"/></provides> </start>} At first I did put it before the start element rather than inside, and so it took me a while to figure out what was wrong.
I am now happy to report that I can now read scout on my Pentium 4! Thanks everyone!
P.S. I should probably use 1024x768@...168... however.
Hello Paul
great to hear that you tamed your hardware to run Genode.
On Wed, Jan 23, 2013 at 12:00:54PM -0500, Paul Dufresne wrote:
P.S. I should probably use 1024x768@...168... however.
AFAIK nitpicker and the other GUI components only support graphics modes with RGB565 colors currently.
Greets
Hi Paul,
On 23.01.2013 16:55, Paul Dufresne wrote:
Thanks, that is quite fun to see a problem like this being fixed by exchanging emails!
thanks for reporting and testing. I opened a issue [0] at github and provided the fix there so that it can be picked up in the next days to the staging branch.
Cheers,
Alex.