sigh, I have a bootloader working!
This commit is contained in:
46
bootloader01/Makefile
Normal file
46
bootloader01/Makefile
Normal 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
52
bootloader01/README
Normal 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
57
bootloader01/blinker.c
Normal 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
257
bootloader01/bootloader01.c
Normal 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
12
bootloader01/loader
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
MEMORY
|
||||
{
|
||||
ram : ORIGIN = 0x00000000, LENGTH = 0x10000000
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : { *(.text*) } > ram
|
||||
.bss : { *(.bss*) } > ram
|
||||
}
|
||||
|
||||
12
bootloader01/memmap
Normal file
12
bootloader01/memmap
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
MEMORY
|
||||
{
|
||||
ram : ORIGIN = 0x00000000, LENGTH = 0x200000
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : { *(.text*) } > ram
|
||||
.bss : { *(.bss*) } > ram
|
||||
}
|
||||
|
||||
35
bootloader01/novectors.s
Normal file
35
bootloader01/novectors.s
Normal 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
317
bootloader01/prograspi.c
Normal 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
106
bootloader01/ser.c
Normal 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
18
bootloader01/ser.h
Normal 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
19
bootloader01/start.s
Normal 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
|
||||
Reference in New Issue
Block a user