adding bootloader02, this is xmodem based.
This commit is contained in:
9
README
9
README
@@ -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
bootloader02/Makefile
Normal file
43
bootloader02/Makefile
Normal 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
|
||||
|
||||
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
bootloader02/README
Normal file
25
bootloader02/README
Normal file
@@ -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
bootloader02/blinker.c
Normal file
57
bootloader02/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);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------
|
||||
192
bootloader02/bootloader02.c
Normal file
192
bootloader02/bootloader02.c
Normal file
@@ -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);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------
|
||||
BIN
bootloader02/kernel.img
Executable file
BIN
bootloader02/kernel.img
Executable file
Binary file not shown.
12
bootloader02/loader
Normal file
12
bootloader02/loader
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
MEMORY
|
||||
{
|
||||
ram : ORIGIN = 0x00000000, LENGTH = 0x10000000
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : { *(.text*) } > ram
|
||||
.bss : { *(.bss*) } > ram
|
||||
}
|
||||
|
||||
12
bootloader02/memmap
Normal file
12
bootloader02/memmap
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
MEMORY
|
||||
{
|
||||
ram : ORIGIN = 0x00000000, LENGTH = 0x200000
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : { *(.text*) } > ram
|
||||
.bss : { *(.bss*) } > ram
|
||||
}
|
||||
|
||||
40
bootloader02/novectors.s
Normal file
40
bootloader02/novectors.s
Normal 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
|
||||
|
||||
19
bootloader02/start.s
Normal file
19
bootloader02/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