forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Operations performed by _start()

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
Fanjita



Joined: 28 Sep 2005
Posts: 217

PostPosted: Fri Oct 07, 2005 10:50 am    Post subject: Operations performed by _start() Reply with quote

Can anyone tell me (or point me at the code that shows) what operations are performed by the _start() function generated by the toolchain?

In attempting to debug the v2.0 FW beta EBOOT loader for EBOOTs that currently don't work, it's looking like the problem lies with the entry code being generated by the toolchain.

So, I'm trying to work out whether there are any problematic operations (e.g. kernel-mode calls) going on in that code, that might be causing a crash during initialisation.

I've looked around the SVN source trying to find the relevant source code, and I'm working on getting a decent disassembly of the object code, but so far without any luck. A high-level overview of what that code is doing would be really helpful.

Thanks in advance.
Back to top
View user's profile Send private message
ooPo
Site Admin


Joined: 17 Jan 2004
Posts: 2032
Location: Canada

PostPosted: Fri Oct 07, 2005 11:47 am    Post subject: Reply with quote

You can usually find _start in the crt0 file.

Code:
/**
 * Startup thread
 *
 * Creates the main program thread based on variables defined by the program.
 *
 * @param args - Size (in bytes) of arguments passed to the program by the kernel.
 * @param argp - Pointer to arguments passed by the kernel.
 */
int _start(SceSize args, void *argp)
{
        void (*_main_func)(SceSize args, void *argp) = _main;
        void (*_init_func)(void) = _init;

        if ((&module_info != NULL) && (module_info.modattribute & 0x1000)) {
                /* If we're running in kernel mode, the addresses of our _main() thread
                   and _init() function must also reside in kernel mode. */
                _main_func = (void *) ((u32) _main_func | 0x80000000);
                _init_func = (void *) ((u32) _init_func | 0x80000000);
        }

        /* Call _init() here, because an app may have code that needs to run in
           kernel mode, but want their main() thread to run in user mode.  If they
           define "constructors" they can do any kernel mode initialization here
           before their app is switched. */
        _init_func();

        if (&sce_newlib_nocreate_thread_in_start != NULL) {
                /* The program does not want main() to be run in a seperate thread. */
                _main_func(args, argp);
                return 1;
        }

        int priority = DEFAULT_THREAD_PRIORITY;
        unsigned int attribute = DEFAULT_THREAD_ATTRIBUTE;
        unsigned int stackSize = DEFAULT_THREAD_STACK_KB_SIZE * 1024;

        if (&sce_newlib_priority != NULL) {
                priority = sce_newlib_priority;
        }
        if (&sce_newlib_attribute != NULL) {
                attribute = sce_newlib_attribute;
        }
        if (&sce_newlib_stack_kb_size != NULL) {
                stackSize = sce_newlib_stack_kb_size * 1024;
        }

        /* Does the _main() thread belong to the User, VSH, or USB/WLAN APIs? */
        if (attribute & (PSP_THREAD_ATTR_USER | PSP_THREAD_ATTR_USBWLAN | PSP_THREAD_ATTR_VSH)) {
                /* Remove the kernel mode addressing from the pointer to _main(). */
                _main_func = (void *) ((u32) _main_func & 0x7fffffff);
        }

        SceUID thid;
        thid = sceKernelCreateThread("user_main", (void *) _main_func, priority, stackSize, attribute, 0);
        sceKernelStartThread(thid, args, argp);

        return 0;
}

http://svn.pspdev.org/filedetails.php?repname=psp&path=%2Ftrunk%2Fpspsdk%2Fsdk%2Fstartup%2Fcrt0.c&rev=0&sc=0
Back to top
View user's profile Send private message Visit poster's website
Shazz



Joined: 31 Aug 2004
Posts: 244
Location: Somewhere over the rainbow

PostPosted: Fri Oct 07, 2005 6:52 pm    Post subject: Reply with quote

And or I missed something or the args parsing is not done..

I'm wrong ?
_________________
- TiTAN Art Division -
http://www.titandemo.org
Back to top
View user's profile Send private message Visit poster's website
Fanjita



Joined: 28 Sep 2005
Posts: 217

PostPosted: Fri Oct 07, 2005 7:13 pm    Post subject: Reply with quote

Excellent, thanks.

It does look like there's a fair bit there worth investigating.
Back to top
View user's profile Send private message
Fanjita



Joined: 28 Sep 2005
Posts: 217

PostPosted: Sun Oct 09, 2005 12:17 pm    Post subject: Reply with quote

Well, some good news...

It does indeed seem (from examining disassembly etc) that the problem loading most existing homebrew into v2.0 is due to the way the main thread is created by this start() function.

By messing around with the module and thread options compiled into some of the SDK samples, I've been able to compile all the samples I've tested so far such that they now load under v2.0 (using a slightly-modified loader).

It's a little early to announce any details, and ideally I want to find some way to patch existing binaries without requiring recompilation.

But things are looking very promising in terms of being able to run just about any existing user-mode homebrew (which does seem to be the majority) on v2.0.
Back to top
View user's profile Send private message
mrbrown



Joined: 17 Jan 2004
Posts: 1536

PostPosted: Sun Oct 09, 2005 4:29 pm    Post subject: Reply with quote

Fanjita wrote:
It does indeed seem (from examining disassembly etc) that the problem loading most existing homebrew into v2.0 is due to the way the main thread is created by this start() function.

What problem? The PSPSDK crt0 works fine for apps that run in usermode only, it doesn't require kernel mode (that's why it's all hacked up).

If you can't launch a pure user-only PSPSDK application then the problem is in the loader. Your loader should be able to check the kernel bit in the module info and reject those from working anyway.
Back to top
View user's profile Send private message
Fanjita



Joined: 28 Sep 2005
Posts: 217

PostPosted: Mon Oct 10, 2005 1:27 am    Post subject: Reply with quote

"The problem" is just that most homebrew crashes immediately after starting under the current loader - even for most user-mode apps.

If I mess around with the startup behaviour being asked for by the app, then I can overcome that (for kernel mode applications).

(I suspect it is something about the loader's behaviour, which is why I'm hopeful I can fix it within the loader, without requiring recompilation of any apps).
Back to top
View user's profile Send private message
mrbrown



Joined: 17 Jan 2004
Posts: 1536

PostPosted: Mon Oct 10, 2005 2:41 am    Post subject: Reply with quote

I still don't follow. You say "I can overcome that (for kernel mode applications)", so does that mean that the PSPSDK samples that don't require kernel mode work fine? If not, what is it you think is happening in _start() that causes them to break?

_start() assumes that the runtime environment is the same used on 1.0 and 1.5. Your loader has to somehow get the exploit environment into that environment if user-only apps will work as is.

Besides patching, I don't see how you can get out of recompiling any app that starts up in kernel mode by default, since the address range code in _start() will kill you right away...
Back to top
View user's profile Send private message
Fanjita



Joined: 28 Sep 2005
Posts: 217

PostPosted: Mon Oct 10, 2005 2:58 am    Post subject: Reply with quote

Sorry, that was a typo, it should have said "I can work around that for user-mode applications".

In terms of environment, it seems that the exploit environment isn't so different to the 1.0/1.5 runtime environment - the only issue does seem to be the lack of kernel mode access.

To be clear - I very much doubt I can get kernel-mode apps working (although it may be possible to hack some apps around with patching, I suppose, but certainly not the general case). But I'm very confident that user-mode apps can work fine.

Anyway - back to the coding...
Back to top
View user's profile Send private message
Fanjita



Joined: 28 Sep 2005
Posts: 217

PostPosted: Mon Oct 10, 2005 10:02 pm    Post subject: Reply with quote

Heh, it turned out that the main problem was that the loader wasn't supplying anything in $ra when it called into the app - so anything that created a "user_main" thread, and then exited (the majority of PSPSDK apps, I'd guess, since it's the default) were ending up heading off into the unknown during initialisation.

I've now released my version of the loader at my website, it seems to work pretty well with most user-mode homebrew that I've tried.
Back to top
View user's profile Send private message
mrbrown



Joined: 17 Jan 2004
Posts: 1536

PostPosted: Tue Oct 11, 2005 1:25 am    Post subject: Reply with quote

Fanjita, you are the man :).
Back to top
View user's profile Send private message
Fanjita



Joined: 28 Sep 2005
Posts: 217

PostPosted: Tue Oct 11, 2005 2:08 am    Post subject: Reply with quote

:)

I'm still trying to decide whether or not I'm proud of my hack to get a valid address into $RA... Unless I'm missing something, there's no convenient "JRAL" opcode, so to jump to a dynamic address (with "JR") I need to fake up my own $RA value beforehand.

Eventually I did it with:

(EBOOT entry point is in $A2):

JAL straightback
NOP
ADDIU $RA, $RA, 0x18
JR $A2
NOP
NOP
NOP
NOP
NOP
SYSCALL nnnn (sleep thread)

straightback:
JR $RA
NOP
Back to top
View user's profile Send private message
Saotome



Joined: 03 Apr 2004
Posts: 182

PostPosted: Tue Oct 11, 2005 2:59 am    Post subject: Reply with quote

wow, nice to see you actually came this far, and did not give up like me :)

regarding your code - looks ok, but how about this:
(I know, I'm an asm masochist, and have to find every "wasted" cycle ;))
Code:

JAL somelabel
NOP
somelabel:
JR $A2
ADDIU $RA, $RA, 8
SYSCALL nnnn (sleep thread)

and what about the NOPs in you code? were there problems without them?

EDIT:
wait a sec JALR didn't work? or did you try "JRAL" (like you have written) instead "JALR $RA, $A2"
_________________
infj
Back to top
View user's profile Send private message
Fanjita



Joined: 28 Sep 2005
Posts: 217

PostPosted: Tue Oct 11, 2005 6:32 pm    Post subject: Reply with quote

Ah! JALR - didn't try that, and JRAL was rejected by gas.

I couldn't find mention of JALR anywhere, so I assumed that it must not exist - excellent, I'll just update the code to use the far-more-sensible JALR.

Thanks!

P.S. The NOPs were just because I was being lazy and couldn't be bothered working out the right offset exactly :)
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
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 vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group