Bootloader

From NaWiki
Revision as of 03:43, 4 July 2007 by PrcY1v (talk | contribs)
Jump to: navigation, search

diazepam online cheap tramadol wellbutrin online free jazz ringtones rivotril online free mtv ringtones lipitor online cheap celexa cheap ativan nokia ringtones norco online motorola ringtones but ultram cheap ultram norco mono ringtones celexa online buy didrex online pharmacy propecia online cheap phentermine viagra online cheap vicodin cheap sildenafil cheap lisinopril free sharp ringtones levitra online funny ringtones but hydrocodone valium cool ringtones clonazepam online cyclobenzaprine online free verizon ringtones buy hgh ambien online sony ringtones cheap cialis free cingular ringtones cheap cialis prozac online free qwest ringtones didrex online punk ringtones free jazz ringtones free free ringtones but ultracet order flexeril free nokia ringtones ativan online cheap viagra midi ringtones free sony ericsson ringtones free real ringtones adipex online free funny ringtones free punk ringtones cheap tenuate meridia kyocera ringtones sprint ringtones meridia online order tenuate cheap clomid cheap ambien sonyericsson ringtones cheap clomid free music ringtones free ericsson ringtones cheap levitra free wwe ringtones free kyocera ringtones cheap nexium free mp3 ringtones cheap hgh xanax online free sagem ringtones cheap xenical cheap alprazolam music ringtones buy zanaflex free verizon ringtones nextel ringtones free tracfone ringtones diethylpropion online cheap albuterol tramadol online samsung ringtones mp3 ringtones free wwe ringtones soma online sharp ringtones order lisinopril paxil online motorola ringtones free samsung ringtones vigrx sildenafil online buy paxil zanaflex online cheap rivotril diethylpropion online sprint ringtones free polyphonic ringtones free sagem ringtones cheap nexium free cingular ringtones cheap cyclobenzaprine cheap pharmacy online free alltel ringtones free sonyericsson ringtones free sony ericsson ringtones diazepam online online vicodin lipitor online cheap vigrx free mtv ringtones soma online buy lorazepam real ringtones zyban online buy albuterol free ericsson ringtones lorazepam online cheap zoloft but adipex wellbutrin online alltel ringtones free cool ringtones nextel ringtones online zoloft clonazepam online valium online fioricet online free midi ringtones xanax online free polyphonic ringtones hoodia online lortab alprazolam online hydrocodone online lortab online ultracet online free ringtones mono ringtones cheap carisoprodol free sony ringtones ortho online free tracfone ringtones but phentermine cheap ortho xenical online order prozac carisoprodol online propecia online but flexeril qwest ringtones buy fioricet cheap hoodia zyban online == Overview ==

DSerial Flash Memory Map

DSerial bootloader is the program that is the first to run once the C8051F320 microcontroller is powered. It responds to commands from DS on the SPI port and allows to boot DSerial firmware amongst other things.

Description

The purpose of DSerial bootloader is to:

  • Boot DSerial firmware
  • Write firmware to internal flash via SPI (other ports may be supported by the bootloader in the future)
  • Read internal flash
  • Send and receive UART data without booting into firmware (baud rate fixed at 115200 bps)

The following sections will describe how the bootloader functions.

Files

Go to downloads to get the bootloader source code.

Detecting DSerial

Check whether DSerial is inserted using a SPI Flash compatible command:

  1. DS sends the byte 0x9F (RDID)
  2. DSerial responds with 0x01 0xAB


This is command is non-destructive to DS game cards. See also DSerial protocol.

Interrupt Vector Table (Currently Used Method)

Interrupt vector table on the C8051F320 is always at offset 0 in FLASH. Unfortunately, we cannot re-target it from bootloader interrupt vector table into the program interrupt vector table with a magic register, since no such register exists in the architecture. Instead, we have to re-target each interrupt separately.

The User Bit in PSW register (also called F1) is used to select bootloader table or firmware table.

<cpp> // Code in bootloader, interrupt.h

/* UART0 interrupt */ void redirS0() __interrupt (4) _naked { _asm push psw jnb psw.1, 00001$ ; if user bit not set, jump to firmware irq

pop psw lcall _uartInterrupt ; otherwise jump to bootloader irq reti

00001$: pop psw ljmp #FIRMWARE_OFFSET IRQ_S0 ; firmware irq _endasm; }

// repeat for the other irqs </cpp>

This code jumps to bootloader interrupt if PSW.1 (also called F1) is set to 1, otherwise it jumps to firmware.

<cpp> // Code in bootloader

void main() { // ... F1 = 1; // relocate interrupts to bootloader EA = 1; // global interrupt enable // ... } </cpp>

<cpp> // Code in firmware

void main() { // ... F1 = 0; // relocate interrupts to FIRMWARE_OFFSET (0x0800) EA = 1; // global interrupt enable // ... } </cpp>

Interrupt Vector Table (Not Used Method)

The following code shows another way that could have been used. It's advantage is that the interrupt vector can be relocated to any address dynamically. The disadvantage is that there's bigger overhead.

<cpp> // Code in bootloader

// Redirects UART IRQ either into our (bootloader's) handler or into firmware handler. void R_uartInterrupt() __interrupt (4) _naked { _asm mov a, _IrqVector ; compare IrqVector to 0 jnz 00001$ mov a, (_IrqVector 1) jz 00002$ 00001$: ; if not 0, then we need to jump to it mov dpl, _IrqVector mov dph, (_IrqVector 1) mov a, #0x23 ; this is the offset for uart irq jmp @a dptr ; call the interrupt handler in firmware 00002$: ; if it's 0, then we'll handle the irq lcall _uartInterrupt ; call our own interrupt handler reti _endasm; }

// repeat for the other irqs </cpp>

IrqVector is a global variable that is set to the location of interrupt vector before enabling interrupts. The bootloader should set IrqVector to 0 while the program should set it to it's location.

<cpp> // Code in firmware

__data __at (0x7e) unsigned int IrqVector;

void main() { // ... IrqVector = 0x0800; // we're relocated to 0x0800 EA = 1; // global interrupt enable // ... } </cpp>