Skip to content
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
95 changes: 95 additions & 0 deletions scripts/Extras.sh
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,62 @@ cat << "EOF"
EOF
}

# Patch vmlinux kernel to use MWDMA2 instead of UDMA4 for DMA
# Fixes IDE→SD/SATA adapters on SCPH-7000x that fail on UDMA writes
patch_vmlinux_mwdma2() {
local vmlinux="$1"
if [ ! -f "$vmlinux" ]; then
echo " [!] vmlinux not found at $vmlinux" | tee -a "${LOG_FILE}"
return 1
fi
echo " Patching kernel for MWDMA2 (SD card mode)..." | tee -a "${LOG_FILE}"
python3 -c "
import struct, sys, subprocess
with open('$vmlinux', 'rb+') as f:
data = f.read()
sym_addr = None
# Try nm first, then readelf
for cmd in (['nm', '$vmlinux'], ['readelf', '-s', '$vmlinux']):
try:
out = subprocess.check_output(cmd, stderr=subprocess.DEVNULL).decode()
for line in out.split('\\n'):
if 'ide_config_drive_speed' in line:
parts = line.split()
if parts:
try: sym_addr = int(parts[0], 16); break
except: pass
if sym_addr: break
except: pass
if sym_addr:
jal = (0x0C << 26) | ((sym_addr >> 2) & 0x3FFFFFF)
jal_bytes = struct.pack('<I', jal)
old_li = struct.pack('<I', 0x24050044)
pattern = jal_bytes + old_li
idx = data.find(pattern)
if idx >= 0:
data = bytearray(data)
data[idx + 4] = 0x22
f.seek(0); f.write(data); f.truncate()
print(f'Patched at file offset 0x{idx+4:x}')
sys.exit(0)
# Fallback: find JAL + li a1,0x44
old_li = struct.pack('<I', 0x24050044)
idx = data.find(old_li)
while idx >= 0:
if idx >= 4:
prev = struct.unpack_from('<I', data, idx - 4)[0]
if (prev >> 26) == 0x03:
data = bytearray(data)
data[idx] = 0x22
f.seek(0); f.write(data); f.truncate()
print(f'Patched at file offset 0x{idx:x}')
sys.exit(0)
idx = data.find(old_li, idx + 1)
print('Pattern not found')
sys.exit(1)
" 2>> "${LOG_FILE}" && echo " [OK] Kernel patched for MWDMA2" | tee -a "${LOG_FILE}" || echo " [!] Kernel patch failed - may already be patched" | tee -a "${LOG_FILE}"
}

# Function for Option 1 - Install PS2 Linux
option_one() {
echo "########################################################################################################" >> "${LOG_FILE}"
Expand Down Expand Up @@ -1407,6 +1463,40 @@ option_five() {
read -n 1 -s -r -p " Press any key to return to the menu..." </dev/tty
}

option_six() {
clear
echo "########################################################################################################" >> "${LOG_FILE}"
echo "MWDMA2 Kernel Patch:" >> "${LOG_FILE}"

echo
echo " This patches the PS2 Linux kernel to use MWDMA2 instead of UDMA4"
echo " for DMA transfers. Fixes write hangs on SCPH-7000x consoles"
echo " using IDE→SD or IDE→SATA adapters."
echo
echo " NOTE: This fixes the PSBBN boot hang, but game launching from"
echo " the PSBBN menu may still freeze on 'Wait while loading' screen."
echo " This is a separate issue under investigation (see PR #575)."
echo
read -p " Apply MWDMA2 kernel patch? [y/N]: " confirm
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
echo
echo " Patch cancelled."
sleep 2
return 0
fi

APA_PARTITIONS=("__system" )
mapper_probe && \
mount_pfs || return 1
sleep 2

patch_vmlinux_mwdma2 "${STORAGE_DIR}/__system/p2lboot/vmlinux"
clean_up || return 1

echo
read -n 1 -s -r -p " Press any key to return to the menu..." </dev/tty
}

EXTRAS_SPLASH() {
clear
cat << "EOF"
Expand Down Expand Up @@ -1436,6 +1526,8 @@ display_menu() {

5) Clear Art & Icon Cache

6) Apply MWDMA2 Kernel Patch

b) Back to Main Menu

EOF
Expand Down Expand Up @@ -1495,6 +1587,9 @@ while true; do
5)
option_five
;;
6)
option_six
;;
b|B)
break
;;
Expand Down
9 changes: 8 additions & 1 deletion scripts/PSBBN-Installer.sh
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ done

if [ "$MODE" = "install" ]; then
LOG_FILE="${TOOLKIT_PATH}/logs/PSBBN-installer.log"
# Always create a small __boot partition (harmless, usable for modchip DEV2)
BOOT_PARTITION=1
else
LOG_FILE="${TOOLKIT_PATH}/logs/update.log"
fi
Expand All @@ -111,7 +113,7 @@ version_le() { # returns 0 (true) if $1 < $2

if [ "$MODE" = "install" ]; then
LINUX_PARTITIONS=("__linux.1" "__linux.4" "__linux.5" "__linux.6" "__linux.7" "__linux.8" "__linux.9" )
PFS_PARTITIONS=("__contents" "__system" "__sysconf" "__common" )
PFS_PARTITIONS=("__contents" "__system" "__sysconf" "__common" "__boot" )
fi

error_msg() {
Expand Down Expand Up @@ -939,6 +941,7 @@ if [ "$MODE" = "install" ]; then

COMMANDS="device ${DEVICE}\n"
COMMANDS+="initialize yes\n"
COMMANDS+="mkpart __boot 8M PFS\n"
COMMANDS+="mkpart __linux.1 512M EXT2\n"
COMMANDS+="mkpart __linux.2 128M EXT2SWAP\n"
COMMANDS+="mkpart __linux.4 512M EXT2\n"
Expand Down Expand Up @@ -1227,6 +1230,8 @@ if [ "$OSD_UPDATE" != "no" ]; then
cp -f "${ASSETS_DIR}/osdmenu/"{hosdmenu.elf,version.txt} "${STORAGE_DIR}/__system/osdmenu/" 2>> "${LOG_FILE}" || error_msg "Failed to copy hosdmenu.elf."
fi

# __boot partition is created automatically; users copy their own bootloader if needed

# Check if OSDMBR.CNF exists
if [ ! -f "${STORAGE_DIR}/__sysconf/osdmenu/OSDMBR.CNF" ]; then
if sudo "${HDL_DUMP}" toc ${DEVICE} | grep -q "__linux.3"; then
Expand Down Expand Up @@ -1388,6 +1393,8 @@ if [ "$OS" = "PSBBN" ] && [ "$MODE" = "update" ]; then
sudo cp -f "${SYSCONF_XML}" "${STORAGE_DIR}/__linux.4/bn/script/utility/sysconf.xml" || error_msg "Failed to replace sysconf.xml."
fi

# MWDMA2 kernel patch is available in the Extras menu for IDE→SD adapter users

UNMOUNT_ALL

if [ "$OS" = "PSBBN" ] && [ "$MODE" = "update" ] && version_le "${psbbn_version:-0}" "4.0.0"; then
Expand Down