even with -G0 ?M.Jackson wrote:man, this looks like a dead end. I have tried all the methods i can think of(including J.F.'s one though I knew it standed little chance to succeed) but no good result was yielded.
But I did find out more info about this. the BAD relocation entries are actually of the type of R_MIPS_GPREL32, instead of R_MIPS_32 for those normal entries. And according to the mips abi, the formula used for its reloc calculation should be:
A + S + GP0 – GP
in which:
A: Represents the addend used to compute the value of the relocatable
field.
S: Represents the value of the symbol whose index resides in the relocation entry, unless the the symbol is STB_LOCAL and is of type
STT_SECTION in which case S represents the original sh_addr minus
the final sh_addr.
GP0: Represents the gp value used to create the relocatable object.
GP: Represents the final gp value to be used for the relocatable, executable, or shared object file being produced.
it doesn't make much sense to me either, 'cos I just can't imagine what kind of formula can translate a value from 0xfffxxxxx to a reasonable address that looks like 0x891xxxxx.
One thing interests me, though, is that all the programs i wrote, either as simple as hello-world or more complex ones, do not contain relocation entries of the type of R_MIPS_GPREL32, making me wonder what kind of code could have generated the demand for such type of relocation. If I can understand the nature of this relocation type and the scenario in which it is used, maybe I can work around the problem by revising those code accountable for this type of relocation a little bit in busybox. And i think the best way to do this is to write a short program that can also result in this special type of reloc. I had tried ".gpword" which is said to be capable of leading to a GPREL32 entry, but turned out it was not supported by GAS. Could anyone give me an example demonstrating what kind of coding would produce this type of relocation?
A new port of uClinux on PSP (with accessibility to ms0)
no, not even -G0 would make any difference. And i also noticed that R_MIPS_GPREL32 entries can always be found in section .rodata (presumably the ReadOnly Data I guess). They also exist in .o files even before linking, which means it was gcc not the linker that creates those entries in the first place. And the values of those in .o files are already odd (like 0xfffxxxxx) though they will be converted into equally odd but different values in the final image.
Exactly what kind of code could have made gcc generate such type of relocation?
Exactly what kind of code could have made gcc generate such type of relocation?
From what I've learned working with other archs, GPREL are usually used for accessing global vars, and literal pools.
if you'll excuse my rusty mips and pseudo-asm, doing stuff GP relative allows you to turn a code seuqence such as:into:
This also applies to literals, which explains the relocations in read-only sections. Say you have a printf("foo") the string gets placed somewhere, and a pointer to the string ends up in the sdata section and gcc compiles a "ld r0, 0(gp)" into the .o which is how it gets the pointer to the string into the correct place before the call to printf. At link time the linker changes the 0 offset from gp to whereever the particular global or literal ended up once the gp-relatives from all .o's have been pooled together.
You say these relo's appear even with -G0 .. are you passing this to the compiler when generating the .o's ?
Whilst all very nice when it works, there are a couple of ways this can go wrong, and from my experience with another gnu-based toolchain the error messages from ld can be far from helpful.. if you're lucky that it barfs - else you might just get a mangled ELF.
One major way that I've managed to consistently break this is:
have in a .s file: and then in some other c file: The compiler assumes that since somevar is small, that it will be placed in the smalldata section so it emits a gp relative load. However, we actually defined it ourselves, and it really is in the .text section.
Depending on luck and the linker script 1 or 3 things will happen:
fixes might be re-ordering sdata section by tweaking linker scripts, or finding offending variables somehow and adding .section "sdata" before declaring them in asm files, so that the gcc's assumption about where they end up is correct.
so just some background infos on the kinds of struggles i've been having with GP-relative offsets, hopefully shedding some light to the issues you are facing :)
Cheers.
if you'll excuse my rusty mips and pseudo-asm, doing stuff GP relative allows you to turn a code seuqence such as:
Code: Select all
loadhigh r0, 0x0010 // set top 16 bits of address
load r0, 0x1230 // set lower 16 bits, we now have a pointer to the var
ld r0, 0(r0) // we can dereference it
Code: Select all
ld r0 0x122(gp) // linker knows our var is 0x122 bytes from gp base
You say these relo's appear even with -G0 .. are you passing this to the compiler when generating the .o's ?
Whilst all very nice when it works, there are a couple of ways this can go wrong, and from my experience with another gnu-based toolchain the error messages from ld can be far from helpful.. if you're lucky that it barfs - else you might just get a mangled ELF.
One major way that I've managed to consistently break this is:
have in a .s file:
Code: Select all
.global somevar
somevar:
.word 42
Code: Select all
extern int somevar;
int get_somehting(){
return somevar;
}
Depending on luck and the linker script 1 or 3 things will happen:
- * it is still reachable by an offset from gp base, so things will work,
* it is too far away and maybe linker will complain about trying to fit an offset of 423648673 bytes into 11 bits (or whatever), or
* if it is actually *before* the gp base, ld may well put (or try to) a negative offset in there which may explain the 0xffff you are seeing.
fixes might be re-ordering sdata section by tweaking linker scripts, or finding offending variables somehow and adding .section "sdata" before declaring them in asm files, so that the gcc's assumption about where they end up is correct.
so just some background infos on the kinds of struggles i've been having with GP-relative offsets, hopefully shedding some light to the issues you are facing :)
Cheers.
Damn, I need a decent signature!
Thanks cheriff! The info you shared was very insightful. On the other hand, I also made some progress today after plunging myself into the ocean of disassembly code for days. I actually discovered that the majority number of R_MIPS_GPREL32 entries was attributed to a gcc optimization for the "switch" statement. When the number of case branches exceeds certain level (say 6+), a particular optimization will kick in by introducing a "jump" table in the .rodata* section, which consists of an array of words measuring the negative distance between gp and the entrance of the target code (it is negative because .text always precedes .data). Therefore, these entries in the jump table require additional steps of calcuation to restore the correct address that the code desires (additional adjustments basing on the gp value at runtime), and the normal relocation procedure applied to R_MIPS_32 will just mess the address up and make the cpu go wild.
I have revised the code of the flat loader accordingly so that it now seems the kernel can get over those "switch" statements in busybox. But the bad news is busybox still crashes, at different location with a different problem I am gonna face...this is just agonizingly interesting. I just can't get my hands off it.
I have revised the code of the flat loader accordingly so that it now seems the kernel can get over those "switch" statements in busybox. But the bad news is busybox still crashes, at different location with a different problem I am gonna face...this is just agonizingly interesting. I just can't get my hands off it.
uClinux on PSP Slim
There is a previous post, not replied though.
Will this port run on psp slim which has not FW 1.5 (running for example 3.71M33-4)?
I have tried with eLoader but I still cannot run it...
Could someone please help?
Will this port run on psp slim which has not FW 1.5 (running for example 3.71M33-4)?
I have tried with eLoader but I still cannot run it...
Could someone please help?
-
- Posts: 6
- Joined: Fri Dec 28, 2007 11:35 pm
Re: uClinux on PSP Slim
Also I don't know what is problem, but I have tried with 3.71M33-4 and retrieve negotiation result.MythosGR wrote:There is a previous post, not replied though.
Will this port run on psp slim which has not FW 1.5 (running for example 3.71M33-4)?
I have tried with eLoader but I still cannot run it...
Could someone please help?
Re: uClinux on PSP Slim
I haven't had my PSP upgraded to 3.71 yet. but to my knowledge, there is a 1.5 kernel patch for 3.71 m33-x and I knew a few people who had successfully run this port on their 3.71 system after applying the patch. Have you tried that?MythosGR wrote:There is a previous post, not replied though.
Will this port run on psp slim which has not FW 1.5 (running for example 3.71M33-4)?
I have tried with eLoader but I still cannot run it...
Could someone please help?
-
- Posts: 6
- Joined: Fri Dec 28, 2007 11:35 pm
Re: uClinux on PSP Slim
Yes, i can tell you, what you need do. Enter into recovery menu (POWER+R), switch kernel to 1.50 in configuration menu. Also of course you need apply 1.5 kernel-addon patch.MythosGR wrote:There is a previous post, not replied though.
Will this port run on psp slim which has not FW 1.5 (running for example 3.71M33-4)?
I have tried with eLoader but I still cannot run it...
Could someone please help?
I tried and it worked. This great step to new future.
Kernel 2.6.22
In Kernel 2.6.22 support for a Marvell Libertas 8388 802.11b/g USB driver was added.
The PSP has a Marvell Libertas 88W8380. The 8380 seems very close in version number to 8388.
Does networking work?
The PSP has a Marvell Libertas 88W8380. The 8380 seems very close in version number to 8388.
Does networking work?
Re: Kernel 2.6.22
That sounds interesting! But if I can choose, I would rather have the usb work first :)shadash wrote:In Kernel 2.6.22 support for a Marvell Libertas 8388 802.11b/g USB driver was added.
The PSP has a Marvell Libertas 88W8380. The 8380 seems very close in version number to 8388.
Does networking work?
lainlives wrote:can you give the source for the bootloader because i wanna port that to 3.xx firmware, since slims cannot run the 1.0/1.5 kernel that it requires
Code: Select all
/*---------------------------------------------------------------------------*/
/* PSPBoot 0.2 Created by Jackson Mo */
/*---------------------------------------------------------------------------*/
#include <pspkernel.h>
#include <pspdebug.h>
#include <stdio.h>
#include <string.h>
#include "/usr/src/psp-zlib/zlib.h"
/*---------------------------------------------------------------------------*/
/* Module info */
/*---------------------------------------------------------------------------*/
/* Define the module info section, note the 0x1000 flag to enable start in
* kernel mode
*/
PSP_MODULE_INFO( "PSPBoot", 0x1000, 1, 1 );
/* Define the thread attribute as 0 so that the main thread does not get
* converted to user mode
*/
PSP_MAIN_THREAD_ATTR( 0 );
/*---------------------------------------------------------------------------*/
/* Macros */
/*---------------------------------------------------------------------------*/
#if 1
#define CONFIG_UART3
#endif
#define BOOL int
#define TRUE 1
#define FALSE 0
#define KERNEL_ENTRY 0x88000000
#define KERNEL_PARAM_OFFSET 0x00000008
#define KERNEL_MAX_SIZE ( 4 * 1024 * 1024 ) /* 4M */
#ifdef CONFIG_UART3
#define UART3_RXBUF ( *(volatile char *)0xbe500000 )
#define UART3_TXBUF ( *(volatile char *)0xbe500000 )
#define UART3_STATUS ( *(volatile unsigned int *)0xbe500018 )
#define UART3_DIV1 ( *(volatile unsigned int *)0xbe500024 )
#define UART3_DIV2 ( *(volatile unsigned int *)0xbe500028 )
#define UART3_CTRL ( *(volatile unsigned int *)0xbe50002c )
#define UART3_MASK_RXEMPTY ( (unsigned int)0x00000010 )
#define UART3_MASK_TXFULL ( (unsigned int)0x00000020 )
#define UART3_MASK_SETBAUD ( (unsigned int)0x00000060 )
#endif
#define BANNER "=====================================\n" \
" PSP Boot v0.2 Created by Jackson Mo\n" \
"=====================================\n\n"
#define BLUE 0x00ff0000
#define GREEN 0x0000ff00
#define RED 0x000000ff
#define CONFIG_FILE "pspboot.conf"
#define CONFIG_MAX_PARAM 256
#define CONFIG_PARAM_CMD "cmdline"
#define CONFIG_PARAM_KERNEL "kernel"
#define CONFIG_PARAM_BAUD "baud"
#define printf pspDebugScreenPrintf
#define sleep(t) sceKernelDelayThread( (t) )
#define exit() transferControl( NULL, 0 )
#define END_OF_LINE(p) ( *(p) == '\r' || *(p) == '\n' || *(p) == 0 )
/*---------------------------------------------------------------------------*/
/* Type definitions */
/*---------------------------------------------------------------------------*/
typedef void ( *KernelEntryFunc )(int zero_, int arch_, void * params_);
/*---------------------------------------------------------------------------*/
/* Static Data */
/*---------------------------------------------------------------------------*/
static char s_paramCmd[ CONFIG_MAX_PARAM ];
static char s_paramKernel[ CONFIG_MAX_PARAM ];
#ifdef CONFIG_UART3
static int s_paramBaud = 1;
#endif
/*---------------------------------------------------------------------------*/
/* Prototypes */
/*---------------------------------------------------------------------------*/
BOOL loadConfig();
BOOL parseParam(const char * name_, const char * value_);
BOOL loadKernel(void ** buf_, int * size_);
void transferControl(void * buf_, int size_);
void disableIrq();
void memCopy(void * dest_, const void * sour_, int size_);
void pspClearIcache(void);
void pspClearDcache(void);
#ifdef CONFIG_UART3
BOOL uart3_setbaud(int baud_);
int uart3_write(const char * buf_, int size_);
int uart3_puts(const char * str_);
#endif
/*---------------------------------------------------------------------------*/
/* Implementations */
/*---------------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
void * kernelBuf;
int kernelSize;
pspDebugScreenInit();
/* Print the banner */
pspDebugScreenSetTextColor( RED );
printf( BANNER );
pspDebugScreenSetTextColor( GREEN );
/* Load the config file first */
if ( !loadConfig() )
{
sleep( 3000 );
exit();
}
/* Load the kernel image */
if ( !loadKernel( &kernelBuf, &kernelSize ) )
{
sleep( 3000 );
exit();
}
transferControl( kernelBuf, kernelSize ); /* no return from here */
return 0;
}
/*---------------------------------------------------------------------------*/
BOOL loadConfig()
{
FILE * fconf;
const int bufLen = 1024;
char buf[ bufLen ];
char * p;
char * end;
char * paramName;
char * paramValue;
int line;
printf( "Loading config file\n" );
fconf = fopen( CONFIG_FILE, "r" );
if ( fconf == NULL )
{
printf( "Failed to open config file %s\n", CONFIG_FILE );
return FALSE;
}
for ( line = 1; fgets( buf, bufLen, fconf ) != NULL; line++ )
{
buf[ bufLen - 1 ] = 0;
p = buf;
end = buf + bufLen;
/* skip all leading white space of tab */
while ( ( *p == ' ' || *p == '\t' ) && *p != 0 && p < end )
{
p++;
}
/* skip empty line and comment */
if ( END_OF_LINE( p ) || p >= end || *p == '#' )
{
continue;
}
paramName = p; /* get the parameter name */
while ( *p != '=' && !END_OF_LINE( p ) && p < end ) p++;
if ( END_OF_LINE( p ) || p >= end )
{
printf( "Syntax error at line %d\n", line );
fclose( fconf );
return FALSE;
}
*p++ = 0; /* set the end of the param name */
paramValue = p; /* get the parameter value */
/* set the end of the param value */
while ( !END_OF_LINE( p ) && p < end ) p++;
*p = 0;
/* Parse the parameter */
if ( !parseParam( paramName, paramValue ) )
{
fclose( fconf );
return FALSE;
}
line++;
}
fclose( fconf );
return TRUE;
}
/*---------------------------------------------------------------------------*/
BOOL parseParam(const char * name_, const char * value_)
{
/* cmdline=... */
if ( stricmp( name_, CONFIG_PARAM_CMD ) == 0 )
{
strncpy( s_paramCmd, value_, CONFIG_MAX_PARAM );
s_paramCmd[ CONFIG_MAX_PARAM - 1 ] = 0;
printf( " %s: %s\n", CONFIG_PARAM_CMD, s_paramCmd );
}
/* kernel=... */
else if ( stricmp( name_, CONFIG_PARAM_KERNEL ) == 0 )
{
strncpy( s_paramKernel, value_, CONFIG_MAX_PARAM );
s_paramKernel[ CONFIG_MAX_PARAM - 1 ] = 0;
printf( " %s: %s\n", CONFIG_PARAM_KERNEL, s_paramKernel );
}
#ifdef CONFIG_UART3
/* baud=9600|115200 */
else if ( stricmp( name_, CONFIG_PARAM_BAUD ) == 0 )
{
sscanf( value_, "%d", &s_paramBaud );
printf( " %s: %d\n", CONFIG_PARAM_BAUD, s_paramBaud );
}
#endif
else
{
printf( " Unsupported param %s\n", name_ );
}
return TRUE;
}
/*---------------------------------------------------------------------------*/
BOOL loadKernel(void ** buf_, int * size_)
{
gzFile zf;
void * buf;
int size;
printf( "Decompressing linux kernel..." );
if ( buf_ == NULL || size_ == NULL )
{
printf( "Internal error\n" );
return FALSE;
}
*buf_ = NULL;
*size_ = 0;
if ( *s_paramKernel == 0 )
{
printf( "Invalid kernel file\n" );
return FALSE;
}
zf = gzopen( s_paramKernel, "r" );
if ( zf == NULL )
{
printf( "Failed to open file %s\n", s_paramKernel );
return FALSE;
}
buf = malloc( KERNEL_MAX_SIZE );
if ( buf == NULL )
{
printf( "Failed to allocate buffer\n" );
gzclose( zf );
return FALSE;
}
size = gzread( zf, buf, KERNEL_MAX_SIZE );
if ( size < 0 )
{
printf( "Failed to read file\n" );
free( buf );
gzclose( zf );
return FALSE;
}
gzclose( zf );
printf( "%d bytes loaded\n", size );
*buf_ = buf;
*size_ = size;
return TRUE;
}
/*---------------------------------------------------------------------------*/
void transferControl(void * buf_, int size_)
{
if ( buf_ != NULL && size_ > 0 )
{
KernelEntryFunc kernelEntry = (KernelEntryFunc)( KERNEL_ENTRY );
void * kernelParam = NULL;
printf( "Transfering control to 0x%08x...\n", kernelEntry );
/* disable IRQ */
disableIrq();
/* prepare kernel image */
memCopy( (void *)( KERNEL_ENTRY ), buf_, size_ );
/* prepare boot command line */
if ( *s_paramCmd != 0 )
{
kernelParam = (void *)( KERNEL_ENTRY + KERNEL_PARAM_OFFSET );
memCopy( kernelParam, s_paramCmd, CONFIG_MAX_PARAM );
}
#ifdef CONFIG_UART3
if ( s_paramBaud > 1 )
{
uart3_setbaud( s_paramBaud );
uart3_puts( "Booting Linux kernel...\n" );
}
#endif
/* flush all caches */
pspClearIcache();
pspClearDcache();
kernelEntry( 0, 0, kernelParam );
/* never returns */
}
sceKernelExitGame();
}
/*---------------------------------------------------------------------------*/
void disableIrq()
{
__asm__ __volatile__ (
"mfc0 $8, $12\n"
"li $9, 0xfffe\n"
"and $8, $8, $9\n"
"mtc0 $8, $12\n"
);
}
/*---------------------------------------------------------------------------*/
void memCopy(void * dest_, const void * sour_, int size_)
{
const char * from = (const char *)sour_;
char * to = (char *)dest_;
while ( size_-- > 0 )
{
*to++ = *from++;
}
}
/*---------------------------------------------------------------------------*/
void pspClearIcache(void)
{
asm("\
.word 0x40088000;\
.word 0x24091000;\
.word 0x7D081240;\
.word 0x01094804;\
.word 0x4080E000;\
.word 0x4080E800;\
.word 0x00004021;\
.word 0xBD010000;\
.word 0xBD030000;\
.word 0x25080040;\
.word 0x1509FFFC;\
.word 0x00000000;\
"::);
}
/*---------------------------------------------------------------------------*/
void pspClearDcache(void)
{
asm("\
.word 0x40088000;\
.word 0x24090800;\
.word 0x7D081180;\
.word 0x01094804;\
.word 0x00004021;\
.word 0xBD140000;\
.word 0xBD140000;\
.word 0x25080040;\
.word 0x1509FFFC;\
.word 0x00000000;\
.word 0x0000000F;\
.word 0x00000000;\
"::);
}
/*---------------------------------------------------------------------------*/
#ifdef CONFIG_UART3
BOOL uart3_setbaud(int baud_)
{
int div1, div2;
div1 = 96000000 / baud_;
div2 = div1 & 0x3F;
div1 >>= 6;
UART3_DIV1 = div1;
UART3_DIV2 = div2;
UART3_CTRL = UART3_MASK_SETBAUD;
return TRUE;
}
/*---------------------------------------------------------------------------*/
int uart3_write(const char * buf_, int size_)
{
int bytesWritten = 0;
while ( bytesWritten < size_ )
{
if ( *buf_ == '\n' )
{
while ( UART3_STATUS & UART3_MASK_TXFULL );
UART3_TXBUF = '\n';
while ( UART3_STATUS & UART3_MASK_TXFULL );
UART3_TXBUF = '\r';
}
else
{
while ( UART3_STATUS & UART3_MASK_TXFULL );
UART3_TXBUF = *buf_;
}
++buf_;
++bytesWritten;
}
return bytesWritten;
}
/*---------------------------------------------------------------------------*/
int uart3_puts(const char * str_)
{
int len = 0;
while ( str_[ len ] != 0 ) ++len;
return uart3_write( str_, len );
}
#endif
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
Last edited by M.Jackson on Wed Jan 02, 2008 6:36 pm, edited 1 time in total.
Here comes a question again. If I wanna have an additional compiling option applied when building libraries that come with gcc (like libstdc++.a), where should I add that option to? Can I modify gcc's "configure" script or some Makefile to concatenate that option to CFLAGS or CFLAGS_FOR_TARGET or CFLAGS_FOR_BUILD? Which one will actually take effect when building those libraries (not building the cross-compiler itself)? This whole scripting and automation thing is just like designed to make your head ache like hell...
thank youM.Jackson wrote:/*---------------------------------------------------------------------------*/lainlives wrote:can you give the source for the bootloader because i wanna port that to 3.xx firmware, since slims cannot run the 1.0/1.5 kernel that it requires
/* PSPBoot 0.2 Created by Jackson Mo */
/*---------------------------------------------------------------------------*/
...
Thanks for Jackson Mo.
First of all, i appreciate Jackson's works. I succeeded compiling kernel version 2.6.22-uc0( not uc1 ), and saw booting meesage on my PSP. I worked document for my works, and post it for any other lazy man. :)
http://riverful.tistory.com/entry/Docum ... on-psp-v01
But, here is the problem. Actuallay, I'm korean master course student, and will be engineer soon in IT company. So, my eng is poor. :) Anyway... This document is korean, not eng. In a few days, i will translate this doc to eng. wait a few days.
my next works is following:
i) one compiler unification. ( not psp-, not mipsel-linux- )
ii) being alive wlan.
iii) using usb gadget.
Thx to Jackson mo. :)
http://riverful.tistory.com/entry/Docum ... on-psp-v01
But, here is the problem. Actuallay, I'm korean master course student, and will be engineer soon in IT company. So, my eng is poor. :) Anyway... This document is korean, not eng. In a few days, i will translate this doc to eng. wait a few days.
my next works is following:
i) one compiler unification. ( not psp-, not mipsel-linux- )
ii) being alive wlan.
iii) using usb gadget.
Thx to Jackson mo. :)
Re: uClinux on PSP Slim
Are you sure you are running FW 3.71M33-4 on slim? I have tried all this and still doesn't work. Furthermore, 1.5 patch cannot be installed on slim.Yes, i can tell you, what you need do. Enter into recovery menu (POWER+R), switch kernel to 1.50 in configuration menu. Also of course you need apply 1.5 kernel-addon patch.
I tried and it worked. This great step to new future.
Anyway, lainlives efforts seem more promising... Any news???
has anyone tried to get miniGUI working under uClinux yet?
http://www.minigui.org
http://www.minigui.com/index.php?id=min ... ce-version
it would be the next big leap, getting a GUI onto this linux platform
http://www.minigui.org
http://www.minigui.com/index.php?id=min ... ce-version
it would be the next big leap, getting a GUI onto this linux platform
-
- Posts: 6
- Joined: Fri Dec 28, 2007 11:35 pm
Re: uClinux on PSP Slim
Oh, i sorry, it is my mistake. You are right! This instruction don't apply to slim PSP. We have one way: port loader to 3.71 kernel.MythosGR wrote:Are you sure you are running FW 3.71M33-4 on slim? I have tried all this and still doesn't work. Furthermore, 1.5 patch cannot be installed on slim.Yes, i can tell you, what you need do. Enter into recovery menu (POWER+R), switch kernel to 1.50 in configuration menu. Also of course you need apply 1.5 kernel-addon patch.
I tried and it worked. This great step to new future.
Anyway, lainlives efforts seem more promising... Any news???
But i don't know what we are need to change in source.
Re: uClinux on PSP Slim
MythosGR wrote:Are you sure you are running FW 3.71M33-4 on slim? I have tried all this and still doesn't work. Furthermore, 1.5 patch cannot be installed on slim.Yes, i can tell you, what you need do. Enter into recovery menu (POWER+R), switch kernel to 1.50 in configuration menu. Also of course you need apply 1.5 kernel-addon patch.
I tried and it worked. This great step to new future.
Anyway, lainlives efforts seem more promising... Any news???
Well, lately i have not been at home, but i did look/modify the source, a little, which should work, i dont have a compiler on my current machine, im not at home for a few weeks
but here someone should beable to compile it.
Code: Select all
/*---------------------------------------------------------------------------*/
/* PSPBoot 0.2 Created by Jackson Mo */
/*---------------------------------------------------------------------------*/
BUILD_PRX = 1
PSP_FW_VERSION = 371
#include <pspkernel.h>
#include <pspdebug.h>
#include <stdio.h>
#include <string.h>
#include "/usr/src/psp-zlib/zlib.h"
/*---------------------------------------------------------------------------*/
/* Module info */
/*---------------------------------------------------------------------------*/
/* Define the module info section, note the 0x1000 flag to enable start in
* kernel mode
*/
PSP_MODULE_INFO( "PSPBoot", 0x1000, 1, 1 );
PSP_HEAP_SIZE_KB(20480);
/* Define the thread attribute as 0 so that the main thread does not get
* converted to user mode
*/
PSP_MAIN_THREAD_ATTR( 0 );
/*---------------------------------------------------------------------------*/
/* Macros */
/*---------------------------------------------------------------------------*/
#if 1
#define CONFIG_UART3
#endif
#define BOOL int
#define TRUE 1
#define FALSE 0
#define KERNEL_ENTRY 0x88000000
#define KERNEL_PARAM_OFFSET 0x00000008
#define KERNEL_MAX_SIZE ( 4 * 1024 * 1024 ) /* 4M */
#ifdef CONFIG_UART3
#define UART3_RXBUF ( *(volatile char *)0xbe500000 )
#define UART3_TXBUF ( *(volatile char *)0xbe500000 )
#define UART3_STATUS ( *(volatile unsigned int *)0xbe500018 )
#define UART3_DIV1 ( *(volatile unsigned int *)0xbe500024 )
#define UART3_DIV2 ( *(volatile unsigned int *)0xbe500028 )
#define UART3_CTRL ( *(volatile unsigned int *)0xbe50002c )
#define UART3_MASK_RXEMPTY ( (unsigned int)0x00000010 )
#define UART3_MASK_TXFULL ( (unsigned int)0x00000020 )
#define UART3_MASK_SETBAUD ( (unsigned int)0x00000060 )
#endif
#define BANNER "=====================================\n" \
" PSP Boot v0.2 3.xx Port by lainlives\n" \
"=====================================\n\n"
#define BLUE 0x00ff0000
#define GREEN 0x0000ff00
#define RED 0x000000ff
#define CONFIG_FILE "pspboot.conf"
#define CONFIG_MAX_PARAM 256
#define CONFIG_PARAM_CMD "cmdline"
#define CONFIG_PARAM_KERNEL "kernel"
#define CONFIG_PARAM_BAUD "baud"
#define printf pspDebugScreenPrintf
#define sleep(t) sceKernelDelayThread( (t) )
#define exit() transferControl( NULL, 0 )
#define END_OF_LINE(p) ( *(p) == '\r' || *(p) == '\n' || *(p) == 0 )
/*---------------------------------------------------------------------------*/
/* Type definitions */
/*---------------------------------------------------------------------------*/
typedef void ( *KernelEntryFunc )(int zero_, int arch_, void * params_);
/*---------------------------------------------------------------------------*/
/* Static Data */
/*---------------------------------------------------------------------------*/
static char s_paramCmd[ CONFIG_MAX_PARAM ];
static char s_paramKernel[ CONFIG_MAX_PARAM ];
#ifdef CONFIG_UART3
static int s_paramBaud = 1;
#endif
/*---------------------------------------------------------------------------*/
/* Prototypes */
/*---------------------------------------------------------------------------*/
BOOL loadConfig();
BOOL parseParam(const char * name_, const char * value_);
BOOL loadKernel(void ** buf_, int * size_);
void transferControl(void * buf_, int size_);
void disableIrq();
void memCopy(void * dest_, const void * sour_, int size_);
void pspClearIcache(void);
void pspClearDcache(void);
#ifdef CONFIG_UART3
BOOL uart3_setbaud(int baud_);
int uart3_write(const char * buf_, int size_);
int uart3_puts(const char * str_);
#endif
/*---------------------------------------------------------------------------*/
/* Implementations */
/*---------------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
void * kernelBuf;
int kernelSize;
pspDebugScreenInit();
/* Print the banner */
pspDebugScreenSetTextColor( RED );
printf( BANNER );
pspDebugScreenSetTextColor( GREEN );
/* Load the config file first */
if ( !loadConfig() )
{
sleep( 3000 );
exit();
}
/* Load the kernel image */
if ( !loadKernel( &kernelBuf, &kernelSize ) )
{
sleep( 3000 );
exit();
}
transferControl( kernelBuf, kernelSize ); /* no return from here */
return 0;
}
/*---------------------------------------------------------------------------*/
BOOL loadConfig()
{
FILE * fconf;
const int bufLen = 1024;
char buf[ bufLen ];
char * p;
char * end;
char * paramName;
char * paramValue;
int line;
printf( "Loading config file\n" );
fconf = fopen( CONFIG_FILE, "r" );
if ( fconf == NULL )
{
printf( "Failed to open config file %s\n", CONFIG_FILE );
return FALSE;
}
for ( line = 1; fgets( buf, bufLen, fconf ) != NULL; line++ )
{
buf[ bufLen - 1 ] = 0;
p = buf;
end = buf + bufLen;
/* skip all leading white space of tab */
while ( ( *p == ' ' || *p == '\t' ) && *p != 0 && p < end )
{
p++;
}
/* skip empty line and comment */
if ( END_OF_LINE( p ) || p >= end || *p == '#' )
{
continue;
}
paramName = p; /* get the parameter name */
while ( *p != '=' && !END_OF_LINE( p ) && p < end ) p++;
if ( END_OF_LINE( p ) || p >= end )
{
printf( "Syntax error at line %d\n", line );
fclose( fconf );
return FALSE;
}
*p++ = 0; /* set the end of the param name */
paramValue = p; /* get the parameter value */
/* set the end of the param value */
while ( !END_OF_LINE( p ) && p < end ) p++;
*p = 0;
/* Parse the parameter */
if ( !parseParam( paramName, paramValue ) )
{
fclose( fconf );
return FALSE;
}
line++;
}
fclose( fconf );
return TRUE;
}
/*---------------------------------------------------------------------------*/
BOOL parseParam(const char * name_, const char * value_)
{
/* cmdline=... */
if ( stricmp( name_, CONFIG_PARAM_CMD ) == 0 )
{
strncpy( s_paramCmd, value_, CONFIG_MAX_PARAM );
s_paramCmd[ CONFIG_MAX_PARAM - 1 ] = 0;
printf( " %s: %s\n", CONFIG_PARAM_CMD, s_paramCmd );
}
/* kernel=... */
else if ( stricmp( name_, CONFIG_PARAM_KERNEL ) == 0 )
{
strncpy( s_paramKernel, value_, CONFIG_MAX_PARAM );
s_paramKernel[ CONFIG_MAX_PARAM - 1 ] = 0;
printf( " %s: %s\n", CONFIG_PARAM_KERNEL, s_paramKernel );
}
#ifdef CONFIG_UART3
/* baud=9600|115200 */
else if ( stricmp( name_, CONFIG_PARAM_BAUD ) == 0 )
{
sscanf( value_, "%d", &s_paramBaud );
printf( " %s: %d\n", CONFIG_PARAM_BAUD, s_paramBaud );
}
#endif
else
{
printf( " Unsupported param %s\n", name_ );
}
return TRUE;
}
/*---------------------------------------------------------------------------*/
BOOL loadKernel(void ** buf_, int * size_)
{
gzFile zf;
void * buf;
int size;
printf( "Decompressing linux kernel..." );
if ( buf_ == NULL || size_ == NULL )
{
printf( "Internal error\n" );
return FALSE;
}
*buf_ = NULL;
*size_ = 0;
if ( *s_paramKernel == 0 )
{
printf( "Invalid kernel file\n" );
return FALSE;
}
zf = gzopen( s_paramKernel, "r" );
if ( zf == NULL )
{
printf( "Failed to open file %s\n", s_paramKernel );
return FALSE;
}
buf = malloc( KERNEL_MAX_SIZE );
if ( buf == NULL )
{
printf( "Failed to allocate buffer\n" );
gzclose( zf );
return FALSE;
}
size = gzread( zf, buf, KERNEL_MAX_SIZE );
if ( size < 0 )
{
printf( "Failed to read file\n" );
free( buf );
gzclose( zf );
return FALSE;
}
gzclose( zf );
printf( "%d bytes loaded\n", size );
*buf_ = buf;
*size_ = size;
return TRUE;
}
/*---------------------------------------------------------------------------*/
void transferControl(void * buf_, int size_)
{
if ( buf_ != NULL && size_ > 0 )
{
KernelEntryFunc kernelEntry = (KernelEntryFunc)( KERNEL_ENTRY );
void * kernelParam = NULL;
printf( "Transfering control to 0x%08x...\n", kernelEntry );
/* disable IRQ */
disableIrq();
/* prepare kernel image */
memCopy( (void *)( KERNEL_ENTRY ), buf_, size_ );
/* prepare boot command line */
if ( *s_paramCmd != 0 )
{
kernelParam = (void *)( KERNEL_ENTRY + KERNEL_PARAM_OFFSET );
memCopy( kernelParam, s_paramCmd, CONFIG_MAX_PARAM );
}
#ifdef CONFIG_UART3
if ( s_paramBaud > 1 )
{
uart3_setbaud( s_paramBaud );
uart3_puts( "Booting Linux kernel...\n" );
}
#endif
/* flush all caches */
pspClearIcache();
pspClearDcache();
kernelEntry( 0, 0, kernelParam );
/* never returns */
}
sceKernelExitGame();
}
/*---------------------------------------------------------------------------*/
void disableIrq()
{
__asm__ __volatile__ (
"mfc0 $8, $12\n"
"li $9, 0xfffe\n"
"and $8, $8, $9\n"
"mtc0 $8, $12\n"
);
}
/*---------------------------------------------------------------------------*/
void memCopy(void * dest_, const void * sour_, int size_)
{
const char * from = (const char *)sour_;
char * to = (char *)dest_;
while ( size_-- > 0 )
{
*to++ = *from++;
}
}
/*---------------------------------------------------------------------------*/
void pspClearIcache(void)
{
asm("\
.word 0x40088000;\
.word 0x24091000;\
.word 0x7D081240;\
.word 0x01094804;\
.word 0x4080E000;\
.word 0x4080E800;\
.word 0x00004021;\
.word 0xBD010000;\
.word 0xBD030000;\
.word 0x25080040;\
.word 0x1509FFFC;\
.word 0x00000000;\
"::);
}
/*---------------------------------------------------------------------------*/
void pspClearDcache(void)
{
asm("\
.word 0x40088000;\
.word 0x24090800;\
.word 0x7D081180;\
.word 0x01094804;\
.word 0x00004021;\
.word 0xBD140000;\
.word 0xBD140000;\
.word 0x25080040;\
.word 0x1509FFFC;\
.word 0x00000000;\
.word 0x0000000F;\
.word 0x00000000;\
"::);
}
/*---------------------------------------------------------------------------*/
#ifdef CONFIG_UART3
BOOL uart3_setbaud(int baud_)
{
int div1, div2;
div1 = 96000000 / baud_;
div2 = div1 & 0x3F;
div1 >>= 6;
UART3_DIV1 = div1;
UART3_DIV2 = div2;
UART3_CTRL = UART3_MASK_SETBAUD;
return TRUE;
}
/*---------------------------------------------------------------------------*/
int uart3_write(const char * buf_, int size_)
{
int bytesWritten = 0;
while ( bytesWritten < size_ )
{
if ( *buf_ == '\n' )
{
while ( UART3_STATUS & UART3_MASK_TXFULL );
UART3_TXBUF = '\n';
while ( UART3_STATUS & UART3_MASK_TXFULL );
UART3_TXBUF = '\r';
}
else
{
while ( UART3_STATUS & UART3_MASK_TXFULL );
UART3_TXBUF = *buf_;
}
++buf_;
++bytesWritten;
}
return bytesWritten;
}
/*---------------------------------------------------------------------------*/
int uart3_puts(const char * str_)
{
int len = 0;
while ( str_[ len ] != 0 ) ++len;
return uart3_write( str_, len );
}
#endif
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
Last edited by lainlives on Thu Jan 03, 2008 12:15 pm, edited 1 time in total.
Aha, after days of troubleshooting, the unified toolchain (gcc 4.2.1+uclibc 0.9.29) is now ready! Both the kernel and apps (both in C and C++) can now neatly be built via one toolchain, which will definitely ease lives for those who wanted to develop on this project. I will put it on my website in the coming few days after making a few more final touches to it.
Good news! That'll make it much easier on those wanting to roll it themselves. :)M.Jackson wrote:Aha, after days of troubleshooting, the unified toolchain (gcc 4.2.1+uclibc 0.9.29) is now ready! Both the kernel and apps (both in C and C++) can now neatly be built via one toolchain, which will definitely ease lives for those who wanted to develop on this project. I will put it on my website in the coming few days after making a few more final touches to it.
help needed
hi guys i have a psp slim running 3.71-m33
and i love to have linux on it
i was trying to get it somehow but couldn't this is what i have done
i downloaded the source from the site and ported the pspboot to kernel3 .........
i then downloaded the precompiled package available in the jacson's site
and and copied the vmlinux.bin in pspboot directory
when i run the app it starts ............
shows that its booting
--------------
decompressing linux --- 0 bytes loading
-----------------
then it returns to XMB i dont now why its not loading the vmlinux.bin file
and i love to have linux on it
i was trying to get it somehow but couldn't this is what i have done
i downloaded the source from the site and ported the pspboot to kernel3 .........
i then downloaded the precompiled package available in the jacson's site
and and copied the vmlinux.bin in pspboot directory
when i run the app it starts ............
shows that its booting
--------------
decompressing linux --- 0 bytes loading
-----------------
then it returns to XMB i dont now why its not loading the vmlinux.bin file
Re: help needed
Did you use my original bootloader or the one that modified by others? If it is the latter, I am afraid you might need to do some debugging first, and that's part of the fun, isn't it? :)vijay wrote:hi guys i have a psp slim running 3.71-m33
and i love to have linux on it
i was trying to get it somehow but couldn't this is what i have done
i downloaded the source from the site and ported the pspboot to kernel3 .........
i then downloaded the precompiled package available in the jacson's site
and and copied the vmlinux.bin in pspboot directory
when i run the app it starts ............
shows that its booting
--------------
decompressing linux --- 0 bytes loading
-----------------
then it returns to XMB i dont now why its not loading the vmlinux.bin file
ok, I took a quick look at the diff between my version of the bootloader and the one midified by lainlives, finding that they really do not differ much except a few lines added probably just to satisfy compilation for slim psp homebrews. Actually I expected more might need to be done in order to get the bootloader work on slim, but off course I could be wrong. The fundamental reason why the original version needs to run under the 1.5 core is because it needs to be in the kernel mode (against the user mode) to gain privilege for manipulating many system elements (like wiping off the firmware from RAM, presetting some of the registers, locking interrupt, flushing CPU caches, etc...), and the 1.5 core offers a pretty simple way of doing so by just specifying an attribute at the beginning of the program. And I am not sure whether this trick still works in 3.71 'cos there is no guy around happen to have a slim for me to run tests on it. If it does not, we may have to figure out a more sophisticated approach to smuggle our code into the kernel mode. Writing a prx could be an option. Again I don't know this for sure, but as some of the drivers are also implemented as prx modules, it may have proven its ability to run in the kernel mode. Am I getting this right or just that I had thought too much?
hi jackson ...............
its my mistake i didnt know that it has to be in kernel mode for it to run
i just saw this forum
http://forums.ps2dev.org/viewtopic.php? ... 96f9268c1e
and followed the instructions ...............
one more thing , is it true that in fw above 2 homebrew kernel mode is disabled , and u can run only in user mode????????
i found this while googling
its my mistake i didnt know that it has to be in kernel mode for it to run
i just saw this forum
http://forums.ps2dev.org/viewtopic.php? ... 96f9268c1e
and followed the instructions ...............
one more thing , is it true that in fw above 2 homebrew kernel mode is disabled , and u can run only in user mode????????
i found this while googling
ok i tried to run the muclinux precompiled binary using eloader which can run a few 1.5 homebrews
the application started and then crashed
here is wht i got
-----------------------------------------------------------
Exception - Coprocessor unusable
EPC - 08900338
Cause - 0000002C
Status - 20008613
BadVAddr - 08025934
zr 00000000 at 08920000 v0 09FA1B24 v1 00008613
a0 00000000 a1 44027F70 a2 00000000 a3 0892618C
t0 00000008 t1 44027F54 t2 00000000 t3 44027F54
t4 00000006 t5 00000000 t6 00000000 t7 00008600
s0 089431B0 s1 00192073 s2 00000001 s3 09FFEEE0
s4 0000001F s5 00000013 s6 DEADBEEF s7 DEADBEEF
t8 0000001C t9 88300000 k0 09FFEF00 k1 00000000
gp 0892ED80 sp 09FFEE10 fp 09FFEEA0 ra 0890054C
-----------------------------------------------------------------------
the application started and then crashed
here is wht i got
-----------------------------------------------------------
Exception - Coprocessor unusable
EPC - 08900338
Cause - 0000002C
Status - 20008613
BadVAddr - 08025934
zr 00000000 at 08920000 v0 09FA1B24 v1 00008613
a0 00000000 a1 44027F70 a2 00000000 a3 0892618C
t0 00000008 t1 44027F54 t2 00000000 t3 44027F54
t4 00000006 t5 00000000 t6 00000000 t7 00008600
s0 089431B0 s1 00192073 s2 00000001 s3 09FFEEE0
s4 0000001F s5 00000013 s6 DEADBEEF s7 DEADBEEF
t8 0000001C t9 88300000 k0 09FFEF00 k1 00000000
gp 0892ED80 sp 09FFEE10 fp 09FFEEA0 ra 0890054C
-----------------------------------------------------------------------