adding bootloader03. another xmodem based bootloader, uses a state machine so should be a little

more tolerant of errors (which you shouldnt get anyway).
This commit is contained in:
David Welch
2012-05-28 10:47:35 -04:00
parent 0ad7724a06
commit b0ebc8d38b
9 changed files with 447 additions and 0 deletions

43
bootloader03/Makefile Normal file
View File

@@ -0,0 +1,43 @@
ARMGNU ?= arm-none-eabi
COPS = -Wall -O2 -nostdlib -nostartfiles -ffreestanding
all : kernel.img blinker.bin
clean :
rm -f *.o
rm -f *.bin
rm -f *.hex
rm -f *.elf
rm -f *.list
rm -f *.img
rm -f *.hex
vectors.o : vectors.s
$(ARMGNU)-as vectors.s -o vectors.o
bootloader03.o : bootloader03.c
$(ARMGNU)-gcc $(COPS) -c bootloader03.c -o bootloader03.o
kernel.img : loader vectors.o bootloader03.o
$(ARMGNU)-ld vectors.o bootloader03.o -T loader -o bootloader03.elf
$(ARMGNU)-objdump -D bootloader03.elf > bootloader03.list
$(ARMGNU)-objcopy bootloader03.elf -O ihex bootloader03.hex
$(ARMGNU)-objcopy bootloader03.elf -O binary kernel.img
start.o : start.s
$(ARMGNU)-as start.s -o start.o
blinker.o : blinker.c
$(ARMGNU)-gcc $(COPS) -c blinker.c -o blinker.o
blinker.bin : memmap start.o blinker.o
$(ARMGNU)-ld start.o blinker.o -T memmap -o blinker.elf
$(ARMGNU)-objdump -D blinker.elf > blinker.list
$(ARMGNU)-objcopy blinker.elf -O ihex blinker.hex
$(ARMGNU)-objcopy blinker.elf -O binary blinker.bin

32
bootloader03/README Normal file
View File

@@ -0,0 +1,32 @@
See the top level README for information on where to find the
schematic and programmers reference manual for the ARM processor
on the raspberry pi. Also find information on how to load and run
these programs.
Derived from bootloader02, this is a very simple bootloader. Instead
of the sd dance (see toplevel README), this makes life a bit simpler
and greatly reduces physical wear and tear on the sd card socket. Do
the sd card dance one time with kernel.img. Get some sort of serial
solution to connect a dumb termial program (minicom, hyperterm, etc)
with xmodem capabilities to the uart on the raspberry pi. (see toplevel
README)
The difference between bootloader02 and bootloader03 is that this one
uses a state machine for xmodem, maybe it will recover from a lost byte
if there is ever one. You take the .bin file of your test program,
assumed to be built based on address 0 and less than 0x200000 bytes.
With uart connected to a terminal
1) power off raspberry pi
2) power on raspberry pi
3) use xmodem to transfer binary file
Repeat for each new program to test
This bootloader sits at 0x200000 so that you have 0x200000 bytes to
develop with. And that way if you like your program you can just
copy a .bin version to kernel.img on the sd card and use it. Fairly
easy to change this address. bootloader03.c and vectors.s each have
a copy of this value.
bootloader01 uses .hex files, bootloader02 and bootloader03 use .bin
files, .hex files wont work.

57
bootloader03/blinker.c Normal file
View File

@@ -0,0 +1,57 @@
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
extern void PUT32 ( unsigned int, unsigned int );
extern unsigned int GET32 ( unsigned int );
extern void dummy ( unsigned int );
#define ARM_TIMER_LOD 0x2000B400
#define ARM_TIMER_VAL 0x2000B404
#define ARM_TIMER_CTL 0x2000B408
#define ARM_TIMER_DIV 0x2000B41C
#define ARM_TIMER_CNT 0x2000B420
#define SYSTIMERCLO 0x20003004
#define GPFSEL1 0x20200004
#define GPSET0 0x2020001C
#define GPCLR0 0x20200028
#define TIMEOUT 1000000
//-------------------------------------------------------------------------
int notmain ( void )
{
unsigned int ra;
unsigned int rb;
ra=GET32(GPFSEL1);
ra&=~(7<<18);
ra|=1<<18;
PUT32(GPFSEL1,ra);
PUT32(ARM_TIMER_CTL,0x00F90000);
PUT32(ARM_TIMER_CTL,0x00F90200);
rb=GET32(ARM_TIMER_CNT);
while(1)
{
PUT32(GPSET0,1<<16);
while(1)
{
ra=GET32(ARM_TIMER_CNT);
if((ra-rb)>=TIMEOUT) break;
}
rb+=TIMEOUT;
PUT32(GPCLR0,1<<16);
while(1)
{
ra=GET32(ARM_TIMER_CNT);
if((ra-rb)>=TIMEOUT) break;
}
rb+=TIMEOUT;
}
return(0);
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------

232
bootloader03/bootloader03.c Normal file
View File

@@ -0,0 +1,232 @@
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
extern void PUT32 ( unsigned int, unsigned int );
extern void PUT16 ( unsigned int, unsigned int );
extern void PUT8 ( unsigned int, unsigned int );
extern unsigned int GET32 ( unsigned int );
extern void BRANCHTO ( unsigned int );
extern void dummy ( unsigned int );
#define ARM_TIMER_CTL 0x2000B408
#define ARM_TIMER_CNT 0x2000B420
#define GPFSEL1 0x20200004
#define GPSET0 0x2020001C
#define GPCLR0 0x20200028
#define GPPUD 0x20200094
#define GPPUDCLK0 0x20200098
#define AUX_ENABLES 0x20215004
#define AUX_MU_IO_REG 0x20215040
#define AUX_MU_IER_REG 0x20215044
#define AUX_MU_IIR_REG 0x20215048
#define AUX_MU_LCR_REG 0x2021504C
#define AUX_MU_MCR_REG 0x20215050
#define AUX_MU_LSR_REG 0x20215054
#define AUX_MU_MSR_REG 0x20215058
#define AUX_MU_SCRATCH 0x2021505C
#define AUX_MU_CNTL_REG 0x20215060
#define AUX_MU_STAT_REG 0x20215064
#define AUX_MU_BAUD_REG 0x20215068
//GPIO14 TXD0 and TXD1
//GPIO15 RXD0 and RXD1
//------------------------------------------------------------------------
unsigned int uart_recv ( void )
{
while(1)
{
if(GET32(AUX_MU_LSR_REG)&0x01) break;
}
return(GET32(AUX_MU_IO_REG)&0xFF);
}
//------------------------------------------------------------------------
void uart_send ( unsigned int c )
{
while(1)
{
if(GET32(AUX_MU_LSR_REG)&0x20) break;
}
PUT32(AUX_MU_IO_REG,c);
}
//------------------------------------------------------------------------
void hexstrings ( unsigned int d )
{
//unsigned int ra;
unsigned int rb;
unsigned int rc;
rb=32;
while(1)
{
rb-=4;
rc=(d>>rb)&0xF;
if(rc>9) rc+=0x37; else rc+=0x30;
uart_send(rc);
if(rb==0) break;
}
uart_send(0x20);
}
//------------------------------------------------------------------------
void hexstring ( unsigned int d )
{
hexstrings(d);
uart_send(0x0D);
uart_send(0x0A);
}
//------------------------------------------------------------------------
unsigned char xstring[256];
//------------------------------------------------------------------------
int notmain ( void )
{
unsigned int ra;
//unsigned int rb;
unsigned int rx;
unsigned int addr;
unsigned int block;
unsigned int state;
unsigned int crc;
PUT32(AUX_ENABLES,1);
PUT32(AUX_MU_IER_REG,0);
PUT32(AUX_MU_CNTL_REG,0);
PUT32(AUX_MU_LCR_REG,3);
PUT32(AUX_MU_MCR_REG,0);
PUT32(AUX_MU_IER_REG,0);
PUT32(AUX_MU_IIR_REG,0xC6);
PUT32(AUX_MU_BAUD_REG,270);
ra=GET32(GPFSEL1);
ra&=~(7<<12); //gpio14
ra|=2<<12; //alt5
ra&=~(7<<15); //gpio15
ra|=2<<15; //alt5
PUT32(GPFSEL1,ra);
PUT32(GPPUD,0);
for(ra=0;ra<150;ra++) dummy(ra);
PUT32(GPPUDCLK0,(1<<14)|(1<<15));
for(ra=0;ra<150;ra++) dummy(ra);
PUT32(GPPUDCLK0,0);
PUT32(AUX_MU_CNTL_REG,3);
PUT32(ARM_TIMER_CTL,0x00F90000);
PUT32(ARM_TIMER_CTL,0x00F90200);
hexstring(0x12345678);
//SOH 0x01
//ACK 0x06
//NAK 0x15
//EOT 0x04
//block numbers start with 1
//132 byte packet
//starts with SOH
//block number byte
//255-block number
//128 bytes of data
//checksum byte (whole packet)
//a single EOT instead of SOH when done, send an ACK on it too
block=1;
addr=0;
state=0;
rx=GET32(ARM_TIMER_CNT);
while(1)
{
ra=GET32(ARM_TIMER_CNT);
if((ra-rx)>=4000000)
{
uart_send(0x15);
rx+=4000000;
}
if((GET32(AUX_MU_LSR_REG)&0x01)==0) continue;
xstring[state]=GET32(AUX_MU_IO_REG)&0xFF;
rx=GET32(ARM_TIMER_CNT);
if(state==0)
{
if(xstring[state]==0x04)
{
uart_send(0x06);
BRANCHTO(0);
break;
}
}
switch(state)
{
case 0:
{
if(xstring[state]==0x01)
{
crc=xstring[state];
state++;
}
else
{
//state=0;
uart_send(0x15);
}
break;
}
case 1:
{
if(xstring[state]==block)
{
crc+=xstring[state];
state++;
}
else
{
state=0;
uart_send(0x15);
}
break;
}
case 2:
{
if(xstring[state]==(0xFF-xstring[state-1]))
{
crc+=xstring[state];
state++;
}
else
{
uart_send(0x15);
state=0;
}
break;
}
case 131:
{
crc&=0xFF;
if(xstring[state]==crc)
{
for(ra=0;ra<128;ra++)
{
PUT8(addr++,xstring[ra+3]);
}
uart_send(0x06);
block=(block+1)&0xFF;
}
else
{
uart_send(0x15);
}
state=0;
break;
}
default:
{
crc+=xstring[state];
state++;
break;
}
}
}
return(0);
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------

BIN
bootloader03/kernel.img Executable file

Binary file not shown.

12
bootloader03/loader Normal file
View File

@@ -0,0 +1,12 @@
MEMORY
{
ram : ORIGIN = 0x00000000, LENGTH = 0x10000000
}
SECTIONS
{
.text : { *(.text*) } > ram
.bss : { *(.bss*) } > ram
}

12
bootloader03/memmap Normal file
View File

@@ -0,0 +1,12 @@
MEMORY
{
ram : ORIGIN = 0x00000000, LENGTH = 0x200000
}
SECTIONS
{
.text : { *(.text*) } > ram
.bss : { *(.bss*) } > ram
}

19
bootloader03/start.s Normal file
View File

@@ -0,0 +1,19 @@
.globl _start
_start:
bl notmain
hang: b hang
.globl PUT32
PUT32:
str r1,[r0]
bx lr
.globl GET32
GET32:
ldr r0,[r0]
bx lr
.globl dummy
dummy:
bx lr

40
bootloader03/vectors.s Normal file
View File

@@ -0,0 +1,40 @@
.globl _start
_start:
b reset
.space 0x200000-4,0
reset:
mov sp,#0x10000000
bl notmain
hang: b hang
.globl PUT32
PUT32:
str r1,[r0]
bx lr
.globl PUT16
PUT16:
strh r1,[r0]
bx lr
.globl PUT8
PUT8:
strb r1,[r0]
bx lr
.globl GET32
GET32:
ldr r0,[r0]
bx lr
.globl BRANCHTO
BRANCHTO:
bx r0
.globl dummy
dummy:
bx lr