]> xenbits.xensource.com Git - people/julieng/boot-wrapper-aarch64.git/commitdiff
Initial version of the AArch64 Linux boot wrapper
authorCatalin Marinas <catalin.marinas@arm.com>
Wed, 2 Dec 2009 12:26:48 +0000 (12:26 +0000)
committerCatalin Marinas <catalin.marinas@arm.com>
Wed, 12 Sep 2012 13:20:41 +0000 (14:20 +0100)
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>
.gitignore [new file with mode: 0644]
LICENSE.txt [new file with mode: 0644]
Makefile [new file with mode: 0644]
README [new file with mode: 0644]
boot.S [new file with mode: 0644]
model.lds.S [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..20026d8
--- /dev/null
@@ -0,0 +1,4 @@
+linux-system.axf
+Image
+model.lds
+boot.o
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644 (file)
index 0000000..d68a74e
--- /dev/null
@@ -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 (file)
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 (file)
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 (file)
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 (file)
index 0000000..ec27433
--- /dev/null
@@ -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) }
+}