Hardware Hacks for the LS2
All input is welcome. Please do not edit this page directly as I do not want any information to get past me without my knowledge as it could be detrimental to the LS2 on which I'm experimenting. Please post any comments to the forum thread or the talk page.
This is an account of the attempts of Tampakuro (aka Kuroguy) to open the LS2 hardware to more development. As the goals in this article are met we will be adding notes to alert other users that a particular goal/set of instructions is safe to attempt.
There is a forum thread at http://forum.linkstationwiki.net/index.php?action=vthread&forum=3&topic=1530 with a discussion relating to this project. Please feel free to add relevant content to that thread.
The LS2 that the community purchased arrived from Dusseldorf today (Oct 6, 2006). I will be installing a JTAG port on it. Once that is done I'll be installing a serial console. I plan to document all of the steps here. As described it came without a hard disk and (possibly) with a bad power supply.
- 1 Additional Info about the history of this particular LS2
- 2 Lets see what we can see
- 3 Getting it to power up
- 4 Planned modifications
Additional Info about the history of this particular LS2
Mindbender asked Adrian (the former owner of this box) again what happened and what he did to repair the LS2 and he told me that he caused the problem by shortening the board somehow while replacing the hdd.
As a result of the short, two capacitors were destroyed and he replaced them....but it did not work. Here is a picture which shows which Capacitors were replaced...maybe they are faulty or not correctly soldered to the board?
Lets see what we can see
I first disassembled the LS2 and took a few photos of the board. Noteworthy on the back of the board labeled CN8 is a mini PCI header. It looks like the addition of 4 SMT resistors and 6 SMT capacitors is all that is necessary to get this port working.
From the manufacturer's literature given to me by Mindbender I know that CN9 is the JTAG port. The spec says that the target voltage can be picked up on pin 14. As in teh case of the LS1 and LS-HG, the series resistor is missing. Rather than mess with it, I'll likely get power for the JTAG cable from elsewhere on the board.
Next I unplugged the power supply from the board and powered it up. My voltmeter told me that the power supply is working. That means I need to look for a bad fuse or switch on the main board. This might be over before it gets started.
J1 looks just like the standard serial header found on all of the PPC based boxes. It even has pads for a decoupling capacitor (C34) across pins 3 and 4 (on the PPC boxes pin 3 is 3.3V and pin 4 is ground). I'll check for 3.3 volts across these pins when I power up the board. Pin 2, like the PPC versions, has a pullup resistor, R256 (not installed) and series resistor, R186 (not installed) If this does turn out to be a serial port it will make life really easy on us.
CN5 appears to be a header for programming the AVR. We shouldn't need to mess with this one and unless someone would like me to solder a header in place, I'll leave it alone.
I've included a couple of high resolution photos of the main circuit board.
Getting it to power up
The buttons wouldn't do anything and I think that the microcontroller (does the same functions as the AVR in the PPC based models) is damaged. The microcontroller is responsible for powering up and down the Linkstation. It also controls the cooling fan. Good news, After a bit of fiddling i Have been able to make the LS2 power up the fan by shorting pins 24 and 25 of the AVR. I can also make the fan and drive spin up by shorting pins 23 and 24 and then shorting and holding pins 24 and 25. I believe the LS is powering up too. I can hear the heads stroking back and forth.
As I will be somewhat bypassing the microprocessor I'll try to trace the pins and document their functions too.
I've gotten some conflicting results when injecting data onto the pins of the microprocessor. I suspect it is due to the circuitry of the microprocessor transferring data onto other pins at the same time. In any event, there is no way for me to know the normal state of the inputs and outputs of the microprocessor with it still in circuit. I'm seriously considering removing the microprocessor from the board to get some certain answers as to what pin does what without interference by the microprocessor. This will allow me to properly document which pin does what.
I assume there are at least the following DI (digital input)and DO (digital output) pins:
DI - fan status DI - front button status DI - Rear button status DI - HDD read/write status DI - Serial in DO - Serial out DO - Fan Start DO - HDD start DO - HDD light on DO - DIAG. light on DO - Power light on DO - Reset CPU
Other pins that have to be present would be Vcc and Ground
If I can determine which pin does what it will be very possible to write our own application for the microprocessor and get rid of the proprietary stuff Buffalo is using. This would allow things like additional flash patterns for the LED.
1. Install and test the JTAG header.
2. Test/Install serial level converter.
3. Optionally try to install a mini PCI slot.
4. Install additional USB ports
The microcontroller work wasn't planned. It was necessitated by the fact that the LS2 I have was someone else's damaged discard. This work came from an attempt to get the LS2 to power up.
The microcontroller was interfering with diagnosing the cause of the LS2 not powering up so I decided to remove it. It took the better part of an hour to remove the microcontroller and solder it in its new home - a piece of perf board with 2 sets of 2x7 pin headers. I had to bend the pins into a single row making two rows of 14 each on .05" centers to match up with the pin spacing on the microcontroller. Check out this photo of the microcontroller sitting atop its new socket. The plan was to attach a 28 strand ribbon cable to the circuit board where the microcontroller was located and terminate the other end of the cable with two 2x7 IDE headers. The microcontroller could then be snapped back in the LS2 at will. With the microcontroller removed from the circuit I could trace those pins and their functions without the microcontroller causing problems.
A bit of serendipity here. Printed on the circuit board under the microcontroller was the part number MC68HC908JL8CDW. This is a Motorola Freescale microprocessor. Motorola has a complete data sheet posted on the Freescale site. This is new and very useful information.
With the microcontroller removed from the circuit, I easily found the cause of the LS2 not powering up; a missing resistor on the main board, R265. This is a series resistor for the power button. I installed a 4.7K resistor and reinstalled the microcontroller and it booted without incident. All that work removing the microcontroller and setting it in a homebrew socket was not necessary. Of course, we did gain some very useful information, such as the true part number for the microcontroller and the pin functions of the microcontroller, so it wasn't a total waste of time. In fact, I couldn't have diagnosed and repaired the problem without removing the microcontroller unless I had a schematic drawing of the LS2 and those aren't available. It is possible to write a completely open source application for this microcontroller now that we know what it is and the specific pin functions.
I have also determined that the Link light is not controlled by the microcontroller.
The following table lists confirmed pin functions of the microcontroller:
|1||-||Pin 3, CN5|
|2||DO||Pull to ground to turn Diagnostic light on|
|3||-||Ground and Pin 9, CN5|
|4||-||Pin 1, CN5|
|6||DO||Pull to ground to turn HDD full light on|
|8||DO||Pull to ground to turn power light on green|
|9||DO||Pull to ground to turn power light on amber|
|13||DI||Serial in from CPU|
|14||DI||Serial out to CPU|
|17||-||Pin 8, CN5|
|18||-||Pin 7, CN5|
|20||-||Pin 10, CN5|
|21||-||Pin 5, CN5|
|23||DI||Rear button pressed pulls low|
|24||DO||Pull High to turn on fan and spin up HDD|
|26||DI||Fan Status, High means fan running|
|27||DI||Power button pressed pulls low|
|28||-||Vcc, Through filter FIL18 to Pin 4, CN5|
CN5 is a 2x5 header that appears to be used to program the microcontroller. Pin 2 of this connector is tied to Vcc (3.3V). Pin 6 of this connector is tied to ground.
Items in bold have been confirmed with the microcontroller removed from the circuit.
The literature lists the following pins and descriptions:
|nTRST||1||must be pulled high if not controlled by the JTAG cable|
|TDO||5||Series Resistor R64 not installed - Installed 330 ohm resistor|
|Power||14||Series resistor R181 and decoupling capacitor C35 not installed. - Bridged R181, didn't install C35.|
The instruction manual at http://www.idt.com/products/files/1868542/32434manual.pdf details the required values of the TDO series resistor on page 494. It states that a typical value of R64 is 1Kohm. It says a smaller value reduces crosstalk and values of 33 ohm are sufficient. It also states that a value of 47Kohm is sufficient for hot plugging applications. Since we will not be hot plugging the JTAG cable we can use a value closer to the recommended value of 1Kohm. As it turned out I could not find a 1K SMT resistor in my computer graveyard. Instead I installed a 330 ohm resistor (has 331 on it).
Bridging R181 and installing a capacitor in the range of .1uF at C35 should be sufficient to power the cable. In fact, The DLC5 cables I made already have a decoupling capacitor across the power and ground lines so C35 may be omitted in our case. If you are in doubt as to whether your cable has a capacitor installed you should install a capacitor at C35. It won't cause problems if both are installed.
Also, according to the manufacturer's data, pin 12 on the main board should be left unpopulated to prevent connecting the JTAG cable to the main board backwards.
The following photo shows the JTAG connector and R64 just above the jtag header. I have installed the JTAG header on the back of the board to make it easy to plug and unplug the JTAG Cable. If I had not done this I would have needed to remove and replace the main board every time I wanted to connect or disconnect the JTAG cable. As a result of the header being on the back side of the board, the rows of pins are reversed. It will mean wiring our JTAG cable connector backwards. This is not a problem until you try to use your JTAG cable on other hardware as it will be wired backwards. Connecting the cable backwards could damage the JTAG port on your board, so make sure you get it right.
The JTAG cable I designed for the PPC boxes along with some very minor modifications was able to detect the chain.
I terminated the cable with the 14 pin IDE connector instead of the 16 pin connector used for the PPC boxes (I built an adapter), it was necessary to pull pin 1 (nTRST) high. I just tied pin 14 (3.3v) to pin 1 through a 1K resistor and Openwince's JTAG Tools detected the chain.
==== Openwince JTAG Tools (never did work here) ==== I was not successful getting Openwince's JTAG tools to work with the LS2. I'm leaving this section in this wiki article for historical purposes. Please skip down to the Hairydairymaid section below for the JTAG solution that was finally made work.
About the only JTAG software that is free and works with the DLC5 flash is Openwince's JTAG tools. This is the software that I use to unbrick Kuros and PPC linkstations (Also works with the Terastation Pro). I need to build the IDT include files for Openwince's JTAG tools before going any further. As those files are not part of the source package I will need to create them myself. This could take some time as I'm not a software person.
I found in IDT's website a BSDL file that describes how to talk to the SOC via JTAG. I have also found a script for converting Xilinx BSDL files for use with JTAG Tools. Hopefully this will work and we'll have the ability to read and write flash contents. There are a number of files that need to be edited so the software will recognize the LS2 properly, but I think I can get that done properly.
I'm still not sure if the DLC5 cable will work, but if it doesn't, I'll build a wiggler cable and continue working. At the very least we know the header is installed correctly.
Configuring JTAG Tools to recognize the LS2's components is simple. The Device has a unique identification string. It is a 32 bit number and JTAG Tools displays this ID when the command detect is executed. The ID is 00000000001000010111000001100111. There are 3 parts to this ID. According to the standard, the least significant bit is required to be 1.
Bits 12 through 2 (00000000001000010111000001100111) are a unique number that identifies the manufacturer. If you add this ID to /usr/local/share/jtag/MANUFACTURERS along with the the manufacturer name and directory name where the target manufacturer's data files are located JTAG Tools will automatically recognize the device manufacturer when detect is run.
The line I added looks like this :
00000110011 idt IDT
The "idt" is the name of the data directory for this manufacturer loacted at /usr/local/share/jtag/data/ and the "IDT" is the text that detect will return as the manufacturer.
In the idt directory there are several files we need to create. Create a file named PARTS. This file uses bits 28 through 13 (00000000001000010111000001100111)of the device identification string. It defines the specific part's name and the subdirectory where the converted BSDL file is located. This file contains the following line:
0000001000010111 79RC32434 79RC32434
We create a file named /usr/local/share/jtag/data/idt/79RC32434/STEPPINGS which contains bits 32 through 29 (00000000001000010111000001100111) and the name of the file that contains the converted BSDL file (mips) along with the version number of the target (I called it LS2):
0000 mips LS2
We also need to create a file named /usr/local/share/jtag/data/idt/79RC32434/mips which contains the converted BSDL file. We create this file by piping the bsdl file into the conversion script and piping the output to a file named mips. We get the BSDL file from http://www.idt.com/products/files/9185/79RC32434_BSDL_83464.txt. We execute:
bsd2jtag < 79RC32434_BSDL_83464 > mips
If you do this correctly, JTAG Tools will return the following when detect is executed:
jtag> detect IR length: 5 Chain length: 1 Device Id: 00000000001000010111000001100111 Manufacturer: IDT Part: 79RC32434 Stepping: LS2 Filename: /usr/local/share/jtag/idt/79RC32434/mips
Next we need to get JTAG Tools to initialize the JTAG bus.
HairyDairyMaid (did work)
Hairydairymaid is a tool used to read and write to the flash of the Linksys WRT54G router. Functionality has been added that would allow access to the flash mamory using E(xtended)JTAG. This is a set of JTAG instructions for the MIPS based processors and they allow what is known as processor access (PrAcc). PrAcc allows the loading and execution of instruction codes into the MIPS core. HairyDairyMaid (HDM) has these applications written and should be able to install that code on the LS2 allowing the reading and writing of the flash contents via JTAG.
As it turned out, the HDM program needed some modifications. Tthe patched source as well as a makefile and compiled zipped binary that will run on x86 architecture is available here. Read on for a description of the modifications and tests that were done to ensure that The HDM was working properly and was not going to make any bricks (at least if used properly).
My first attempt at using HairyDairyMaid produced the following output (after amking minor modifications to the source code):
localhost HDM # ./wrt54g -backup:cfe ==================================== WRT54G/GS EJTAG Debrick Utility v4.5 ==================================== Probing bus ... Done Instruction Length set to 5 CPU Chip ID: 00000000001000010111000001100111 (00217067) *** Found a LS2 chip *** - EJTAG IMPCODE ....... : 01000000010000000100000000000000 (40404000) - EJTAG Version ....... : 2.6 - EJTAG DMA Support ... : No Issuing Processor / Peripheral Reset ... Done Enabling Memory Writes ... Skipped Halting Processor ... <Processor Entered Debug Mode!> ... Done Clearing Watchdog ... Done Probing Flash at (Flash Window: 0x1fc00000) ... Done *** Unknown or NO Flash Chip Detected *** *** REQUESTED OPERATION IS COMPLETE ***
It looks like I need to define the flash chip in HDM. This might work....
With the help of linuxnotincluded I was able to read, write, and erase areas of the flash via JTAG. Since LNI didn't have a LS2 I did the testing and made several suggestions while he did most (pretty much all) of the coding. The source code for the modified hairydairymaid software will be posted in a day or two as there is still some cleanup to do.
As it turns out, the JTAG port on the LS2 is actually a MIPS proprietary EJTAG port. It is similar to the JTAG port except that it allows debugging. We were able to execute code on the LS2 that would read or write the flash contents and send them out to the host computer via the EJTAG port. What follows are some of the tests that were performed on the LS2
First we got the HDM to recognize the LS2's MIPS 32434 SOC by adding the ID code to the source code. Next, LNI wrote an 8 bit flash chip driver and integrated it into HDM. I tested the changes and emailed output from the HDM to him for additional modifications. Here is the output from the first version that could read the flash. I Flashed a 256 byte file to the area starting at 1fc3400 as that entire area was filled with ff. By the way, the /flash8 option was added since the 32434 could only write 8 bits wide at a time. The HDM was later modified so the /flash8 switch is no longer required as the HDM now detects the flash type and knows how to write and read its contents.
localhost LNIHDM # ./wrt54g -flash:custom /flash8 /start:1fc34000 /length:ff /window:bfc00000 ==================================== WRT54G/GS EJTAG Debrick Utility v4.6 ==================================== Probing bus ... Done Instruction Length set to 5 CPU Chip ID: 00000000001000010111000001100111 (00217067) *** Found a Linkstation 2 with RISC K4C chip *** - EJTAG IMPCODE ....... : 01000000010000000100000000000000 (40404000) - EJTAG Version ....... : 2.6 - EJTAG DMA Support ... : No Issuing Processor / Peripheral Reset ... Done Enabling Memory Writes ... Skipped Halting Processor ... <Processor Entered Debug Mode!> ... Done Clearing Watchdog ... Done Probing Flash at (Flash Window: 0xbfc00000) ... identify_flash_part: vendid: C2, devid: A7 Done Flash Vendor ID: 00000000000000000000000011000010 (000000C2) Flash Device ID: 00000000000000000000000010100111 (000000A7) *** Found a MX29LV320T 2Mx16 TopB (4MB) Flash Chip *** - Flash Chip Window Start .... : bfc00000 - Flash Chip Window Length ... : 00400000 - Selected Area Start ........ : 1fc34000 - Selected Area Length ....... : 000000ff *** You Selected to Flash the CUSTOM.BIN *** ========================= Flashing Routine Started ========================= Total Blocks to Erase: 0 Loading CUSTOM.BIN to Flash Memory... [ 1% Flashed] 1fc34000: 00000000 00000000 00000000 00000000 [ 7% Flashed] 1fc34010: 00000000 00000000 00000000 00000000 [ 14% Flashed] 1fc34020: 00000000 00000000 00000000 00000000 [ 20% Flashed] 1fc34030: 00000000 00000000 00000000 00000000 [ 26% Flashed] 1fc34040: 00000000 00000000 00000000 00000000 [ 32% Flashed] 1fc34050: 00000000 00000000 00000000 00000000 [ 39% Flashed] 1fc34060: 00000000 00000000 00000000 00000000 [ 45% Flashed] 1fc34070: 00000000 00000000 00000000 00000000 [ 51% Flashed] 1fc34080: 00000000 00000000 00000000 00000000 [ 58% Flashed] 1fc34090: 00000000 00000000 00000000 00000000 [ 64% Flashed] 1fc340a0: 00000000 00000000 00000000 00000000 [ 70% Flashed] 1fc340b0: 00000000 00000000 00000000 00000000 [ 76% Flashed] 1fc340c0: 00000000 00000000 00000000 00000000 [ 83% Flashed] 1fc340d0: 00000000 00000000 00000000 00000000 [ 89% Flashed] 1fc340e0: 00000000 00000000 00000000 00000000 [ 95% Flashed] 1fc340f0: 00000000 00000000 00000000 00000000 Done (CUSTOM.BIN loaded into Flash Memory OK) ========================= Flashing Routine Complete ========================= elapsed time: 15 seconds *** REQUESTED OPERATION IS COMPLETE ***
and then read the flash and got:
localhost LNIHDM # ./wrt54g -backup:custom /flash8 /start:1fc34000 /length:ff /window:bfc00000 ==================================== WRT54G/GS EJTAG Debrick Utility v4.6 ==================================== Probing bus ... Done Instruction Length set to 5 CPU Chip ID: 00000000001000010111000001100111 (00217067) *** Found a Linkstation 2 with RISC K4C chip *** - EJTAG IMPCODE ....... : 01000000010000000100000000000000 (40404000) - EJTAG Version ....... : 2.6 - EJTAG DMA Support ... : No Issuing Processor / Peripheral Reset ... Done Enabling Memory Writes ... Skipped Halting Processor ... <Processor Entered Debug Mode!> ... Done Clearing Watchdog ... Done Probing Flash at (Flash Window: 0xbfc00000) ... identify_flash_part: vendid: C2, devid: A7 Done Flash Vendor ID: 00000000000000000000000011000010 (000000C2) Flash Device ID: 00000000000000000000000010100111 (000000A7) *** Found a MX29LV320T 2Mx16 TopB (4MB) Flash Chip *** - Flash Chip Window Start .... : bfc00000 - Flash Chip Window Length ... : 00400000 - Selected Area Start ........ : 1fc34000 - Selected Area Length ....... : 000000ff *** You Selected to Backup the CUSTOM.BIN *** ========================= Backup Routine Started ========================= Saving CUSTOM.BIN.SAVED_20061119_130016 to Disk... [ 1% Backed Up] 1fc34000: 00000000 00000000 00000000 00000000 [ 7% Backed Up] 1fc34010: 00000000 00000000 00000000 00000000 [ 14% Backed Up] 1fc34020: 00000000 00000000 00000000 00000000 [ 20% Backed Up] 1fc34030: 00000000 00000000 00000000 00000000 [ 26% Backed Up] 1fc34040: 00000000 00000000 00000000 00000000 [ 32% Backed Up] 1fc34050: 00000000 00000000 00000000 00000000 [ 39% Backed Up] 1fc34060: 00000000 00000000 00000000 00000000 [ 45% Backed Up] 1fc34070: 00000000 00000000 00000000 00000000 [ 51% Backed Up] 1fc34080: 00000000 00000000 00000000 00000000 [ 58% Backed Up] 1fc34090: 00000000 00000000 00000000 00000000 [ 64% Backed Up] 1fc340a0: 00000000 00000000 00000000 00000000 [ 70% Backed Up] 1fc340b0: 00000000 00000000 00000000 00000000 [ 76% Backed Up] 1fc340c0: 00000000 00000000 00000000 00000000 [ 83% Backed Up] 1fc340d0: 00000000 00000000 00000000 00000000 [ 89% Backed Up] 1fc340e0: 00000000 00000000 00000000 00000000 [ 95% Backed Up] 1fc340f0: 00000000 00000000 00000000 00000000 Done (CUSTOM.BIN.SAVED_20061119_130016 saved to Disk OK) bytes written: 256 ========================= Backup Routine Complete ========================= elapsed time: 0 seconds *** REQUESTED OPERATION IS COMPLETE ***
Looks like we are in business. Next I read the contents from 1FFF9000 thru 1FFFA000. It contained all 0xFF. I then flashed 256 bytes of 0x00 starting at 0x1FFF9000 and read the area from 0x1FFF9000 thru 0x1FFFA000 and verified that the first 256 bytes had been changed to 0x00. After that I erased the area from 0x1FFF9000 thru 0x1FFFA000 and reread the same area once again. That area once again contained all 0xFF.
Now that I knew that the read and erase functions worked I needed to test that the data was being written to the flash and read from the flash in the proper order.
Next I did the same with a file that contained a sequence of bytes that started at 0x00 and incremented to 0xff. The flash contents were written properly and erased properly leaving that area containing all 0xff.
The only suggestion I had for LNI was to modify the source code to allow the user to specify the name of the file to flash and backup, as it can be very confusing having a disk full of files named CUSTOM.BIN.SAVED_<date>_
The last test I did was to boot the LS2 normally and read the MTD devices using dd. I then compared them to the data I had read from the flash using the JTAG cable and HDM. They were exactly alike.
The final version of the HDM software will include the ability to specify the filename to write and read. It also currently automatically detects the LS2's MIPS 32434 and flash chip so it is no longer necessary to specify the /flash8 option that LNI included in the source code.
I will upload the flash contents to the downloads section in a day or two after I have had time to test the final version.
Serial console installation (Completed - Safe to install)
I ordered a max3232 chip and 5 capacitors from Mouser electronics (along with some other parts for the hacks I'm doing here) and have built a serial level converter on perf board (I don't have time to etch a board) This box will have a permanently installed serial level converter. We'll need to install a series resistor (R186). Had we installed a temporary level converter we would have had to install both a pullup and series resistor. This is because the level converter holds the pin high unless pulled down by serial data to the LS2, and without it the LS2's serial input pin will float causing bad data to show up on the serail port. For the Kuro we used the 10K resistor that was installed as a pullup resistor as a series resistor with success, although I suspect anything between 1K and 10K would work.
I have read that in order to toggle the UART from the AVR to the serial console, since the LS2 only has one serial port, a jumper must be installed at J2. One side of J2 is tied to pin H4 of the IDT 79RC32H434 SOC. This pin is defined in one of the manuals on page 6 as U0SINP: Alternate function: UART channel 0 serial input, so that pretty much confirms that J2 is directly related to the serial port. We'll give this a shot once I have confirmed that the JTAG modification works. I don't want to make more than one change at a time for ttroubleshooting purposes.
Of course with the AVR not able to communicate with the processor (on boxes with a working AVR), it will be necessary to disable the watchdog before starting the LS2 or it will shutdown when the watchdog runs down. No problems there for me. This is where the red button on the rear of the LS2 will finally come in handy. Just hold it down while powering up the LS2 to disable the watchdog (AKA Christmas tree mode).
As it turns out, simply jumpering J2, bridging R186, and disabling the watchdog (or not) will allow two way communiction via the serial console. Of course, you do need to install a serial level converter at J1. I installed the J2 header on the back of the board so it can be accessed without removing the board from the chassis. Simply remove the side of the case and it can be accessed. Photos will be posted shortly.
Mini PCI Slot
It appears that all of the capacitors are decoupling capacitors. Based on the pin descriptions at http://www.interfacebus.com/MiniPCI_Pinout_124Pin.html they all bridge 3.3v to ground. I suspect anything in the .1uF range will work for these.
Also according to the standard, R238 and R239 enable and disable the 66Mhz PCI bus.
Install additional USB ports
The USB controller used is the same as the Kurobox and LS1. Additional ports can be added by following the instructions at http://www.kurobox.com/mwiki/index.php/Add_USB_Port#Additional_USB_Port_in_the_Rear. The USB controller is labeled IC7 and is installed on the back of the main board adjacent to the front USB plug. R86 thru R93 are pulldown resistors that have already been installed to keep those USB ports from floating. All that is necessary is the installation of two 36 ohm resistors and a USB plug for each additional port. Six resistors and 3 plugs would max out the USB controller with five working USB ports.
Other stuff I know
Install an LED at LED8 and a 330 ohm resistor at R268 (Both near the IDE connector pin 40) and It will turn on when a HDD read or write occurs.