Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add HDDLOAD Implementation #598

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ee/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ SUBDIRS = startup erl kernel libcglue libpthreadglue libprofglue rpc debug \
libvux font input inputx network iopreboot \
mpeg \
elf-loader elf-loader-nocolour \
hddboot

include $(PS2SDKSRC)/Defs.make
include $(PS2SDKSRC)/Rules.make
Expand Down
14 changes: 14 additions & 0 deletions ee/hddboot/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# _____ ___ ____ ___ ____
# ____| | ____| | | |____|
# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
#-----------------------------------------------------------------------
# Copyright 2001-2024, ps2dev - http://www.ps2dev.org
# Licenced under Academic Free License version 2.0
# Review ps2sdk README & LICENSE files for further details.

EE_OBJS = hddboot.o erl_support.o

include $(PS2SDKSRC)/Defs.make
include $(PS2SDKSRC)/ee/Rules.lib.make
include $(PS2SDKSRC)/ee/Rules.make
include $(PS2SDKSRC)/ee/Rules.release
39 changes: 39 additions & 0 deletions ee/hddboot/include/hdd_boot.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#ifndef H_HDDBOOT_INC
#define H_HDDBOOT_INC

/**
* @brief Executes the HDDLOAD module from a file
* @param path path to the HDDLOAD IRX Module
* @param ret integer pointer to obtain the Module return value. it should return 0 on successfull load
* @return Module ID. if 0 or larger, success. if negative number, then MODLOAD refused to load the module (see kerr.h)
*/
int BootHDDLoadFile(char* path, int* ret);

/**
* @brief Executes the HDDLOAD module from a buffer on EE
* @param irx Pointer to the buffer holding HDDLOAD IRX Module
* @param size Size of the HDDLOAD IRX Module buffer
* @param ret integer pointer to obtain the Module return value. it should return 0 on successfull load
* @return Module ID. if 0 or larger, success. if negative number, then MODLOAD refused to load the module (see kerr.h)
*/
int BootHDDLoadBuffer(void* irx, unsigned int size, int* ret);

/**
* @brief Internal check for the HDDLOAD Status
* @return 1 if module loaded successfully
*/
int GetHddSupportEnabledStatus(void);

/**
* @brief Checks if the HDDLOAD Module thread has completed the DMA Transfer of the MBR.KELF from HDD to RAM
* @note once it is done, check with the ::DetermineHDDLoadStatus function
*/
int GetHddUpdateStatus(void);

/**
* @brief Returns the status of the HDDLOAD thread execution
* @return 1 if module Completed it's task
*/
void DetermineHDDLoadStatus(void);

#endif
20 changes: 20 additions & 0 deletions ee/hddboot/src/erl_support.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
# _____ ___ ____ ___ ____
# ____| | ____| | | |____|
# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
#-----------------------------------------------------------------------
# Copyright 2001-2004, ps2dev - http://www.ps2dev.org
# Licenced under Academic Free License version 2.0
# Review ps2sdk README & LICENSE files for further details.
#
# The erl-tags support
*/

#include <erl.h>

char * erl_id = "libhddboot";
char * erl_dependancies[] = {
"libkernel",
"libc",
0
};
58 changes: 58 additions & 0 deletions ee/hddboot/src/hddboot.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#include <kernel.h>
#include <loadfile.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

#include "hdd_boot.h"

static volatile unsigned int HDDLoadStatArea[4] ALIGNED(16);
static unsigned char IsHddSupportEnabled=0, HddSupportStatus=0;
char CmdStr[34];

static void construct_params() {
memset(&CmdStr, 0, sizeof(CmdStr));
strcpy(CmdStr, "-osd");
strcpy(&CmdStr[5], "0x00100000");
strcpy(&CmdStr[16], "-stat");
sprintf(&CmdStr[22], "%p", HDDLoadStatArea);
CmdStr[sizeof(CmdStr)-1]='\0';
}

int BootHDDLoadBuffer(void* irx, unsigned int size, int* ret){
int id, rett;
construct_params();
id = SifExecModuleBuffer(irx, size, sizeof(CmdStr), CmdStr, &rett);
if (id > 0 && rett != 1) IsHddSupportEnabled = 1;
if (ret != NULL) *ret = rett;
return id;
}

int BootHDDLoadFile(char* path, int* ret){
int id, rett;
construct_params();
id = SifLoadStartModule(path, sizeof(CmdStr), CmdStr, &rett);
if (id > 0 && rett != 1) IsHddSupportEnabled = 1;
if (ret != NULL) *ret = rett;
return id;
}

int GetHddSupportEnabledStatus(void){
return IsHddSupportEnabled;
}

int GetHddUpdateStatus(void){
return HddSupportStatus;
}

void DetermineHDDLoadStatus(void){
int result;

if((result=*(int *)UNCACHED_SEG(HDDLoadStatArea))==1){
HddSupportStatus = 1;
}
else if(result<0){
IsHddSupportEnabled = 0;
}
}
3 changes: 2 additions & 1 deletion iop/hdd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ SUBDIRS = \
hdck \
hdsk \
fsck \
fssk
fssk \
hddload

include $(PS2SDKSRC)/Defs.make
include $(PS2SDKSRC)/Rules.make
16 changes: 16 additions & 0 deletions iop/hdd/hddload/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# _____ ___ ____ ___ ____
# ____| | ____| | | |____|
# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
#-----------------------------------------------------------------------
# Copyright 2001-2024, ps2dev - http://www.ps2dev.org
# Licenced under Academic Free License version 2.0
# Review ps2sdk README & LICENSE files for further details.

IOP_BIN ?= hddload.irx
IOP_OBJS = hddload.o imports.o exports.o
IOP_INCS += -I$(PS2SDKSRC)/iop/dev9/dev9/include -I -I$(PS2SDKSRC)/iop/dev9/atad/include

include $(PS2SDKSRC)/Defs.make
include $(PS2SDKSRC)/iop/Rules.bin.make
include $(PS2SDKSRC)/iop/Rules.make
include $(PS2SDKSRC)/iop/Rules.release
85 changes: 85 additions & 0 deletions iop/hdd/hddload/README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# HDDLOAD
The HDDLOAD module is used for loading a bootstrap program from the `__mbr` partition of the attached HDD unit. The program is expected to be an ELF file, headerless, with load address `0x00100000` and appropriately-flagged KELF. (`kelftool encrypt mbr ELF KELF`)

Some PlayStation 2 consoles like the `SCPH-10000`, `SCPH-15000` and `SCPH-18000` do not support their HDD units, the Sony HDD Utility Disc may be used to install a "System Driver Update" that adds the ability to boot from the HDD.

While not intended by Sony, it is possible to use this system to boot a HDD update on the `SCPH-700xx`.

This update will boot a HDDLOAD module, which works similarly to the one found in the boot ROM (`rom0:HDDLOAD` on expansion bay models).

This package contains the source code a clone of the HDDLOAD module, based on a module from the 1.60 ROM.

# Dependencies

It depends on `dev9.irx` and `atad.irx` tp function.


## Workflow
- Call either `BootHDDLoadFile()` or `BootHDDLoadBuffer()` depending if the module will be loaded from a file or buffer. This will attempt to load `hddload.irx`, on the given memory card. If an update can be loaded, the update will be loaded to `0x00100000`.
This will take some time as the HDD may be spun up, so you could consider doing this in another thread. Otherwise, the user will be greeted with a black screen. Sony renders the "Sony Computer Entertainment" boot screen as this is being done.
- Call `DetermineHDDLoadStatus()`.
- Call `GetHddSupportEnabledStatus()` and `GetHddUpdateStatus()` to determine whether HDD booting was enabled and if an update was successfully booted.
- If both return 1, then boot the executable can be executed from `0x00100000`.


## Configuration
The IOP side will access the configuration storage area which is set up by EELOAD, which resides at `0x000003c0`. This is loaded from the MECHACON's NVRAM storage.

- Bits:
```
1 = Disable ATAD. By default, this is not set.
2 = Disable HDD support. PS2 consoles come with this bit set.
```
So if the HDD browser was never installed on the PS2, HDD support is disabled. Which results in HDDLOAD switching off the HDD immediately after the program is loaded.


## ATAD check
As described above, the `ATAD` module from the boot ROM is a combination of `DEV9` and `ATAD` from the Sony PS2 SDK. It will also check whether `ATAD` is enabled.
This bit is not set by default (`ATAD` is enabled by default). This is what the `ATAD` module checks:
```c
static int CheckATADEnabled(void){
return(!((*(*(vu8 **)0x000003c0))&1));
}
```

## Enabling HDD support
As shown in the FMCB Installer, the following can be done from the EE to enable HDD booting on the PS2. This should be done during installation:

```c
static int EnableHDDBooting(void){
int OpResult, result;
unsigned char OSDConfigBuffer[15];

do {
sceCdOpenConfig(0, 0, 1, &OpResult);
} while(OpResult&9);

do {
result=sceCdReadConfig(OSDConfigBuffer, &OpResult);
} while(OpResult&9 || result==0);

do {
result=sceCdCloseConfig(&OpResult);
} while(OpResult&9 || result==0);

if ((OSDConfigBuffer[0]&3)!=2) { //If ATAD support and HDD booting are not already activated.
OSDConfigBuffer[0]=(OSDConfigBuffer[0]&~3)|2;

do {
sceCdOpenConfig(0, 1, 1, &OpResult);
} while(OpResult&9);

do {
result = sceCdWriteConfig(OSDConfigBuffer, &OpResult);
} while(OpResult&9 || result==0);

do {
result = sceCdCloseConfig(&OpResult);
} while(OpResult&9 || result==0);

result = 0;
} else result = 1;

return result;
}
```
Loading
Loading