From 074d37d46c3f9b282cd2d849d997b1b39acd710c Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Sat, 7 Feb 2015 18:37:05 +0000 Subject: [PATCH] Add a Raspberry Pi 2 static loader --- sys/boot/arm/rpi/Makefile | 62 +++++++++++ sys/boot/arm/rpi/conf.c | 39 +++++++ sys/boot/arm/rpi/ldscript.arm | 131 +++++++++++++++++++++++ sys/boot/arm/rpi/main.c | 172 +++++++++++++++++++++++++++++++ sys/boot/arm/rpi/pl011_console.c | 84 +++++++++++++++ sys/boot/arm/rpi/reloc.c | 93 +++++++++++++++++ sys/boot/arm/rpi/start.S | 56 ++++++++++ sys/boot/arm/rpi/version | 6 ++ 8 files changed, 643 insertions(+) create mode 100644 sys/boot/arm/rpi/Makefile create mode 100644 sys/boot/arm/rpi/conf.c create mode 100644 sys/boot/arm/rpi/ldscript.arm create mode 100644 sys/boot/arm/rpi/main.c create mode 100644 sys/boot/arm/rpi/pl011_console.c create mode 100644 sys/boot/arm/rpi/reloc.c create mode 100644 sys/boot/arm/rpi/start.S create mode 100644 sys/boot/arm/rpi/version diff --git a/sys/boot/arm/rpi/Makefile b/sys/boot/arm/rpi/Makefile new file mode 100644 index 00000000000000..772250fcfcfea3 --- /dev/null +++ b/sys/boot/arm/rpi/Makefile @@ -0,0 +1,62 @@ +# $FreeBSD$ + +.include + +PROG= loader.sym +INTERNALPROG= + +NEWVERSWHAT= "Raspberry Pi loader" ${MACHINE_ARCH} +BINDIR?= /boot +INSTALLFLAGS= -b +WARNS?= 1 + +# Architecture-specific loader code +SRCS= start.S \ + main.c \ + reloc.c \ + conf.c \ + vers.c \ + pl011_console.c + +# Always add MI sources +.PATH: ${.CURDIR}/../../common +#.include "${.CURDIR}/../../common/Makefile.inc" +SRCS+= console.c \ + panic.c +CFLAGS+= -I${.CURDIR}/../../common +CFLAGS+= -I. +CFLAGS+= -I${.CURDIR}/../../../contrib/libfdt + +FILES= loader.bin +FILESMODE_loader.bin= ${BINMODE} +CLEANFILES+= vers.c loader.sym + +CFLAGS+= -ffreestanding -msoft-float + +LDFLAGS= -nostdlib +LDFLAGS+= -Wl,-Bsymbolic -shared +#LDFLAGS+= -static +LDFLAGS+= -Wl,-T ${.CURDIR}/ldscript.${MACHINE_CPUARCH} + +# where to get libstand from +CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ + +# clang doesn't understand %D as a specifier to printf +NO_WERROR.clang= + +#DPADD= ${LIBSTAND} +DDADD= ${.OBJDIR}/../../../../lib/libstand/libstand.a +#LDADD= -lstand +LDADD= ${.OBJDIR}/../../../../lib/libstand/libstand.a + +vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version + sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT} + +loader.sym: ${.CURDIR}/ldscript.${MACHINE_CPUARCH} + +loader.bin: loader.sym + ${OBJCOPY} -S -O binary loader.sym ${.TARGET} + +MAN= + +.include diff --git a/sys/boot/arm/rpi/conf.c b/sys/boot/arm/rpi/conf.c new file mode 100644 index 00000000000000..ade218a0cdf11f --- /dev/null +++ b/sys/boot/arm/rpi/conf.c @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2008 Semihalf, Rafal Jaworowski + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include "bootstrap.h" + +extern struct console pl011_console; + +struct console *consoles[] = { + &pl011_console, + NULL +}; diff --git a/sys/boot/arm/rpi/ldscript.arm b/sys/boot/arm/rpi/ldscript.arm new file mode 100644 index 00000000000000..362e1bcdf8db92 --- /dev/null +++ b/sys/boot/arm/rpi/ldscript.arm @@ -0,0 +1,131 @@ +/* $FreeBSD$ */ + +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0; /*SIZEOF_HEADERS;*/ + ImageBase = .; + .text : + { + *(.text) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.gnu.linkonce.t*) + } =0 + _etext = .; + PROVIDE (etext = .); + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rela.text : + { *(.rela.text) *(.rela.gnu.linkonce.t*) } + .rela.data : + { *(.rela.data) *(.rela.gnu.linkonce.d*) } + .rela.rodata : + { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } + .rela.got : { *(.rela.got) } + .rela.got1 : { *(.rela.got1) } + .rela.got2 : { *(.rela.got2) } + .rela.ctors : { *(.rela.ctors) } + .rela.dtors : { *(.rela.dtors) } + .rela.init : { *(.rela.init) } + .rela.fini : { *(.rela.fini) } + .rela.bss : { *(.rela.bss) } + .rela.plt : { *(.rela.plt) } + .rela.sdata : { *(.rela.sdata) } + .rela.sbss : { *(.rela.sbss) } + .rela.sdata2 : { *(.rela.sdata2) } + .rela.sbss2 : { *(.rela.sbss2) } + .init : { *(.init) } =0 + .fini : { *(.fini) } =0 + .rodata : { *(.rodata) *(.gnu.linkonce.r*) } + .rodata1 : { *(.rodata1) } + .sdata2 : { *(.sdata2) } + .sbss2 : { *(.sbss2) } + /* Adjust the address for the data segment to the next page up. */ + . = ((. + 0x1000) & ~(0x1000 - 1)); + .data : + { + *(.data) + *(.gnu.linkonce.d*) + CONSTRUCTORS + } + .data1 : { *(.data1) } + .got1 : { *(.got1) } + .dynamic : { *(.dynamic) } + /* Put .ctors and .dtors next to the .got2 section, so that the pointers + get relocated with -mrelocatable. Also put in the .fixup pointers. + The current compiler no longer needs this, but keep it around for 2.7.2 */ + PROVIDE (_GOT2_START_ = .); + .got2 : { *(.got2) } + PROVIDE (__CTOR_LIST__ = .); + .ctors : { *(.ctors) } + PROVIDE (__CTOR_END__ = .); + PROVIDE (__DTOR_LIST__ = .); + .dtors : { *(.dtors) } + PROVIDE (__DTOR_END__ = .); + PROVIDE (_FIXUP_START_ = .); + .fixup : { *(.fixup) } + PROVIDE (_FIXUP_END_ = .); + PROVIDE (_GOT2_END_ = .); + PROVIDE (_GOT_START_ = .); + .got : { *(.got) } + .got.plt : { *(.got.plt) } + PROVIDE (_GOT_END_ = .); + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : { *(.sdata) } + _edata = .; + PROVIDE (edata = .); + .plt : { *(.plt) } + __bss_start = .; + .sbss : + { + *(.sbss) + *(.scommon) + *(.dynsbss) + } + .bss : + { + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* These must appear regardless of . */ +} diff --git a/sys/boot/arm/rpi/main.c b/sys/boot/arm/rpi/main.c new file mode 100644 index 00000000000000..6a3f40a8e5b6b0 --- /dev/null +++ b/sys/boot/arm/rpi/main.c @@ -0,0 +1,172 @@ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +/* + * Copy module-related data into the load area, where it can be + * used as a directory for loaded modules. + * + * Module data is presented in a self-describing format. Each datum + * is preceded by a 32-bit identifier and a 32-bit size field. + * + * Currently, the following data are saved: + * + * MOD_NAME (variable) module name (string) + * MOD_TYPE (variable) module type (string) + * MOD_ARGS (variable) module parameters (string) + * MOD_ADDR sizeof(vm_offset_t) module load address + * MOD_SIZE sizeof(size_t) module size + * MOD_METADATA (variable) type-specific metadata + */ +#define COPY32(v, a, c) { \ + uint32_t *x = (uint32_t *)(a); \ + if (c) \ + *x = (v); \ + a += sizeof(*x); \ +} + +#define MOD_STR(t, a, s, c) { \ + COPY32(t, a, c); \ + COPY32(strlen(s) + 1, a, c); \ + if (c) \ + memcpy((void *)a, s, strlen(s) + 1); \ + a += roundup(strlen(s) + 1, sizeof(u_long)); \ +} + +#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) +#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c) +#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c) + +#define MOD_VAR(t, a, s, c) { \ + COPY32(t, a, c); \ + COPY32(sizeof(s), a, c); \ + if (c) \ + memcpy((void *)a, &s, sizeof(s)); \ + a += roundup(sizeof(s), sizeof(u_long)); \ +} + +#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) +#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c) + +#define MOD_METADATA(a, t, d, c) { \ + COPY32(MODINFO_METADATA | t, a, c); \ + COPY32(sizeof(d), a, c); \ + if (c) \ + memcpy((void *)a, &(d), sizeof(d)); \ + a += roundup(sizeof(d), sizeof(u_long)); \ +} + +#define MOD_END(a, c) { \ + COPY32(MODINFO_END, a, c); \ + COPY32(0, a, c); \ +} + +static vm_offset_t +bi_copymodules(vm_offset_t addr, struct preloaded_file *fp, int howto, + void *envp, vm_offset_t dtbp, vm_offset_t kernend) +{ + int copy; + + copy = addr != 0; + + MOD_NAME(addr, "kernel", copy); + MOD_TYPE(addr, "elf kernel", copy); + MOD_ADDR(addr, fp->f_addr, copy); + MOD_SIZE(addr, fp->f_size, copy); + + MOD_METADATA(addr, MODINFOMD_HOWTO, howto, copy); + MOD_METADATA(addr, MODINFOMD_ENVP, envp, copy); + MOD_METADATA(addr, MODINFOMD_DTBP, dtbp, copy); + MOD_METADATA(addr, MODINFOMD_KERNEND, kernend, copy); + + MOD_END(addr, copy); + + return (addr); +} + +static void +exec(void *base, struct fdt_header *dtb) +{ + struct preloaded_file kfp; + Elf_Ehdr *e; + void (*entry)(void *); + vm_offset_t addr, size; + vm_offset_t dtbp, kernend; + void *envp; + int howto; + + bzero(&kfp, sizeof(kfp)); + kfp.f_addr = (vm_offset_t)base; + /* Guess */ + kfp.f_size = 6 * 1024 * 1024; + + howto = 0; + envp = NULL; + + addr = kfp.f_addr + kfp.f_size; + memcpy((void *)addr, dtb, fdt_totalsize(dtb)); + dtbp = addr - (unsigned int)base + 0xc0100000; + addr += roundup2(fdt_totalsize(dtb), PAGE_SIZE); + + size = bi_copymodules(0, &kfp, 0, NULL, dtbp, 0); + kernend = roundup(addr + size, PAGE_SIZE); + kernend = kernend - (unsigned int)base + 0xc0100000; + (void)bi_copymodules(addr, &kfp, 0, NULL, dtbp, kernend); + + e = base; + entry = (void *)((unsigned int)e->e_entry - 0xc0100000 + + (unsigned int)base); + addr = addr - (unsigned int)base + 0xc0100000; + + printf("entry: %p %x\n", entry, *(uint32_t *)entry); + entry((void *)addr); +} + +int +main(void *dtb, unsigned int end) +{ + volatile uint32_t *gpio = (volatile uint32_t *)0x3f200000; + struct fdt_header *header; + uint32_t tmp; + + tmp = gpio[1]; + tmp &= ~(0x7 << 15 | 0x7 << 12); + tmp |= (0x4 << 15 | 0x4 << 12); + gpio[1] = tmp; + + /* + * Initialise the heap as early as possible. Once this is done, + * alloc() is usable. The stack is buried inside us, so this is safe. + */ + setheap((void *)end, (void *)(end + 512 * 1024)); + + /* + * Set up console. + */ + cons_probe(); + + header = dtb; + exec((void *)0xa00000, header); + + return (1); +} + +void _exit(void); +void +exit(int code) +{ + + _exit(); +} diff --git a/sys/boot/arm/rpi/pl011_console.c b/sys/boot/arm/rpi/pl011_console.c new file mode 100644 index 00000000000000..d861d2d2477cff --- /dev/null +++ b/sys/boot/arm/rpi/pl011_console.c @@ -0,0 +1,84 @@ +/*- + * Copyright (c) 2000 Doug Rabson + * Copyright (c) 2015 Andrew Turner + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include + +static void +pl011_cons_probe(struct console *cp) +{ + + cp->c_flags |= C_PRESENTIN | C_PRESENTOUT; +} + +static int +pl011_cons_init(int arg) +{ + + return 0; +} + +static void +pl011_cons_putchar(int c) +{ + volatile uint32_t *uart = (volatile uint32_t *)0x3f201000; + + if (c == '\n') + pl011_cons_putchar('\r'); + + while (uart[6] & (1 << 5)) + ; + + uart[0] = c; +} + +static int +pl011_cons_getchar(void) +{ + + return (0); +} + +static int +pl011_cons_poll(void) +{ + + return (0); +} + +struct console pl011_console = { + "pl011", + "pl011 console", + 0, + pl011_cons_probe, + pl011_cons_init, + pl011_cons_putchar, + pl011_cons_getchar, + pl011_cons_poll +}; diff --git a/sys/boot/arm/rpi/reloc.c b/sys/boot/arm/rpi/reloc.c new file mode 100644 index 00000000000000..a29d31ede80324 --- /dev/null +++ b/sys/boot/arm/rpi/reloc.c @@ -0,0 +1,93 @@ +/*- + * Copyright (c) 2008-2010 Rui Paulo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +/* + * A simple relocator for IA32/AMD64 EFI binaries. + */ +void +_reloc(unsigned long ImageBase, Elf32_Dyn *dynamic) +{ + unsigned long relsz, relent; + unsigned long *newaddr; + Elf32_Rel *rel; + Elf32_Dyn *dynp; + +{ + volatile uint32_t *gpio = (volatile uint32_t *)0x3f200000; + uint32_t tmp; + + tmp = gpio[1]; + tmp &= ~(0x7 << 15 | 0x7 << 12); + tmp |= (0x4 << 15 | 0x4 << 12); + gpio[1] = tmp; +} + + /* + * Find the relocation address, its size and the relocation entry. + */ + relsz = 0; + relent = 0; + for (dynp = dynamic; dynp->d_tag != DT_NULL; dynp++) { + switch (dynp->d_tag) { + case DT_REL: + rel = (Elf32_Rel *) ((unsigned long) dynp->d_un.d_ptr + + ImageBase); + break; + case DT_RELSZ: + relsz = dynp->d_un.d_val; + break; + case DT_RELENT: + relent = dynp->d_un.d_val; + break; + default: + break; + } + } + + /* + * Perform the actual relocation. + */ + for (; relsz > 0; relsz -= relent) { + switch (ELF32_R_TYPE(rel->r_info)) { + case R_ARM_RELATIVE: + /* Address relative to the base address. */ + newaddr = (unsigned long *)(ImageBase + rel->r_offset); + *newaddr += ImageBase; + break; + default: + /* XXX: do we need other relocations ? */ + break; + } + rel = (Elf32_Rel *) ((caddr_t) rel + relent); + } +} diff --git a/sys/boot/arm/rpi/start.S b/sys/boot/arm/rpi/start.S new file mode 100644 index 00000000000000..f4d47b9ed6dde6 --- /dev/null +++ b/sys/boot/arm/rpi/start.S @@ -0,0 +1,56 @@ + +#include + +.globl _start +_start: + mov r4, r2 + + adr r0, stack_end + mov sp, r0 + + adr r0, .Lbase + ldr r1, [r0] + sub r5, r0, r1 + + ldr r0, .Limagebase + add r0, r0, r5 + ldr r1, .Ldynamic + add r1, r1, r5 + + bl _C_LABEL(_reloc) + + /* Zero the BSS, _reloc fixed the values for us */ + ldr r0, .Lbss + ldr r1, .Lbssend + mov r2, #0 + +1: cmp r0, r1 + bgt 2f + str r2, [r0], #4 + b 1b + +2: + mov r0, r4 + bl _C_LABEL(main) + +.globl _exit +_exit: +1: WFI + b 1b + +.Lbase: + .word . +.Limagebase: + .word ImageBase +.Ldynamic: + .word _DYNAMIC +.Lbss: + .word __bss_start +.Lbssend: + .word _end + +.align 3 +stack: + .space 512 +stack_end: + diff --git a/sys/boot/arm/rpi/version b/sys/boot/arm/rpi/version new file mode 100644 index 00000000000000..692091a47afe91 --- /dev/null +++ b/sys/boot/arm/rpi/version @@ -0,0 +1,6 @@ +$FreeBSD$ + +NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this +file is important. Make sure the current version number is on line 6. + +0.5: Initial arm binary loader.