diff --git a/README b/README index d9bd19d..623e1cf 100644 --- a/README +++ b/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 diff --git a/bootloader02/Makefile b/bootloader02/Makefile new file mode 100644 index 0000000..5a7d209 --- /dev/null +++ b/bootloader02/Makefile @@ -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 + + diff --git a/bootloader02/README b/bootloader02/README new file mode 100644 index 0000000..0e5b79e --- /dev/null +++ b/bootloader02/README @@ -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. diff --git a/bootloader02/blinker.c b/bootloader02/blinker.c new file mode 100644 index 0000000..2e6388d --- /dev/null +++ b/bootloader02/blinker.c @@ -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); +} +//------------------------------------------------------------------------- +//------------------------------------------------------------------------- diff --git a/bootloader02/bootloader02.c b/bootloader02/bootloader02.c new file mode 100644 index 0000000..a6eb816 --- /dev/null +++ b/bootloader02/bootloader02.c @@ -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); +} +//------------------------------------------------------------------------- +//------------------------------------------------------------------------- diff --git a/bootloader02/kernel.img b/bootloader02/kernel.img new file mode 100755 index 0000000..f3533fa Binary files /dev/null and b/bootloader02/kernel.img differ diff --git a/bootloader02/loader b/bootloader02/loader new file mode 100644 index 0000000..7bb7988 --- /dev/null +++ b/bootloader02/loader @@ -0,0 +1,12 @@ + +MEMORY +{ + ram : ORIGIN = 0x00000000, LENGTH = 0x10000000 +} + +SECTIONS +{ + .text : { *(.text*) } > ram + .bss : { *(.bss*) } > ram +} + diff --git a/bootloader02/memmap b/bootloader02/memmap new file mode 100644 index 0000000..203c50d --- /dev/null +++ b/bootloader02/memmap @@ -0,0 +1,12 @@ + +MEMORY +{ + ram : ORIGIN = 0x00000000, LENGTH = 0x200000 +} + +SECTIONS +{ + .text : { *(.text*) } > ram + .bss : { *(.bss*) } > ram +} + diff --git a/bootloader02/novectors.s b/bootloader02/novectors.s new file mode 100644 index 0000000..484cc85 --- /dev/null +++ b/bootloader02/novectors.s @@ -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 + diff --git a/bootloader02/start.s b/bootloader02/start.s new file mode 100644 index 0000000..07817bc --- /dev/null +++ b/bootloader02/start.s @@ -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