aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCatalin Marinas <catalin.marinas@arm.com>2009-12-02 12:26:48 +0000
committerCatalin Marinas <catalin.marinas@arm.com>2012-09-12 14:20:41 +0100
commit26b62f586020fd998c6efd43db657eaafeec14da (patch)
treeec0dd0ff281ba47614baec4d496e581c7b9e0c89
downloadboot-wrapper-aarch64-26b62f586020fd998c6efd43db657eaafeec14da.tar.gz
Initial version of the AArch64 Linux boot wrapperubuntu
This boot wrapper contains the code for initialising the ARMv8 software model before the Linux kernel can run (see Documentation/arm64/booting.txt in the kernel tree for the Linux booting requirements). Running "make" creates a "linux-system.axf" ELF file that can be loaded by the software model. Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
-rw-r--r--.gitignore4
-rw-r--r--LICENSE.txt28
-rw-r--r--Makefile79
-rw-r--r--README14
-rw-r--r--boot.S110
-rw-r--r--model.lds.S45
6 files changed, 280 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..20026d8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+linux-system.axf
+Image
+model.lds
+boot.o
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..d68a74e
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,28 @@
+Copyright (c) 2012, ARM Limited
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * 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.
+ * Neither the name of ARM nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
+HOLDER 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.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..5e8b154
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,79 @@
+#
+# Makefile - build a kernel+filesystem image for stand-alone Linux booting
+#
+# Copyright (C) 2012 ARM Limited. All rights reserved.
+#
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE.txt file.
+
+# VE
+PHYS_OFFSET := 0x80000000
+UART_BASE := 0x1c090000
+GIC_DIST_BASE := 0x2c001000
+GIC_CPU_BASE := 0x2c002000
+CNTFRQ := 0x01800000 # 24Mhz
+
+#INITRD_FLAGS := -DUSE_INITRD
+CPPFLAGS += $(INITRD_FLAGS)
+
+BOOTLOADER := boot.S
+MBOX_OFFSET := 0xfff8
+KERNEL := Image
+KERNEL_OFFSET := 0x80000
+LD_SCRIPT := model.lds.S
+IMAGE := linux-system.axf
+
+FILESYSTEM := filesystem.cpio.gz
+FS_OFFSET := 0x10000000
+FILESYSTEM_START:= $(shell echo $$(($(PHYS_OFFSET) + $(FS_OFFSET))))
+FILESYSTEM_SIZE := $(shell stat -Lc %s $(FILESYSTEM) 2>/dev/null || echo 0)
+FILESYSTEM_END := $(shell echo $$(($(FILESYSTEM_START) + $(FILESYSTEM_SIZE))))
+
+FDT_SRC := vexpress-v2p-aarch64.dts
+FDT_INCL_REGEX := \(/include/[[:space:]]*"\)\([^"]\+\)\(".*\)
+FDT_DEPS := $(FDT_SRC) $(addprefix $(dir $(FDT_SRC)), $(shell sed -ne 'sq$(strip $(FDT_INCL_REGEX)q\2q p' < $(FDT_SRC))))
+FDT_OFFSET := 0x08000000
+
+ifneq (,$(findstring USE_INITRD,$(CPPFLAGS)))
+BOOTARGS := "console=ttyAMA0 $(BOOTARGS_EXTRA)"
+CHOSEN_NODE := chosen { \
+ bootargs = $(BOOTARGS); \
+ linux,initrd-start = <$(FILESYSTEM_START)>; \
+ linux,initrd-end = <$(FILESYSTEM_END)>; \
+ };
+else
+BOOTARGS := "console=ttyAMA0 root=/dev/nfs nfsroot=10.1.69.68:/work/debootstrap/aarch64,tcp rw ip=dhcp $(BOOTARGS_EXTRA)"
+CHOSEN_NODE := chosen { \
+ bootargs = $(BOOTARGS); \
+ };
+endif
+
+CROSS_COMPILE := aarch64-none-linux-gnu-
+CC := $(CROSS_COMPILE)gcc
+LD := $(CROSS_COMPILE)ld
+DTC := $(if $(wildcard ./dtc), ./dtc, $(shell which dtc))
+
+all: $(IMAGE)
+
+clean:
+ rm -f $(IMAGE) boot.o model.lds fdt.dtb
+
+$(IMAGE): boot.o model.lds fdt.dtb $(KERNEL) $(FILESYSTEM)
+ $(LD) -o $@ --script=model.lds
+
+boot.o: $(BOOTLOADER) Makefile
+ $(CC) $(CPPFLAGS) -DCNTFRQ=$(CNTFRQ) -DUART_BASE=$(UART_BASE) -DSYS_FLAGS=$(SYS_FLAGS) -DGIC_DIST_BASE=$(GIC_DIST_BASE) -DGIC_CPU_BASE=$(GIC_CPU_BASE) -c -o $@ $(BOOTLOADER)
+
+model.lds: $(LD_SCRIPT) Makefile
+ $(CC) $(CPPFLAGS) -DPHYS_OFFSET=$(PHYS_OFFSET) -DMBOX_OFFSET=$(MBOX_OFFSET) -DKERNEL_OFFSET=$(KERNEL_OFFSET) -DFDT_OFFSET=$(FDT_OFFSET) -DFS_OFFSET=$(FS_OFFSET) -DKERNEL=$(KERNEL) -DFILESYSTEM=$(FILESYSTEM) -E -P -C -o $@ $<
+
+ifeq ($(DTC),)
+ $(error No dtc found! You can git clone from git://git.jdl.com/software/dtc.git)
+endif
+
+fdt.dtb: $(FDT_DEPS) Makefile
+ @sed -e 's%/\* chosen \*/%$(CHOSEN_NODE)%' -e 's%$(strip $(FDT_INCL_REGEX))%\1$(dir $(FDT_SRC))\2\3%' $< | \
+ $(DTC) -O dtb -o $@ -
+
+# The filesystem archive might not exist if INITRD is not being used
+.PHONY: all clean $(FILESYSTEM)
diff --git a/README b/README
new file mode 100644
index 0000000..d1e15c4
--- /dev/null
+++ b/README
@@ -0,0 +1,14 @@
+Linux boot wrapper with FDT support
+===================================
+
+The following files need to be linked into the boot wrapper directory:
+
+dtc - point to <linux-build-dir>/scripts/dtc/dtc
+vexpress-v2p-aarch64.dts - point to <linux-src-dir>/arch/arm64/boot/dts/vexpress-v2p-aarch64.dts
+vexpress-v2m-rs1.dtsi - point to <linux-src-dir>/arch/arm64/boot/dts/vexpress-v2m-rs1.dtsi
+skeleton.dtsi - point to <linux-src-dir>/arch/arm64/boot/dts/skeleton.dtsi
+
+Alternatively, you may specify the paths for dtc and the main dts file
+on the make command-line. For example:
+
+make DTC=<path-to-dtc> FDT_SRC=<linux-src-dir>/arch/arm64/boot/dts/vexpress-v2p-aarch64.dtsi
diff --git a/boot.S b/boot.S
new file mode 100644
index 0000000..27367d8
--- /dev/null
+++ b/boot.S
@@ -0,0 +1,110 @@
+/*
+ * boot.S - simple register setup code for stand-alone Linux booting
+ *
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE.txt file.
+ */
+
+ .text
+
+ .globl _start
+_start:
+ /*
+ * EL3 initialisation
+ */
+ mrs x0, CurrentEL
+ cmp x0, #0xc // EL3?
+ b.ne start_ns // skip EL3 initialisation
+
+ mov x0, #0x30 // RES1
+ orr x0, x0, #(1 << 0) // Non-secure EL1
+ orr x0, x0, #(1 << 8) // HVC enable
+ orr x0, x0, #(1 << 10) // 64-bit EL2
+ msr scr_el3, x0
+
+ msr cptr_el3, xzr // Disable copro. traps to EL3
+
+ ldr x0, =CNTFRQ
+ msr cntfrq_el0, x0
+
+ /*
+ * Check for the primary CPU to avoid a race on the distributor
+ * registers.
+ */
+ mrs x0, mpidr_el1
+ tst x0, #15
+ b.ne 1f // secondary CPU
+
+ ldr x1, =GIC_DIST_BASE // GICD_CTLR
+ mov w0, #3 // EnableGrp0 | EnableGrp1
+ str w0, [x1]
+
+1: ldr x1, =GIC_DIST_BASE + 0x80 // GICD_IGROUPR
+ mov w0, #~0 // Grp1 interrupts
+ str w0, [x1], #4
+ b.ne 2f // Only local interrupts for secondary CPUs
+ str w0, [x1], #4
+ str w0, [x1], #4
+
+2: ldr x1, =GIC_CPU_BASE // GICC_CTLR
+ ldr w0, [x1]
+ mov w0, #3 // EnableGrp0 | EnableGrp1
+ str w0, [x1]
+
+ mov w0, #1 << 7 // allow NS access to GICC_PMR
+ str w0, [x1, #4] // GICC_PMR
+
+ msr sctlr_el2, xzr
+
+ /*
+ * Prepare the switch to the EL2_SP1 mode from EL3
+ */
+ ldr x0, =start_ns // Return after mode switch
+ mov x1, #0x3c9 // EL2_SP1 | D | A | I | F
+ msr elr_el3, x0
+ msr spsr_el3, x1
+ eret
+
+start_ns:
+ /*
+ * Kernel parameters
+ */
+ mov x0, xzr
+ mov x1, xzr
+ mov x2, xzr
+ mov x3, xzr
+
+ mrs x4, mpidr_el1
+ tst x4, #15
+ b.eq 2f
+
+ /*
+ * Secondary CPUs
+ */
+1: wfe
+ ldr x4, mbox
+ cbz x4, 1b
+ br x4 // branch to the given address
+
+2:
+ /*
+ * UART initialisation (38400 8N1)
+ */
+ ldr x4, =UART_BASE // UART base
+ mov w5, #0x10 // ibrd
+ str w5, [x4, #0x24]
+ mov w5, #0xc300
+ orr w5, w5, #0x0001 // cr
+ str w5, [x4, #0x30]
+
+ /*
+ * Primary CPU
+ */
+ ldr x0, =dtb // device tree blob
+ b kernel
+
+ .ltorg
+
+ .org 0x200
diff --git a/model.lds.S b/model.lds.S
new file mode 100644
index 0000000..ec27433
--- /dev/null
+++ b/model.lds.S
@@ -0,0 +1,45 @@
+/*
+ * model.lds.S - simple linker script for stand-alone Linux booting
+ *
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE.txt file.
+ */
+
+OUTPUT_FORMAT("elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+TARGET(binary)
+
+INPUT(./boot.o)
+INPUT(KERNEL)
+INPUT(./fdt.dtb)
+
+#ifdef USE_INITRD
+INPUT(FILESYSTEM)
+#endif
+
+SECTIONS
+{
+ . = PHYS_OFFSET;
+ .text : { boot.o }
+ . = PHYS_OFFSET + MBOX_OFFSET;
+ mbox = .;
+ .mbox : { QUAD(0x0) }
+ . = PHYS_OFFSET + KERNEL_OFFSET;
+ kernel = .;
+ .kernel : { KERNEL }
+
+ . = PHYS_OFFSET + FDT_OFFSET;
+ dtb = .;
+ .dtb : { ./fdt.dtb }
+ . = PHYS_OFFSET + FS_OFFSET;
+ filesystem = .;
+#ifdef USE_INITRD
+ .filesystem : { FILESYSTEM }
+ fs_size = . - filesystem;
+#endif
+
+ .data : { *(.data) }
+ .bss : { *(.bss) }
+}