sigh, I have a bootloader working!

This commit is contained in:
David Welch
2012-05-27 02:31:05 -04:00
parent d69e19201f
commit c44c1146ea
11 changed files with 931 additions and 0 deletions

46
bootloader01/Makefile Normal file
View File

@@ -0,0 +1,46 @@
ARMGNU ?= arm-none-eabi
COPS = -Wall -O2 -nostdlib -nostartfiles -ffreestanding
all : kernel.img blinker.hex prograspi
clean :
rm -f *.o
rm -f *.bin
rm -f *.elf
rm -f *.list
rm -f *.img
rm -f *.hex
rm -f prograspi
novectors.o : novectors.s
$(ARMGNU)-as novectors.s -o novectors.o
bootloader01.o : bootloader01.c
$(ARMGNU)-gcc $(COPS) -c bootloader01.c -o bootloader01.o
kernel.img : loader novectors.o bootloader01.o
$(ARMGNU)-ld novectors.o bootloader01.o -T loader -o bootloader01.elf
$(ARMGNU)-objdump -D bootloader01.elf > bootloader01.list
$(ARMGNU)-objcopy bootloader01.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.hex : 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 binary blinker.bin
$(ARMGNU)-objcopy blinker.elf -O ihex blinker.hex
prograspi : prograspi.c ser.c ser.h
gcc -O2 -Wall prograspi.c ser.c -o prograspi

52
bootloader01/README Normal file
View File

@@ -0,0 +1,52 @@
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.
Derived from uart02 and code of various ages (yes some from 1996), this
is a very simple bootloader. Instead of removing, writing, and replcing
the sd card numerous times. This makes that a bit simpler. Using the
uart on the card and some sort of uart on the host (see below) you only
need to load the bootloader (kernel.img derived from bootloader01.elf)
one time. From then on just power cycle the raspberry pi and use the
host loader program (prograspi) to load and start the program under
development on the raspberry pi.
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. I had
the bootloader closer to 0x0000000 and test programs would be after it
but that means to make a real program for the sd card would be another
link step. Very easy to change this, both bootloader01.c and prograspi.c
use the same number 0x200000.
On the host you will want to use something like this:
http://www.sparkfun.com/products/718
to connect to the uart pins on the raspi. Do not connect the raspberry
pi pins directly to a com port on a computer you will fry the board.
The above board happens to have pins in the same order as the raspberry
pi. On connector P1 on the raspberry pi connect pin 6 to ground on the
usb to serial board. Pin 8 on P1 to RX on the usb to serial board, and
pin 10 on P1 to TX on the usb to serial board. I use these
http://www.sparkfun.com/products/8430
to connect the ftdi board to the raspberry pi. No soldering required,
at least not at the moment. If down the road the raspberri pi does
not have P1 header pins then there will be some soldering or something
required.
You do not use a dumb terminal program. The program on the host
that loads your ARM program is called prograspi. There is a test
program derived from blinker03 called blinker. Once you have copied
kernel.img to the sd card on the raspberry pi. You have hooked up
the usb to serial board to the raspberry pi. Plug the usb into
the usb to serial board and use dmesg to note the /dev/ttyUSBX port.
Plug in the raspberry pi to power it and then run:
./prograspi blinker.hex /dev/ttyUSBX
where /dev/ttyUSBX is the port you are connecting through, it could
be a real serial port if you have a tranciever for the raspberry pi
side. (MAX232 for example).
Now you can go back and try my other examples without the dozens/hundreds
of sd card insertions it took me to get to this point.

57
bootloader01/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);
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------

257
bootloader01/bootloader01.c Normal file
View File

@@ -0,0 +1,257 @@
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
extern void PUT32 ( unsigned int, unsigned int );
extern void PUT16 ( unsigned int, unsigned int );
extern unsigned int GET32 ( unsigned int );
extern void BRANCHTO ( unsigned int );
extern void dummy ( unsigned int );
#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);
}
//------------------------------------------------------------------------
// Packet Format
// [0] 0x7C start sync
// [1] datalen
// [2] ~datalen
// datalen bytes:
// [3] type
// [4] sequence
// [5] pass=0/fail!=0
// [6]
// [7]
// [8] payload starts
// ...
// datalen ends
// [n-2] 0x7D end sync
// [n-1] checksum
//------------------------------------------------------------------------
unsigned char xstring[512];
//------------------------------------------------------------------------
int recv_packet ( void )
{
unsigned int len;
unsigned int ra;
unsigned int rb;
unsigned int rc;
while(1)
{
ra=uart_recv();
if(ra!=0x7C)
{
continue;
}
ra=0;
xstring[ra++]=0x7C; //sync
xstring[ra++]=uart_recv(); //datalen
xstring[ra++]=uart_recv(); //~datalen
if(xstring[ra-2]!=(~xstring[ra-1]&0xFF))
{
continue;
}
len=xstring[ra-2];
while(len--) xstring[ra++]=uart_recv();
xstring[ra++]=uart_recv(); //sync
xstring[ra++]=uart_recv(); //checksum
if(xstring[ra-2]!=0x7D)
{
continue;
}
for(rb=0,rc=0x00;rb<ra;rb++) rc+=xstring[rb];
rc&=0xFF;
if(rc==0xFF) break;
}
return(0);
}
//------------------------------------------------------------------------
int send_result ( unsigned char res )
{
unsigned int ra;
unsigned int rb;
unsigned int rc;
ra=0;
xstring[ra++]=0x7C; //xstring[ra++]=0x7C; //sync
xstring[ra++]=0x05; //xstring[ra++]=uart_recv(); //datalen
xstring[ra++]=~0x05;//xstring[ra++]=uart_recv(); //~datalen
//datalen:
ra++; //same as input
ra++; //same as input
xstring[ra++]=res;
xstring[ra++]=0;
xstring[ra++]=0;
//datalen
xstring[ra++]=0x7D;
for(rb=0,rc=0;rb<ra;rb++) rc+=xstring[rb];
xstring[ra++]=(~rc)&0xFF;
for(rb=0;rb<ra;rb++) uart_send(xstring[rb]);
return(0);
}
//------------------------------------------------------------------------
int notmain ( void )
{
unsigned int ra;
unsigned int len;
unsigned int addr;
unsigned int data;
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);
hexstring(0x12345678);
while(1)
{
if(recv_packet()) break;
switch(xstring[3])
{
case 0x07: //write to ram
{
//validate len
len=xstring[1];
if(len<(5+4+2))
{
send_result(1);
break;
}
if((len-5-4-2)&1)
{
send_result(1);
break;
}
//[5,6,7,8,9] packet header
//[8,9,10,11] address
//[12,13] first halfword
//[14,15] second halfword
ra=8;
addr=0;
addr<<=8; addr|=xstring[ra++];
addr<<=8; addr|=xstring[ra++];
addr<<=8; addr|=xstring[ra++];
addr<<=8; addr|=xstring[ra++];
len-=5+4;
while(len)
{
data=0;
data<<=8; data|=xstring[ra++];
data<<=8; data|=xstring[ra++];
PUT16(addr,data);
addr+=2;
len-=2;
}
send_result(0);
break;
}
case 0x08: //branch to address
{
//validate len
len=xstring[1];
if(len!=(5+4))
{
send_result(1);
break;
}
//[5,6,7,8,9] packet header
//[8,9,10,11] address
ra=8;
addr=0;
addr<<=8; addr|=xstring[ra++];
addr<<=8; addr|=xstring[ra++];
addr<<=8; addr|=xstring[ra++];
addr<<=8; addr|=xstring[ra++];
send_result(0);
BRANCHTO(addr);
break;
}
}
}
return(0);
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------

12
bootloader01/loader Normal file
View File

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

12
bootloader01/memmap Normal file
View File

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

35
bootloader01/novectors.s Normal file
View File

@@ -0,0 +1,35 @@
.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 GET32
GET32:
ldr r0,[r0]
bx lr
.globl BRANCHTO
BRANCHTO:
bx r0
.globl dummy
dummy:
bx lr

317
bootloader01/prograspi.c Normal file
View File

@@ -0,0 +1,317 @@
//-----------------------------------------------------------------------------
// Copyright (C) David Welch, 2000, 2003, 2008, 2009, 2012
//-----------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
FILE *fp;
#include "ser.h"
unsigned int seq;
unsigned int ra,rb,rc,rd;
unsigned int addr;
unsigned int firstaddr;
unsigned char data[128];
unsigned char sdata[512];
unsigned char rdata[5000];
//-----------------------------------------------------------------------------
int check_packet ( void )
{
unsigned int ra;
unsigned int rb;
unsigned int rc;
if(rdata[0]!=0x7C) return(2);
if(rdata[1]!=(~rdata[2]&0xFF)) return(2);
if(rdata[3]!=sdata[3]) return(2);
if(rdata[4]!=sdata[4]) return(2);
if(rdata[3+rdata[1]]!=0x7D) return(2);
ra=3;
ra=rdata[1]+5;
for(rb=0,rc=0;rb<ra;rb++) rc+=rdata[rb];
rc&=0xFF;
if(rc!=0xFF) return(2);
return(rdata[5]);
}
//-----------------------------------------------------------------------------
int raspload ( unsigned int addr, unsigned int data )
{
unsigned int ra;
unsigned int rb;
unsigned int rc;
unsigned int rd;
//printf("load 0x%08X, 0x%04X\n",addr,data);
if(firstaddr==0xFFFFFFFF) firstaddr=addr;
ra=0;
sdata[ra++]=0x7C;
sdata[ra++]=2+5+4;
sdata[ra]=~sdata[ra-1]; ra++;
//
sdata[ra++]=0x07;
sdata[ra++]=seq&0xFF; seq++;
sdata[ra++]=0;
sdata[ra++]=0;
sdata[ra++]=0;
sdata[ra++]=(addr>>24)&0xFF;
sdata[ra++]=(addr>>16)&0xFF;
sdata[ra++]=(addr>> 8)&0xFF;
sdata[ra++]=(addr>> 0)&0xFF;
// for(rd=0;rd<rb;rd+=2)
{
sdata[ra++]=(data>>8)&0xFF;
sdata[ra++]=(data>>0)&0xFF;
}
//
sdata[ra++]=0x7D;
for(rd=0,rc=0;rd<ra;rd++) rc+=sdata[rd];
sdata[ra++]=(~rc)&0xFF;
//for(rd=0;rd<ra;rd++) printf("%02X ",sdata[rd]); printf("\n");
//for(rd=0,rc=0x00;rd<ra;rd++) rc+=sdata[rd];
//rc&=0xFF;
ser_senddata(sdata,ra);
rb=0;
rc=0;
while(1)
{
rb=ser_copystring(rdata);
//if(rb!=rc) printf("%u\n",rb);
rc=rb;
if(rb==10)
{
//for(ra=0;ra<rb;ra++) printf("%02X ",rdata[ra]); printf("\n");
ra=check_packet();
if(ra) return(1);
ser_dump(rc);
break;
}
}
return(0);
}
//-----------------------------------------------------------------------------
int readhex ( FILE *fp )
{
char gstring[80];
char newline[1024];
unsigned char hexline[1024];
//intimately tied to the .balign value in the bootloader startup
#define RAMMASK 0x1FFFFF
unsigned int addhigh;
unsigned int add;
unsigned int data;
unsigned int ra;
unsigned int line;
unsigned char checksum;
unsigned int len;
unsigned int maxadd;
unsigned char t;
maxadd=0;
addhigh=0;
line=0;
while(fgets(newline,sizeof(newline)-1,fp))
{
line++;
//printf("%s",newline);
if(newline[0]!=':')
{
printf("Syntax error <%u> no colon\n",line);
continue;
}
gstring[0]=newline[1];
gstring[1]=newline[2];
gstring[2]=0;
len=strtoul(gstring,NULL,16);
for(ra=0;ra<(len+5);ra++)
{
gstring[0]=newline[(ra<<1)+1];
gstring[1]=newline[(ra<<1)+2];
gstring[2]=0;
hexline[ra]=(unsigned char)strtoul(gstring,NULL,16);
}
checksum=0;
for(ra=0;ra<(len+5);ra++) checksum+=hexline[ra];
//checksum&=0xFF;
if(checksum)
{
printf("checksum error <%u>\n",line);
}
add=hexline[1]; add<<=8;
add|=hexline[2];
add|=addhigh;
if(add>RAMMASK)
{
printf("address too big 0x%08X\n",add);
//return(1);
continue;
}
if(add&3)
{
printf("bad address 0x%08X\n",add);
return(1);
}
t=hexline[3];
if(t!=0x02)
{
if(len&3)
{
printf("bad length\n");
return(1);
}
}
//:0011223344
//;llaaaattdddddd
//01234567890
switch(t)
{
default:
printf("UNKNOWN type %02X <%u>\n",t,line);
break;
case 0x00:
for(ra=0;ra<len;ra+=4)
{
if(add>RAMMASK)
{
printf("address too big 0x%08X\n",add);
break;
}
data= hexline[ra+4+1];
data<<=8; data|=hexline[ra+4+0];
if(raspload(add,data)) return(1);
add+=2;
data= hexline[ra+4+3];
data<<=8; data|=hexline[ra+4+2];
if(raspload(add,data)) return(1);
add+=2;
if(add>maxadd) maxadd=add;
}
break;
case 0x01:
// printf("End of data\n");
break;
case 0x02:
addhigh=hexline[5];
addhigh<<=8;
addhigh|=hexline[4];
addhigh<<=16;
break;
case 0x03:
data= hexline[4+0];
data<<=8; data|=hexline[4+1];
data<<=8; data|=hexline[4+2];
data<<=8; data|=hexline[4+3];
printf("TYPE 3 0x%08X\n",data);
break;
}
}
//printf("%u lines processed\n",line);
//printf("%08X\n",maxadd);
//for(ra=0;ra<maxadd;ra+=4)
//{
//printf("0x%08X: 0x%08X\n",ra,ram[ra>>2]);
//}
return(0);
}
//-----------------------------------------------------------------------------
int main ( int argc, char *argv[] )
{
unsigned int ra;
//unsigned int rb;
unsigned int rc;
if(argc<3)
{
printf("prograspi filename.hex /dev/ttyXYZ\n");
return(1);
}
fp=fopen(argv[1],"rt");
if(fp==NULL)
{
printf("Error opening file [%s]\n",argv[1]);
return(1);
}
printf("file opened\n");
if(ser_open(argv[2]))
{
printf("ser_open() failed\n");
return(1);
}
printf("port opened\n");
seq=17;
firstaddr=0xFFFFFFFF;
if(readhex(fp))
{
return(1);
}
printf("Entry point: 0x%08X\n",firstaddr);
ra=0;
sdata[ra++]=0x7C;
sdata[ra++]=5+4;
sdata[ra]=~sdata[ra-1]; ra++;
//
sdata[ra++]=0x08;
sdata[ra++]=seq&0xFF; seq++;
sdata[ra++]=0;
sdata[ra++]=0;
sdata[ra++]=0;
sdata[ra++]=(firstaddr>>24)&0xFF;
sdata[ra++]=(firstaddr>>16)&0xFF;
sdata[ra++]=(firstaddr>> 8)&0xFF;
sdata[ra++]=(firstaddr>> 0)&0xFF;
//
sdata[ra++]=0x7D;
for(rd=0,rc=0;rd<ra;rd++) rc+=sdata[rd];
sdata[ra++]=(~rc)&0xFF;
//for(rd=0;rd<ra;rd++) printf("%02X ",sdata[rd]); printf("\n");
for(rd=0,rc=0x00;rd<ra;rd++) rc+=sdata[rd];
rc&=0xFF;
ser_senddata(sdata,ra);
ser_close();
printf("\n\n");
return(0);
}
//-----------------------------------------------------------------------------
// Copyright (C) David Welch, 2000, 2003, 2008, 2009, 2012
//-----------------------------------------------------------------------------

106
bootloader01/ser.c Normal file
View File

@@ -0,0 +1,106 @@
//-----------------------------------------------------------------------------
// Copyright (C) David Welch, 2000
//-----------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <time.h>
int ser_hand;
unsigned short ser_buffcnt;
unsigned short ser_maincnt;
unsigned char ser_buffer[(0xFFF+1)<<1];
//-----------------------------------------------------------------------------
unsigned char ser_open ( char *devname )
{
struct termios options;
ser_hand=open(devname,O_RDWR|O_NOCTTY|O_NDELAY);
if(ser_hand==-1)
{
fprintf(stderr,"ser_open: error - %s\n",strerror(errno));
return(1);
}
fcntl(ser_hand,F_SETFL,FNDELAY);
bzero(&options,sizeof(options));
options.c_cflag=B115200|CS8|CLOCAL|CREAD;
options.c_iflag=IGNPAR;
tcflush(ser_hand,TCIFLUSH);
tcsetattr(ser_hand,TCSANOW,&options);
ser_maincnt=ser_buffcnt=0;
return(0);
}
//----------------------------------------------------------------------------
void ser_close ( void )
{
close(ser_hand);
}
//-----------------------------------------------------------------------------
void ser_senddata ( unsigned char *s, unsigned short len )
{
unsigned int wlen;
wlen=(unsigned int)write(ser_hand,s,len);
tcdrain(ser_hand);
}
//-----------------------------------------------------------------------------
void ser_sendstring ( char *s )
{
unsigned int wlen;
wlen=(unsigned int)write(ser_hand,s,strlen(s));
tcdrain(ser_hand);
}
//-----------------------------------------------------------------------------
void ser_update ( void )
{
int r;
r=read(ser_hand,&ser_buffer[ser_maincnt],4000);
if(r>0)
{
ser_maincnt+=r;
if(ser_maincnt>0xFFF)
{
ser_maincnt&=0xFFF;
memcpy(ser_buffer,&ser_buffer[0xFFF+1],ser_maincnt);
}
}
}
//-----------------------------------------------------------------------------
unsigned short ser_copystring ( unsigned char *d )
{
unsigned short r;
unsigned short buffcnt;
unsigned short maincnt;
ser_update();
buffcnt=ser_buffcnt;
maincnt=ser_maincnt;
for(r=0;buffcnt!=maincnt;buffcnt=(buffcnt+1)&0xFFF,r++) *d++=ser_buffer[buffcnt];
return(r);
}
//-----------------------------------------------------------------------------
unsigned short ser_dump ( unsigned short x )
{
unsigned short r;
for(r=0;r<x;r++)
{
if(ser_buffcnt==ser_maincnt) break;
ser_buffcnt=(ser_buffcnt+1)&0xFFF;
}
return(r);
}
//-----------------------------------------------------------------------------
// Copyright (C) David Welch, 2000
//-----------------------------------------------------------------------------

18
bootloader01/ser.h Normal file
View File

@@ -0,0 +1,18 @@
//-----------------------------------------------------------------------------
// Copyright (c) David Welch 1996, 2012
//-----------------------------------------------------------------------------
unsigned char ser_open ( char *devname );
void strobedtr ( void );
void ser_close ( void );
void ser_senddata ( unsigned char *, unsigned short );
void ser_sendstring ( char *s );
void ser_update ( void );
unsigned short ser_copystring ( unsigned char * );
unsigned short ser_dump ( unsigned short );
//-----------------------------------------------------------------------------
// Copyright (c) David Welch 1996, 2012
//-----------------------------------------------------------------------------

19
bootloader01/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