Dual-boot ARM machineDual boot machines are usually thought as
single computer booting two OSes. Mine is different - it is
single OS (Linux 2.6.34 in this case) running on the same virtual CPU
emulated on two
different microcontrollers. You select your MCU by really hardware way
- by physically inserting particular device into its socket.
Recently I noticed this
project from Dmitri Grinberg. It is emulator of ARMv5TE class CPU
running on AtMega1284. After a bit problems with sourcing 16MB 30-pin
SIMM module I finally got one and tried his code. I designed my
breadbord work to include two MCUs actually - one is original Mega1284,
another one is place for 64-pin Microchip MCU. In fact, there could be
PIC32 or PIC24/dsPIC33, as they are pin compatible. I populated it with
PIC32MX795F512H, quite capable piece with MIPS core.
Using PIC32 to emulate ARM to run Linux is pure technical perversion, as PIC32 is itself capable of running BSD UNIX,
at least two orders of magnitude faster than this toy. However it is
nice academic excercise. You may try to run BSD UNIX on PIC32 emulated
on Linux host system running on ARM emulated on PIC32. Sounds like great fun for long winter evenings.
the emulator sources for PIC32 wasn't that difficult, main problem was rewriting
DRAM routines. Interesting is that DRAM requires standard TTL voltage
levels (2,4V as high level) on its inputs, however memory didn't accept 3,3V
levels from MCU. Using open-drain feature and 2,2kOhm pullups on all IO
pins solved this problem. Conversion from
memory to MCU (5V domain to 3,3V domain) was simple, as I used 5V
tolerant IO lines of PIC32.
original SD driver wasn't optimal. In order to simplify hardware he omitted CS
line, so part of initialization seqence tries to get to sync with state
machine in SD card by applying single clock pulse after every byte
while waiting for valid response. After this procedure, there is no
byte synchronization (usually ensured by CS signal), so noise can
bring communication down. It works, but I found it unreliable with
some SD cards or at higher clock speeds - anything above 2MHz failed,
sometimes after tens or hundreds of megabytes of succesfully
transferred data, sometimes after three sectors. That's why I replaced
original SD driver with the one from elm-chan's fatfs. After this, reading and writing SD cards works as expected with clock speed 20MHz.
original work expects AtMega1284 running at 24MHz (overclocking from
guaranteed 20MHz operation), however it refused to run correctly for me
despite correct bypassing and stable 5V power. I don't like violating
specifiactions, so I didn't try to figure what's wrong. Using 12MHz
crystal I had at hand fixed all problems, however it ran at half the
PIC32 version is - no surprise - much faster
than the AVR one. AVR emulator boots linux in 5'20 (five hours and
twenty minutes) at 12MHz, yielding 3'12 boot time at maximal 20MHz.
Response to simple commands is within minutes, ls command takes quarter
of hour. PIC version boots the same Linux build in 15 minutes at 80MHz,
with second Dmitri's SD image in 13 minutes, reply to simple commands
in seconds, what makes emulator somehow usable. Effective emulation
speed is cca 110kHz at 80MHz, compared to original 6,5kHz at 24MHz.
is quite simple - it comes from original schematics with a few changes.
I used LF33 regulator to get 3,3V for powering SD card, level
converting for SD card was done with 2,2/3,3kOhm reistors, LEDs got
330Ohm series resitors, not to mention decoupling capacitors on power
rails of SD card and AVR MCU.
this I connected PIC32. Address lines come
to port D, data lines to port E, WE is port F0, RAS F4 and CAS is F1.
All those lines are equipped with 2,2kOhm pull-ups to 5V. Yellow RED
for SD read activity is at port B1, red LED indicating write activity
is at B0. SD card is connected to SPI2 with CS line at port G9
(pull-down 22kOhm to keep compatibility with Dmitri's code). Serial
console at 115kbaud is on UART5. Button is at port F5. Device
expects 8MHz crystal, PLL is set to generate 80MHz internally. I'm too
lazy to draw schematics for now, everything needed can be tracked from
sources or from information above.
There is room for
improvements, like implementing multi-byte DRAM
access, like Dmitri did it in his second version that could bring serious performace increase. Fiddling with icache
values didn't help as much as I hoped for, differences were in order of
complete boot sequence. Interesting would be using modern SDRAMs
instead of 80's style DRAMs (getting 16MB SIMM-30 module for
appropriate price is really hard) or even SRAMs. More improvements can
be done on Linux side, however building light-weight one is out of my
knowledge by now. Volunteers are welcomed.
For download - sources for PIC32, boot log for AVR version and boot log for PIC32 version.
used MPLAB 8.84 as IDE for development, Microchip C32 1.12 as compiler,
all files were compiled with "-g -O3 -funroll-loops
-fomit-frame-pointer" options, except of main_p32.c file, with options
"-g -O2", linker set to 256B heap and 256B min. stack size. There is
binary file and also MPLAB project in package.
See the LINCENCE.txt and README.txt files.
More pictures in my picassa album.
Back to topics