cpio.secure from harddrive will not load on 160gb units. don't know why. works fine in flash. this hack will not work 'out of the box' for 160gb units. that will be coming very shortly.
First, let me also congratulate Archilles. Very nice job! I was also working on this in order to be able to replace my HDD in case of failure, and thanks of your precious help i've been able to replace it right now. That's a great relief: now i'm sure i will be able to keep using my Archos in the future!
Since i have a 160GB unit, i can confirm that the cpio.secure file is not read from HDD. For the moment, i've replaced the HDD with a 80GB one to have this hack working. And i'm investigating the reason why it doesn't work.
Since it works with smaller HDD, it seems pretty obvious that it should be the infamous 137.4GB limit issue because of the use of 28-bit only LBA instead of 48-bit one.
This is confirmed by analyzing the boot1 assembly. Note: since boot1 is copied from Flash to RAM and executed from RAM, i will give both FLASH (including offset) and RAM addresses.
- In sub 0x20382C4 (0x820071FC): HDD geometry/properties are retrieved ("Identify Drive" 0xEC command) and stored in RAM starting at 0x82E01004. The first 4 double words stored are: number of logical heads, number of logical sectors per logical track, number of cylinders, number of user addressable sectors (LBA mode). Then there's a word containing the number of sectors per mutiple R/W command, and finally 2 bytes: containing either 0x20/0xC4 and 0x30/0xC5. The interesting parts here are:
* The "number of user addressable sectors" for LBA mode: 32 bits = 4294967296 sectors, with 512 bytes/sector = 2 TB max. This is enough for a while i believe
So the problem is not here.
* The last 2 bytes are in fact the codes of Read or Write commands that will be used later. If Multiple R/W mode is not available, simple Read (0x20) or Write (0x30) command will be used. If multiple R/W mode available: 0xC4 (Read Multiple) and 0xC5 (Write Multiple) commands will be used.
- In sub 0x2038084 (0x82006FBC): This function reads sectors. Around 0x803211C (0x82007054), HDD is set to LBA mode. Then starting from 0x2038194 (0x820070CC), the start sector address is stored in registers 0x1C661F3 to F6: Bits 7:0 to LBA Low, 15:8 to LBA Mid, 23:16 to LBA High and 27:24 to Device Register. Then the previously stored read command code is retrieved from memory, i.e. 0xC4 which is "Read Multiple" command. According to ATA standard (http://www.t10.org/t13/project/d1410r3a-ATA-ATAPI-6.pdf
) p.188, and as we can see, only 28-bit LBA is used here, so we can address no more than 137.4GB (2^28 * 512)!
That's why cpio.secure file is not read from 160GB drives, since hidden partition is located at the very end of the disk, below the 137.4GB limit!
According to the ATA standard, p.191, we should use instead "Read Multiple Ext" command (code 0x29) which used a 48-bit LBA. But, if i understand well the standard, this command uses the same registers but in 2 passes:
- First pass to write LBA bits 31:24, 39:32, 47:40 to LBA Low, Mid and High
- Second pass to write LBA bits 7:0, 15:8, 23:16 to LBA Low, Mid and High
2 passes are also used to extend the sector count from 8 to 16-bit, but i don't think we need to read so much sectors in our case
Device register is no more used for LBA, but only indicates which device is addressed and define LBA mode.
So we should be able to overcome the issue by using 0x29 command instead of 0xC4, but for that we need to write 2 times to the registers were the original code write only once. So we can't simply patch the aread, since we need more space to add a second pass.
We could create a subroutine in an unused space. Boot0 copies Flash memory zone 0x20310C8 to 0x20450C7 (= Boot1) to RAM (0x82000000). It seems to me that the space 0x020431C8 (0x82012100) to 0x020450C3 (0x82013FFB) is empty and unused, so we could probably use it.
So the solution could be:
- Patch sub 0x20382C4 (0x820071FC) to store command code 0x29 instead of 0xC4
- Patch sub 0x2038084 (0x82006FBC), replacing the portion of code starting at 0x2038194 (0x820070CC) by a BL to a new subroutine in the unused space.
- Add a new subroutine in the unused space with code to fill the 48-bit LBA in registers in 2 passes
Despite the write command code is also stored in memory, i've not found any other subroutine that could write to disk in boot1. Since boot1 just load and boot the kernel from cpio.secure, i believe that the kernel is able to handle big HDD correctly.
Since modifying the Flash is always a risky operation, I would appreciate if our great gurus out there could check my assumptions and confirm that the proposed solution is OK. Thanks in advance!