Welcome! Log In Create A New Profile

Advanced

IOS_ReloadIOS doesn't work in binary from MEM2

Posted by sorg 
IOS_ReloadIOS doesn't work in binary from MEM2
August 18, 2010 10:58PM
Just found this problem.
If binary compiled to MEM2 address (>0x90000000) then IOS_ReloadIOS hangs.
After further investigation, it sticks in ios.c at this place:
	while ((read32(0x80003140) >> 16) == 0)
	{
		udelay(1000);
	}

Can anybody tell me how to fix it?
Re: IOS_ReloadIOS doesn't work in binary from MEM2
August 19, 2010 10:29AM
Beware that IOS is using the upper 12-16MB of MEM2, if your code is running from there it obviously can cause issues with running IOS.

Also, DOL loaders (like the HBC) uses MEM2 as data holding space so it's generally not a good idea to make the DOL you are loading use this area as well, when it will be copied in memory, it could overwrites the loader data. I guess that more details on the way you are loading the DOL that is crashing and the exact address it is running from might help.

The fact it hangs at this stage means that IOS did not write the expected value at this address, this is cleared by libogc in IOS_reload function and used for synchronization, to wait for IOS to be completely reloaded . According to memory map , this location should hold the current IOS version.



Edited 1 time(s). Last edit at 08/19/2010 10:29AM by ekeeke.
Re: IOS_ReloadIOS doesn't work in binary from MEM2
August 23, 2010 11:32AM
I made some experiments - problem caused only if code is in MEM2. Both, stack and heap can be in MEM2 without problem as long as code is in MEM1. My app's binary starts from 0x92800000 and occupies around 400kb. Stack and heap occupies space 0x90002000 - 0x92800000.
This is loader for homebrew, channels and DVD. The reason why MEM2 has been choosen, is because no any applications (from Nintendo or Homebrew) loads to MEM2. So, my loader can load any app with insurance it won't be overwritten. It doesn't do much things, just loads binary from starage and optionaly loads requested IOS.

Quote

I guess that more details on the way you are loading the DOL that is crashing and the exact address it is running from might help.
IOS_RealoadIOS doesn't cause crash. It sticks in libogc's ios.c code mentioned above in while() loop. Yep, i understand what 0x80003140 address means. But it doesn't explain why IOS doesn't finish loading.
If i load homebrew without call IOS_ReloadIOS, then loaded app works fine and can call IOS_ReloadIOS without issues. It means, my loader doesn't overwrite anything. I saw in some places of libogc: it sets stack for some threads using static allocation inside data section of binary which looks terrible for me. Probably libogc does some similar nasty things while IOS reloading...



Edited 1 time(s). Last edit at 08/23/2010 11:33AM by sorg.
Re: IOS_ReloadIOS doesn't work in binary from MEM2
August 24, 2010 11:49AM
IOS kernels have a small loader at the start that is made to be executed from 0x11000000, which copies the new kernel into starlet and the IOS region of memory. So it's probably trashing your MEM2 program/data when it stages the kernel there.
In other words, IOS reloads shouldn't be done if you care about the contents of MEM2.
Re: IOS_ReloadIOS doesn't work in binary from MEM2
August 24, 2010 12:55PM
Quote

I saw in some places of libogc: it sets stack for some threads using static allocation inside data section of binary which looks terrible for me. Probably libogc does some similar nasty things while IOS reloading...

hum, where did you see libogc doing that ? Data section is copied from the .dol by the loader and left untouched by libogc, otherwise NO application would work correctly.
The thread implementation is a generic one, it should not work different for "some threads". Afaik, stack is dynamically allocated/unallocated in the heap section, which starts above the .bss section (starting at ArenaLow, then libogc is reserving 1MB for his workspace).
Re: IOS_ReloadIOS doesn't work in binary from MEM2
August 24, 2010 05:07PM
ekeeke,
you can check thread in libwiikeyboard (keyboard.c).

tueidj,
i did one experiment: filled MEM2 with some value, executed IOS_ReloadIOS() and dumped MEM2. Nothing has been changed these besides around 256 bytes at the end of MEM2 space, just before IOS protected area.
So, nothing has been trashed.
Re: IOS_ReloadIOS doesn't work in binary from MEM2
August 24, 2010 05:10PM
by the way, under SNEEK, IOS_ReloadIOS is working from MEM2 binary.
Re: IOS_ReloadIOS doesn't work in binary from MEM2
August 24, 2010 06:55PM
Quote
sorg
ekeeke,
you can check thread in libwiikeyboard (keyboard.c)..

Yes, unless I don't understand the code, this seems to be an error

static u8 *_kbd_stack[KBD_THREAD_STACKSIZE] ATTRIBUTE_ALIGN(8);
static u8 *_kbd_buf_stack[KBD_THREAD_STACKSIZE] ATTRIBUTE_ALIGN(8);

This should not be declared as an array of pointer but an array of bytes, right ? This shouldn't lead to any problem though , the reserved memory is just 4x bigger than expected.

That's said, if it is what you are referring to, it's perfectly normal for an application that create tasks to declare stack as a static buffer. It's up to the application to make sure the stack is big enough. Also, since it's uninitialized, it's not included in the binary data but is placed in the .bss area in main memory.



Edited 1 time(s). Last edit at 08/24/2010 07:33PM by ekeeke.
Re: IOS_ReloadIOS doesn't work in binary from MEM2
August 24, 2010 10:20PM
Initialized or not, it's static and resides inside executable address space instead of heap or stack area.
I don't think it's normal and good style.
That's why i'm thinking that some similar "tricks" can cause hang using IOS_ReloadIOS from MEM2
Re: IOS_ReloadIOS doesn't work in binary from MEM2
August 25, 2010 02:56AM
Quote
sorg
tueidj,
i did one experiment: filled MEM2 with some value, executed IOS_ReloadIOS() and dumped MEM2. Nothing has been changed these besides around 256 bytes at the end of MEM2 space, just before IOS protected area.
So, nothing has been trashed.
So how do you propose IOS loads a new kernel? Does it somehow magically load new code over the top of itself while it is running?

Here's some excerpts from the Load_IOS syscall:

LOAD:FFFF136E                 LDR     R0, =0x10100000
LOAD:FFFF1370                 LDR     R1, =0x1FFFFFFF
LOAD:FFFF1372                 LDR     R3, =(protect_MEM2+1)
LOAD:FFFF1374                 BLX     R3
First it enables MEM2 protection on this range (I quoted the wrong address before, it's 0x10100000 instead of 0x11000000). Then it gets a handle to the new IOS kernel file (using IOS_Open), checks the size and a few other things, then this:
LOAD:FFFF13B2                 LDR     R3, =(os_device_read+1)
LOAD:FFFF13B4                 ADDS    R0, R5, #0
LOAD:FFFF13B6                 LDR     R1, =0x10100000
LOAD:FFFF13B8                 BLX     R3
Which places the new kernel blob at 0x10100000 in memory. Then it does some more setup stuff and jumps to it, which runs the loader stub that pushes the new IOS into starlet's SRAM. Anything at 0x10100000 in MEM2 is going to be overwritten. If you say you verified that it doesn't, you must have done something wrong.
Re: IOS_ReloadIOS doesn't work in binary from MEM2
August 25, 2010 09:45AM
Quote
sorg
Initialized or not, it's static and resides inside executable address space instead of heap or stack area.
I don't think it's normal and good style.
That's why I'm thinking that some similar "tricks" can cause hang using IOS_ReloadIOS from MEM2

Sorry to insist but could you explain me how this is a trick and what could be bad with that ?
AFAIK, libogc uses LWP implementation, the application creating a task has to allocate a fixed size stack so I don't think it matters if it is statically allocated... also, the task is actually managed by the application (even in the case of libkeyboard), not really libogc kernel...please someone correct me if I'm wrong,

The subject is interesting though, it deals with the way how libogc manages the memory which is not quite clear to me:
for example, I'm not sure where the "stack area" you are referring to is located, I only know libogc reserves 1MB for its own workspace at the start of heap then anything above can be used for dynamic memory allocation (application heap), up to Arena2High. Some drivers dealing with IOS seems to declare a private heap at the top of allowed MEM2 area (decrementing Arena2High). The rest is pretty much obscure to me.



Edited 1 time(s). Last edit at 08/25/2010 09:47AM by ekeeke.
Sorry, only registered users may post in this forum.

Click here to login