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
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) }
+}