Ps2 Homebrew Development Question. Launch arguments

Discussion in 'Sony Programming and Development' started by Based_Skid, Jan 20, 2018.

  1. Based_Skid

    Based_Skid Newly Registered

    Joined:
    Oct 20, 2017
    Messages:
    4
    Likes Received:
    0
    I noticed that some Apps like PS2PSXe can accept a launch argument Example:
    ps2psxe.elf -cdimage=

    Im working on a homebrew application and want to be able to create a second application that accepts some arguments such as the main executable of a game (and its arguments) and when this application starts up running some type of file operation on the memorycard for example, and then pass an argument to the second application when its loaded

    For example This Code Snippet Launches the PS2LOGO that is displayed when launching a disc however the code is passing an argument to ps2logo that contains an elf that accepts it own arguments in this case a games main executable (socom combined assault) and i am also passing another set of arguments to its executable that cause it to load directly into LAN mode using the save profile in slot 0.

    Code:
    char *argvs[1];
                argvs[0] = "cdrom0:\SCUS_975.45;1";
                argvs[1] = "--mission";
                argvs[2] = "ui_lan";
                argvs[3] = "--profile";
                argvs[4] = "0";
                argvs[5] = NULL;
    
                LoadExecPS2("rom0:PS2LOGO", 5, argvs);
    
    
    In my Case im not trying to Load PS2LOGO im trying to boot up my own application that accepts arguments like this runs some code that i have written, for example add some files to the memorycard the issue is Im not very skilled in C and so i dont know the terminology of things very well or where to begin on writing code that will allow my homebrew app to recognize the arguments thrown at it when it is being launched.

    Essentially
    In my First App I would want to Write some code like this that specifies the arguments that need to be passed to the second program.
    Example
    Code:
    char *argvs[1];
                argvs[0] = "cdrom0:\SCUS_975.45;1";
                argvs[1] = "--mission";
                argvs[2] = "ui_lan";
                argvs[3] = "--profile";
                argvs[4] = "0";
                argvs[5] = NULL;
    
                LoadExecPS2("mc0:/folder/program2.elf", 5, argvs);
    
    
    the Second program would then run and then it would take the arguments passed to it when it is booted and run what its programmed to do and then launch the program specified in the above sample code with its arguments (scus_975.45) the problem is i dont know how to write code that would allow my "program2.elf" to accept these launch arguments in the first place.

    So in program one I would include the second Sample Code Snippet that launches my program2.elf, program2 then accepts the launch arguments, runs its code and then executes socom CA main executable with the arguments i supplied for it in program one.

    So basically I want program to be able to accept a set of launch arguments like the socom ca main executable

    Im sorry if this sounds repetitive or erroneous but i dont know else how to describe my issues.

    Would anyone know how i could make my program be capable of accepting a launch argument?

    Thanks in Advance
    -Based_Skid
     
  2. HI_Ricky

    HI_Ricky Intrepid Member

    Joined:
    Jun 7, 2007
    Messages:
    650
    Likes Received:
    187
    use demo disc title to select ok ?
     
  3. sp193

    sp193 Site Soldier

    Joined:
    Mar 28, 2012
    Messages:
    2,217
    Likes Received:
    1,052
    The definition of the main function in C is something like this:
    Code:
    int main(int argc, char *argv[])
    {
      ...
      return the result;
    }
    
    The method signature (the type and number of arguments, and the return value) is standard. This means that argc and argv will always exist.
    argc contains the number of arguments, while argv is an array of strings. Each argument you pass becomes a string, which is stored in argv.

    Even if you do not pass any arguments to the program, the first argument (argv[0]) will always contain a path to the executable. The arguments that you specify will begin as the 2nd argument (argv[1]).

    For example, given the following:
    Code:
        char *argvs[3];
        argvs[0] = "Red";
        argvs[1] = "Blue";
        argvs[2] = "Green";
    
        LoadExecPS2("host:myapp.elf", 3, argvs);
    
    Accessing "Blue" can be done as such, from myapp.elf:
    Code:
        int main(int argc, char *argv[])
        {
            printf("%s", argv[3]);
            return 0;
        }
    
    There are some mistakes in the code that you provided:

    If you have 6 arguments, then this must be at least 6 in capacity. Otherwise, you will cause a buffer overflow, which results in undefined behaviour.

    As the backslash (\) is used to escape characters in C, you must put double-backslashes (\\) to cause GCC to treat it as a single backslash.
    Finally, once you have wrapped your mind around this concept, you might want to consider adding error-handling code. i.e. check argc and act accordingly if the incorrect number of arguments was supplied (can happen if the user just runs your ELF directly).
     
    pool7 likes this.
  4. Based_Skid

    Based_Skid Newly Registered

    Joined:
    Oct 20, 2017
    Messages:
    4
    Likes Received:
    0
    Thank you for the reply!

    I have a few more questions. is there some special code needed to launch ELFs? because when trying to load anything other then a ps2 game disc the console will hang.

    Also If it Helps Im Using a Prebuilt version of the ps2sdk.(ps2dev not the sony one)

    Its quite a bit of work to set one up and i have followed 2 different guides on here for building it and it fails every time for me.

    Do you have any information on how DHCP can be used when initializing the network? Long story short I got an old http client sample that only worked if you loaded it with ps2link. i managed to get the sample working and i am able to actually get files to download on official hardware with the sample(without needing ps2link!), I had to swap out 2 of the irx modules and i had to mess around with the code that handles "iopreset" i added in a "proper" User-Agent to the http.c (library i assume?). Me and another Guy barely figured out how to get the modules to load correctly and then we managed to use some of the ULE code for reading an ip address from a config file and extend the code to also support a dns server address

    So I wanted to Experiment with Getting DHCP working,Downloading a File (an elf), And then Getting the Ps2 to Execute the downloaded elf.

    Some other Things im interested on learning how to do is identify the model number of the ps2 that is shown in OSDSYS so that it can be used as part of the user agent string.

    Can File hashing be done? CRC32, MD5, SHA1 etc?

    Right Now this is how the Request shows up in my Server logs. Essentially It would be Kind of neat to be able to read the model number from the ps2 and be able to store that as some sort of variable that can be used later to display the model as part of the user Agent String

    Code:
    [19/Jan/2018:19:41:04 -0500] "GET /file.example HTTP/1.1" 200 62 "-" "LWIP (Sony PlayStation2; Homebrew; rv:0.1) PS2SDK/5.0 APPNAME/1.0
    
    On a Side Note I wrote a Prototype php Application that will let you throw a games product code at it (scus-97545,sles-XXXXX,sces,pbpx,etc) using a querystring and it Will Return The Title of the Game, Release,date,region,rating,cover art,disc art and other information if i have it in the database i am building. And I actually do have a prototype php application that i was able to construct in a short amount of time, i can show you a demo in a private message or something. I haven't really made any noise about this because i still have a lot of work to do with putting together all the data i have collected, then the application needs to be properly rate limited,i need to set up a memory cache on my server, and then fine tune it to work behind a loadbalancer/cdn


    but anyways heres an example

    Example: GET api.php?ProductID=SCUS-97545
    (server outputs this as raw text)
    Code:
    ProductID="SCUS-97545"
    Title="SOCOM - U.S. Navy SEALs - Combined Assault"
    Platform="PS2"
    Region="NTSC-U"
    Genre="Third-person shooter"
    Dev="Zipper Interactive"
    Pub="SCEA"
    Released="November 7, 2006"
    elpsa="N/A"
    ersb="Teen"
    pegi="N/A"
    usk="N/A"
    
    This Format Will probably Change and there are actually 2 scripts involved to get the information from the database.

    It Should be Noted that I was able to actually use the http.c library to download a game DB entry from my php app and save the contents of the output as a file on the memorycard.

    I also have the Intention of opening up this "titleID" php app to the public at some point,

    , But When I thought Up this "API" and coded the sample I didnt really know anything about ps2 homebrew development or the limitations of the SDK,how it reads files,etc and i really dont know much now.

    So Essentially I want to build an Application that Can Read the Disc in the Tray and Identify it and utilize the data provided by my Sample php app. Display a Picture or 2 and then be able to launch it. once i can learn how to do something like that it might be possible to create some other web driven homebrew apps for the ps2.

    Considering that There isn't any other Homebrew for the PS2 out there that i know of that can do anything like this, Im sure i have a long ways to go. But Hey Im a lot further then i expected.


    If I could Learn some More about the C language and what is available to use in the PS2 SDK (and maybe get the latest one) i could probably design a few web driven ps2 applications.
     
  5. sp193

    sp193 Site Soldier

    Joined:
    Mar 28, 2012
    Messages:
    2,217
    Likes Received:
    1,052
    There are a few things you must know of:
    • LoadExecPS2() only supports a few devices (these devices are the only ones supported by the PS2 IOP kernel):
      • CD/DVD-ROM.
      • Boot ROM, which includes rom0.
      • DVD ROM (the ROM chip that contains the DVD player), which includes rom1, rom2 and erom.
      • Memory Card
    • User-writable media will only supported signed files. This means that LoadExecPS2 does not support booting ELFs from memory card.
    To get around these restrictions (including the lack of support for devices like the HDD unit), you need to write your own loader (that takes the place of EELOAD. EELOAD is the loader that the EE kernel will use to load the ELF you specified, on behalf of LoadExecPS2.

    I do not have a very good example to give you (since FMCB is closed source), but you can refer to this version of LaunchELF's: https://github.com/AKuHAK/uLaunchELF/blob/master/loader/loader.c
    It does extra things, but the main parts are:
    • main() initializes SIFRPC, since it needs to tell the IOP to load the ELF.
    • Wipes EE RAM with wipeUserMem().
    • Writes back the data cache with FlushCache(0) before SifLoadELF. Note: if you do not do this, then there may be a cache coherency problem!
    • Loads the specified ELF with SifLoadELF.
    • Checks on the load result and prepares arguments for the loaded ELF.
    • Executes the loaded ELF with ExecPS2.

    If it is an old revision of the homebrew SDK, it may be good to upgrade to the latest version because a number of bugs and problems with solved over the years.

    If you need help, please provide more details (like what you attempted to build and what sort of error(s) were there).

    Before we get into the details of DHCP, you need to know about your choices for networking. Especially if you do not know about NETMAN.

    You have a few choices for networking in 2018 (NETMAN was only added in 2014):
    • Protocol stack on the EE, with the NETMAN network manager.
    • Protocol stack on the IOP, with the NETMAN network manager.
    • Protocol stack on the IOP, without the NETMAN network manager (legacy method).

    The protocol stack that we use is LWIP.

    NETMAN - The homebrew NETwork MANager
    From 2014, I have added a homebrew network manager. This allows us to mix and match the network stack with the SMAP (Ethernet) driver.
    It would also allow realtime monitoring and configuration of the network interface - something which could not be previously done.

    Protocol stack on the EE, with NETMAN

    If you chose this route, you get best performance, at the cost of having the EE to deal with the protocol. There is also currently no way to get IOP-side code to interact with the EE-side protocol stack, so you cannot do networking from the IOP side with this method.

    You need to do these to initialize the system:
    1. Load netman.irx
    2. Load smap.irx
    3. Initialize the EE-side LWIP library with ps2ipInit()

    Your EE program should link against -lnetman and -lps2ip.
    If you want to use DHCP, specify a dummy address like "169.254.0.1" , before enabling DHCP via ps2ip_setconfig(). I will get into that later.

    Protocol stack on the IOP, with NETMAN

    If you chose this route, you get to offload processing onto the IOP, at the cost of performance. It is possible to access the IOP-side LWIP library with the tcpips library.

    You need to do these to initialize the system:
    1. Load netman.irx
    2. Load smap.irx
    3. Load ps2ip-nm.irx
    4. Call NetManInit()

    Your EE program should link against -lnetman.
    If you want to use DHCP, specify a dummy address like "169.254.0.1" when loading ps2ip-nm.irx, before enabling DHCP via ps2ip_setconfig(). I will get into that later.

    Legacy method (PS2ETH)
    The bottom-most choice is the legacy method, which requires you to load ps2ip.irx before ps2smap.irx (from the PS2ETH project).

    Enabling DHCP in LWIP

    The DHCP feature would have to be built at compile-time. As of 2015, this feature is built by default.

    Code:
    int enableDHCP(void)
    {
        t_ip_info ip_info;
        struct ip4_addr dns;
    
         if ((result = ps2ip_getconfig("sm0", &ip_info)) >= 0) //The SMAP interface is always registered with LWIP as "sm0"
         {
                    IP4_ADDR((struct ip4_addr *)&ip_info.ipaddr, 169, 254, 0, 1);  //Set it to some dummy address
                    IP4_ADDR((struct ip4_addr *)&ip_info.netmask, 255, 255, 0, 0);
                    IP4_ADDR((struct ip4_addr *)&ip_info.gw, 0, 0, 0, 0);
                    IP4_ADDR(&dns, 0, 0, 0, 0);
    
                    ip_info.dhcp_enabled = 1;  //Enable DHCP
    
                dns_setserver(0, &dns); //Update DNS setting
                result = ps2ip_setconfig(&ip_info); //Apply new settings. This call will return 0 on success.
            } else
                result = 0;
        }
    
        return result; //After returning, if there is no error (0 = success), wait for DHCP to acquire a lease.
    }
    

    Examples (OPL)

    Utilize NETMAN to wait for the link status to be valid (user can unplug/plug in the Ethernet cable after OPL boots and it still works fine): https://github.com/ifcaro/Open-PS2-Loader/blob/master/src/ethsupport.c#L224

    The function within OPL that gets the current status from LWIP and updates the settings, if there is a difference: https://github.com/ifcaro/Open-PS2-Loader/blob/master/src/ethsupport.c#L843

    This is not very straightforward. While there is a function (sceCdRM), it is not supported by all PlayStation 2 models.

    This is how PS2Ident does it, which is how the HDD Browser does it:
    Code:
          char romver[16], ModelName[16];
           int result, fd;
    
           fd = fioOpen("rom0:ROMVER", O_RDONLY);
           fioRead(fd, romver, sizeof(romver));
           fioClose(fd);
    
        /*    Here's a weird tale of the model names of early PlayStation 2 consoles (SCPH-10000 and SCPH-15000):
              The model name was originally hardcoded into the OSDSYS, and the MECHACON appears to be unaware of the console's model name.
              Its EEPROM does not have the model name recorded in it.
              Invoking the "Read model" command on the first SCPH-10000 seems to return an error code,
              but it seems to function on my SCPH-15000... although no valid name is returned!
              In the HDD OSD, "SCPH-10000" is returned when the ROM v1.00 is detected (It checks rom0:ROMVER).
              However, it attempts to read the model name from the OSDSYS program of the consoles with ROM v1.01 (late SCPH-10000 and all SCPH-15000 models)!
              Perhaps it's because their TEST consoles have a varient of ROM v1.00,
              as well as their TOOLs... so perhaps that's why they had to hardcode the
              "SCPH-1000" model name for only this particular ROM version.
        */
        if(romver[0]=='0' && romver[1]=='1' && romver[2]=='0'){
            if(romver[3]=='0'){    // For ROM v1.00 (Early SCPH-10000 units).
                strcpy(ModelName, "SCPH-10000");
            }
            else{    //For ROM v1.01 (Late SCPH-10000, and all SCPH-15000 units).
                if((fd=fioOpen("rom0:OSDSYS", O_RDONLY))>=0){
                    fioLseek(fd, 0x8C808, SEEK_SET);    //The model name is located at this address. The HDD OSD will extract it this way too.
                    fioRead(fd, ModelName, 11);
                    fioClose(fd);
                }
                else strcpy(ModelName, "Unknown");
            }
        }
        else{
            if(sceCdAltRM(ModelName, &result)==0 || result!=0){
                strcpy(ModelName, "Unknown");
            }
        }
    
    sceCdRM() is not supported by the default IOP kernel's CDVDMAN+CDVDFSV combo either. This is why I use sceCdAltRM, which issues the Read Model command via sceCdApplySCmd. Please do not use board-specific modules, if you want your software to be compatible with all PlayStation 2 models.
    Code:
    
    int sceCdAltRM(char *ModelName, int *stat){
        unsigned char rdata[9];
        unsigned char sdata;
        int result1, result2;
    
        sdata=0;
        result1=sceCdApplySCmd(0x17, &sdata, 1, rdata, 9);
    
        *stat=rdata[0];
        memcpy(ModelName, &rdata[1], 8);
    
        sdata=8;
        result2=sceCdApplySCmd(0x17, &sdata, 1, rdata, 9);
    
        *stat|=rdata[0];
        memcpy(&ModelName[8], &rdata[1], 8);
    
        return((result1!=0&&result2!=0)?1:0);
    }
    
    You will need to source for your own library.

    You can reach me via PM or via e-mail.

    That is very impressive! It has been a long time, since I have heard of a major PlayStation 2 project.

    Regarding file I/O: there is support for stdio functions. However, they are actually wrappers around the real I/O libraries.
    The Sony SDK only has one I/O library, which is FILEIO. However, we in the homebrew world use the default IOP kernel's services... which cannot support filesystem-like devices, so we created fileXio to extend the FILEIO service's capabilities.

    So pick your library: fileio (part of libkernel) or fileXio. A long time ago, LaunchELF actually used both (for whatever reason). But you should just pick one...

    This sounds like OPL. We have the OPL-CL service that allows some data to be downloaded. However, we stopped short of supporting themes.
    I forgot what information it provides, unfortunately.

    Network support is challenging, and I applaud your afforts. Regardless of how it goes.
    If you have any further questions, please feel free to ask.

    If there are any bugs/suggestions to report, please feel free to open an issue ticket on ps2dev/ps2sdk.
     
    pool7 and svotib like this.
  6. Based_Skid

    Based_Skid Newly Registered

    Joined:
    Oct 20, 2017
    Messages:
    4
    Likes Received:
    0
    I did notice that OPL had Samba Share Support. but why use samba to download the information?
     
  7. sp193

    sp193 Site Soldier

    Joined:
    Mar 28, 2012
    Messages:
    2,217
    Likes Received:
    1,052
    We don't use SMB for downloading. We use HTTP.
    SMB is used for access game disc images.
     
sonicdude10
Draft saved Draft deleted
Insert every image as a...
  1.  0%

Share This Page