Skip to content

Commit

Permalink
adding bootloader02, this is xmodem based.
Browse files Browse the repository at this point in the history
  • Loading branch information
dwelch67 committed May 28, 2012
1 parent caf3559 commit 0ad7724
Show file tree
Hide file tree
Showing 10 changed files with 405 additions and 4 deletions.
9 changes: 5 additions & 4 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,10 @@ parity, 1 stop bit. NO flow control. With minicom you likely have
to save the config, exit minicom, then restart in order for flow control
changes to take effect.

going to work on a terminal based bootloder with xmodem, instead of the
proprietary solution in bootloader01.

I recommend you start with blinker01 and follow the discovery through
those to uart01, etc. If you dont have a bootloader, do the sd card
dance with the .bin file. If you have a bootloader use the .hex file.
dance with the .bin file.

bootloader01 uses the .hex file from the examples and prograspi program
bootloader02 uses the .bin file from the examples and xmodem from a
terminal program
43 changes: 43 additions & 0 deletions bootloader02/Makefile
Original file line number Diff line number Diff line change
@@ -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

novectors.o : novectors.s
$(ARMGNU)-as novectors.s -o novectors.o

bootloader02.o : bootloader02.c
$(ARMGNU)-gcc $(COPS) -c bootloader02.c -o bootloader02.o

kernel.img : loader novectors.o bootloader02.o
$(ARMGNU)-ld novectors.o bootloader02.o -T loader -o bootloader02.elf
$(ARMGNU)-objdump -D bootloader02.elf > bootloader02.list
$(ARMGNU)-objcopy bootloader02.elf -O ihex bootloader02.hex
$(ARMGNU)-objcopy bootloader02.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


25 changes: 25 additions & 0 deletions bootloader02/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

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 uart02, 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) to the uart on
the raspberry pi. (see toplevel README)

The difference between bootloader01 and bootloader02 is that this one
uses xmodem. So you take the .bin file of your test program, assumed
to be built based on address 0 and less than 0x200000 bytes.

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. bootloader02.c and novectors.s each have
a copy of this value.

bootloader01 uses .hex files, bootloader02 uses .bin files dont send it
.hex files, wont work.
57 changes: 57 additions & 0 deletions bootloader02/blinker.c
Original file line number Diff line number Diff line change
@@ -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);
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
192 changes: 192 additions & 0 deletions bootloader02/bootloader02.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@

//-------------------------------------------------------------------------
//-------------------------------------------------------------------------

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 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


//this is a very crude solution, worked for a small test program though
//if it slips one byte it is all over. Need to make a more robust
//solution.

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) break;
}
block=1;
addr=0;
while(1)
{
xstring[0]=uart_recv();
if(xstring[0]==0x04)
{
uart_send(0x06);
break;
}
if(xstring[0]!=0x01) break;
crc=0x01;
for(ra=1;ra<132;ra++)
{
xstring[ra]=uart_recv();
crc+=xstring[ra];
}
if(xstring[2]!=(255-xstring[1])) break;
crc-=xstring[131];
crc&=0xFF;
if(xstring[131]!=crc)
{
uart_send(0x15);
}
for(ra=0;ra<128;ra++)
{
PUT8(addr++,xstring[ra+3]);
}
if(addr>0x200000)
{
uart_send(0x15);
break;
}
uart_send(0x06);
block=(block+1)&0xFF;
}
if(xstring[0]==0x04)
{
BRANCHTO(0);
}
return(0);
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
Binary file added bootloader02/kernel.img
Binary file not shown.
12 changes: 12 additions & 0 deletions bootloader02/loader
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

MEMORY
{
ram : ORIGIN = 0x00000000, LENGTH = 0x10000000
}

SECTIONS
{
.text : { *(.text*) } > ram
.bss : { *(.bss*) } > ram
}

12 changes: 12 additions & 0 deletions bootloader02/memmap
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

MEMORY
{
ram : ORIGIN = 0x00000000, LENGTH = 0x200000
}

SECTIONS
{
.text : { *(.text*) } > ram
.bss : { *(.bss*) } > ram
}

Loading

0 comments on commit 0ad7724

Please sign in to comment.