Small bootloader - Raspberry Pi Forums


i created tiny bootloader , thought i'd share class.
small fits inside first 0x100 bytes (252 bytes exact, + 48 bytes of code handles relocation 0x0).
preserves atags setup , register values, means can theoretically load linux kernel (not tested), though might take while @ 115.2kbps
not use special protocol transfer means terminal can send raw file work. of course biggest weakness there no error checking or recovery.
use uart0, larger fifo can reduce risks involved in not checking errors. kudos dwelch67 making example uart0 way.
code made 1 single block of assembly, removes need stack management , frees couple of words. reserve space standard patchable vector table though. apart that, think breaks most, if not all, of "good programming practice" rules, hardcoding of values, no functions , writing null pointer.
might notice bootloader not use ldr method initialize variables. avoids issue assembler place actual value outside region gets relocated. besides, need have more 2x8bit blocks in constant gets loaded before mov + orr gets bigger.

comments?

here is, loaded @ default 0x8000:

code: select all

.section .init .globl _start _start: bootloader_start:     ldr pc,reset_handler     ldr pc,undefined_handler     ldr pc,swi_handler     ldr pc,prefetch_handler     ldr pc,data_handler     ldr pc,unused_handler     ldr pc,irq_handler     ldr pc,fiq_handler reset_handler: .word loader_loader undefined_handler: .word 0x40 swi_handler: .word 0x40 prefetch_handler: .word 0x40 data_handler: .word 0x40 unused_handler: .word 0x40 irq_handler: .word 0x40 fiq_handler: .word 0x40  # gets loaded @ address 0x40 hang:     mov     r0, #0x40     bx      r0  # gets loaded @ address 0x48 reset: # begin: uart initialization     status .req r0     machtype .req r1     atags .req r2     val .req r3     uart_phys_base .req r4     gpio_phys_base .req r5     timer_phys_base .req r6     active_time .req r7     current_time .req r8     load_ptr .req r9          mov     uart_phys_base,#0x20000000     orr     uart_phys_base,uart_phys_base,#0x00200000     orr     uart_phys_base,uart_phys_base,#0x00001000     mov     gpio_phys_base,#0x20000000     orr     gpio_phys_base, gpio_phys_base, #0x00200000     mov     timer_phys_base,#0x20000000     orr     timer_phys_base, timer_phys_base, #0x00003000     mov     load_ptr,#0x8000          # uart0_cr = 0     mov     val,#0     str     val, [uart_phys_base, #0x30]          # gpio function uart0 pins 14 , 15     mov     val,#0x24000     str     val, [gpio_phys_base, #4]          # uart0_icr = 0x7f1     mov     val,#0x7f0     orr     val, val, #0x001     str     val, [uart_phys_base, #0x44]      # uart0_ibrd = 1     mov     val,#1     str     val, [uart_phys_base, #0x24]      # uart0_fbrd = 40     mov     val,#40     str     val, [uart_phys_base, #0x28]      # uart0_lcrh = 0x70     mov     val,#0x70     str     val, [uart_phys_base, #0x2c]      # uart0_cr = 0x301     mov     val,#0x300     orr     val, val, #0x001     str     val, [uart_phys_base, #0x30] # end: uart initialization      # transmit 'b' on uart     mov     val, #0x42     str     val, [uart_phys_base, #0x00]  # initialize time timeout     ldr     current_time, [timer_phys_base, #4]     mov     active_time, current_time loop$: # read uart0_fr     ldr     val, [uart_phys_base, #0x18]     ands    val, val, #0x10 # if result non-zero, continue timeout check     bne     cont$      # load actual uart data byte , mask byte     ldr     val, [uart_phys_base, #0x00]     ,     val, val, #0xff      # *load_ptr = val, load_ptr++     strb    val, [load_ptr], #1  # set active time     mov     active_time, current_time  cont$: # check timeout     ldr     current_time, [timer_phys_base, #4]     sub     val, current_time, active_time     cmp     val, #0x50000     bls     loop$ # ... if have started receiving data     cmp     load_ptr, #0x8000     beq     loop$  # transmit 's' on uart     mov     val, #0x53     str     val, [uart_phys_base, #0x00]  # branch loaded code entry point     mov     val, #0x8000     bx      val  bootloader_end:  loader_loader:     mov     r3, # 0x8000     mov     r4, # bootloader_end - bootloader_start     mov     r5, #0 copy:     ldr     r6, [r3], #4        @ load starting 0x8000, postincrement 4     str     r6, [r5], #4        @ store starting 0x0, postincrement 4     subs    r4, r4,   #4        @ if ((r4 -= 4) != 0)     bne     copy                @     goto copy          mov     r3, #0x20     mov     r4, #0x48     str     r4, [r3]            @ *(0x20) = 0x48, point reset vector "reset"      # goto address 0x0 reset vector     mov     r7, #0     bx      r7 



raspberrypi



Comments

Popular posts from this blog

CAN'T INSTALL MAMBELFISH 1.5 FROM DIRECTORY - Joomla! Forum - community, help and support

error: expected initializer before 'void'

CPU load monitoring using GPIO and leds - Raspberry Pi Forums