-
Notifications
You must be signed in to change notification settings - Fork 0
/
find_ps3_ufs2_byte_locations
executable file
·126 lines (98 loc) · 4.36 KB
/
find_ps3_ufs2_byte_locations
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/bin/bash
test "$#" -eq 1 || { cat << __EOF__
usage: find_ps3_ufs2_byte_locations GameOS_superblock.img
The PS3 defaults to setting the UFS2 formatted GameOS partition to
have 8% minimum free space and uses the TIME optimization option. This is
fine for smaller drives, but this wastes over 100GB on a 1.5TB drive.
The reason they do this is that UFS2 recommends no less than 5% free
space to reduce fragmentation and increase performance, and TIME
optimization increases write performance. However, it's possible to
reduce the minimum free space to allow for more drive usage, which
should not cause many problems on very large drives. Changing to SPACE
optimization will also slow down writes, but will lower fragmentation
which should speed up reads. Since we mainly care about read speed,
this seems like a resonable tradeoff to get a ton of extra space for games.
While it's possible to mount a PS3 hard drive and view it's decrypted
paritions, unfortunately the tunefs.ufs tool doesn't appear to work.
However, the file command does appear to show the UFS2 filesystem info.
So instead of using that to change the minimum free space and the
optimization type, this script manually scans and tests changes to a
parition dump and uses the file command to check for success.
This would hypothetically work directly on the PS3 drive, but since it
writes to so many bytes very quickly, and who knows how stable the
decryption and mounting software is, it's safer to use a small image
dump of the head of the partition first, then only write the bytes that
are needed.
__EOF__
exit
}
FILE=$1
SIZE=$(stat --printf="%s" $FILE)
MIN_LOCATION=0
OPT_LOCATION=0
MIN_ALREADY_SET=0
OPT_ALREADY_SET=0
# Check if the drive has already been reconfigured
test $(file $FILE | grep "minimum percentage of free blocks 1," | wc -l) -ne 1 || MIN_ALREADY_SET=1
test $(file $FILE | grep "SPACE optimization" | wc -l) -ne 1 || OPT_ALREADY_SET=1
# Hide the cursor to prevent flickering
tput civis
# Trap ctrl-c to reset the cursor if the user cancels the operation
trap ctrl_c INT
function ctrl_c() {
tput cnorm
exit
}
# Start at 65536 to save time as this is where the superblock starts and the beginning should all be zeros
i=65536
# Loop through the paritition image, setting one byte at a time and checking with file
while [ $i -lt $SIZE ]; do
# Skip to the end if the drive is already configured
if [ $MIN_ALREADY_SET -eq 1 ] && [ $OPT_ALREADY_SET -eq 1 ]; then
break
fi
# Save the current byte
CURRENT=$(xxd -p -l 1 -s $i $FILE)
printf "\rChecking byte $i... current contents: $CURRENT "
# Try writing 0x01 to this location as this will either set the min free space to 1%
# or it will change the optimization type from TIME to SPACE
printf '\x01' | dd of=$FILE bs=1 seek=$i count=1 conv=notrunc status=none
# If needed, check to see if this is the minimum space byte location
if [ $MIN_LOCATION -eq 0 ] && [ $(file $FILE | grep "minimum percentage of free blocks 1," | wc -l) -eq 1 ]; then
# Found it!
#printf "Found minimum space location! $i\n"
MIN_LOCATION=$i
fi
# If not found yet, check to see if this is the optimization type byte location
if [ $OPT_LOCATION -eq 0 ]; [ $(file $FILE | grep "SPACE optimization" | wc -l) -eq 1 ]; then
# Found it!
#printf "Found optimization type location! $i\n"
OPT_LOCATION=$i
fi
# Return the file to it's original state
printf "\x$CURRENT" | dd of=$FILE bs=1 seek=$i count=1 conv=notrunc status=none
# See if we are all done
if [ $MIN_LOCATION -ne 0 ] && [ $OPT_LOCATION -ne 0 ]; then
break
fi
i=$[$i+1]
done
# Clear the output
printf "\r$(tput el)"
# Print the results
if [ $MIN_ALREADY_SET -eq 1 ]; then
printf "Minimum free space already configured to 1%%\n"
elif [ $MIN_LOCATION -eq 0 ]; then
printf "Minimum free space byte location not found\n"
else
printf "Minimum free space byte location: $MIN_LOCATION\n"
fi
if [ $OPT_ALREADY_SET -eq 1 ]; then
printf "Optimization type already set to SPACE\n"
elif [ $OPT_LOCATION -eq 0 ]; then
printf "Optimization type byte location not found\n"
else
printf "Optimiation type byte location: $OPT_LOCATION\n"
fi
# Reset the cursor
tput cnorm