summaryrefslogtreecommitdiffstats
path: root/arch/arm/boot/bootp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--arch/arm/boot/bootp/Makefile60
-rw-r--r--arch/arm/boot/bootp/bootp.lds27
-rw-r--r--arch/arm/boot/bootp/init.S85
-rw-r--r--arch/arm/boot/bootp/initrd.S7
-rw-r--r--arch/arm/boot/bootp/kernel.S7
5 files changed, 186 insertions, 0 deletions
diff --git a/arch/arm/boot/bootp/Makefile b/arch/arm/boot/bootp/Makefile
new file mode 100644
index 000000000..a2934e6fd
--- /dev/null
+++ b/arch/arm/boot/bootp/Makefile
@@ -0,0 +1,60 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# linux/arch/arm/boot/bootp/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies.
+#
+GCOV_PROFILE := n
+
+ifdef PHYS_OFFSET
+add_hex = $(shell printf 0x%x $$(( $(1) + $(2) )) )
+
+# If PHYS_OFFSET is set, INITRD_PHYS and PARAMS_PHYS can be derived,
+# otherwise they must be passed on the command line.
+#
+# Note: the following conditions must always be true:
+# PARAMS_PHYS must be within 4MB of ZRELADDR
+# INITRD_PHYS must be in RAM
+
+PARAMS_PHYS := $(call add_hex, $(PHYS_OFFSET), 0x100)
+
+# guess an initrd location if possible
+initrd_offset-$(CONFIG_ARCH_FOOTBRIDGE) += 0x00800000
+initrd_offset-$(CONFIG_ARCH_SA1100) += 0x00800000
+initrd_offset-$(CONFIG_ARCH_RPC) += 0x08000000
+INITRD_OFFSET := $(initrd_offset-y)
+ifdef INITRD_OFFSET
+INITRD_PHYS := $(call add_hex, $(PHYS_OFFSET), $(INITRD_OFFSET))
+endif
+
+endif
+
+PHONY += initrd
+initrd:
+ @test "$(PARAMS_PHYS)" != "" || \
+ (echo bootpImage: You must specify PHYS_OFFSET of PARAMS_PHYS ; exit -1)
+ @test "$(INITRD_PHYS)" != "" || \
+ (echo bootpImage: You must specify INITRD_OFFSET or INITRD_PHYS ; exit -1)
+ @test "$(INITRD)" != "" || \
+ (echo bootpImage: You must specify INITRD; exit -1)
+
+LDFLAGS_bootp := --no-undefined -X \
+ --defsym initrd_phys=$(INITRD_PHYS) \
+ --defsym params_phys=$(PARAMS_PHYS) -T
+AFLAGS_initrd.o :=-DINITRD=\"$(INITRD)\"
+
+targets := bootp init.o kernel.o initrd.o
+
+# Note that bootp.lds picks up kernel.o and initrd.o
+$(obj)/bootp: $(src)/bootp.lds $(addprefix $(obj)/,init.o kernel.o initrd.o) FORCE
+ $(call if_changed,ld)
+
+# kernel.o and initrd.o includes a binary image using
+# .incbin, a dependency which is not tracked automatically
+
+$(obj)/kernel.o: arch/arm/boot/zImage FORCE
+
+$(obj)/initrd.o: initrd $(INITRD) FORCE
+
+PHONY += $(INITRD)
diff --git a/arch/arm/boot/bootp/bootp.lds b/arch/arm/boot/bootp/bootp.lds
new file mode 100644
index 000000000..160128186
--- /dev/null
+++ b/arch/arm/boot/bootp/bootp.lds
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * linux/arch/arm/boot/bootp/bootp.lds
+ *
+ * Copyright (C) 2000-2002 Russell King
+ */
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0;
+ .text : {
+ _stext = .;
+ *(.start)
+ *(.text)
+ initrd_size = initrd_end - initrd_start;
+ _etext = .;
+ }
+
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+}
diff --git a/arch/arm/boot/bootp/init.S b/arch/arm/boot/bootp/init.S
new file mode 100644
index 000000000..b562da2f7
--- /dev/null
+++ b/arch/arm/boot/bootp/init.S
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * linux/arch/arm/boot/bootp/init.S
+ *
+ * Copyright (C) 2000-2003 Russell King.
+ *
+ * "Header" file for splitting kernel + initrd. Note that we pass
+ * r0 through to r3 straight through.
+ *
+ * This demonstrates how to append code to the start of the kernel
+ * zImage, and boot the kernel without copying it around. This
+ * example would be simpler; if we didn't have an object of unknown
+ * size immediately following the kernel, we could build this into
+ * a binary blob, and concatenate the zImage using the cat command.
+ */
+ .section .start, "ax"
+ .type _start, #function
+ .globl _start
+
+_start: add lr, pc, #-0x8 @ lr = current load addr
+ adr r13, data
+ ldmia r13!, {r4-r6} @ r5 = dest, r6 = length
+ add r4, r4, lr @ r4 = initrd_start + load addr
+ bl move @ move the initrd
+
+/*
+ * Setup the initrd parameters to pass to the kernel. This can only be
+ * passed in via the tagged list.
+ */
+ ldmia r13, {r5-r9} @ get size and addr of initrd
+ @ r5 = ATAG_CORE
+ @ r6 = ATAG_INITRD2
+ @ r7 = initrd start
+ @ r8 = initrd end
+ @ r9 = param_struct address
+
+ ldr r10, [r9, #4] @ get first tag
+ teq r10, r5 @ is it ATAG_CORE?
+/*
+ * If we didn't find a valid tag list, create a dummy ATAG_CORE entry.
+ */
+ movne r10, #0 @ terminator
+ movne r4, #2 @ Size of this entry (2 words)
+ stmiane r9, {r4, r5, r10} @ Size, ATAG_CORE, terminator
+
+/*
+ * find the end of the tag list, and then add an INITRD tag on the end.
+ * If there is already an INITRD tag, then we ignore it; the last INITRD
+ * tag takes precedence.
+ */
+taglist: ldr r10, [r9, #0] @ tag length
+ teq r10, #0 @ last tag (zero length)?
+ addne r9, r9, r10, lsl #2
+ bne taglist
+
+ mov r5, #4 @ Size of initrd tag (4 words)
+ stmia r9, {r5, r6, r7, r8, r10}
+ b kernel_start @ call kernel
+
+/*
+ * Move the block of memory length r6 from address r4 to address r5
+ */
+move: ldmia r4!, {r7 - r10} @ move 32-bytes at a time
+ stmia r5!, {r7 - r10}
+ ldmia r4!, {r7 - r10}
+ stmia r5!, {r7 - r10}
+ subs r6, r6, #8 * 4
+ bcs move
+ mov pc, lr
+
+ .size _start, . - _start
+
+ .align
+
+ .type data,#object
+data: .word initrd_start @ source initrd address
+ .word initrd_phys @ destination initrd address
+ .word initrd_size @ initrd size
+
+ .word 0x54410001 @ r5 = ATAG_CORE
+ .word 0x54420005 @ r6 = ATAG_INITRD2
+ .word initrd_phys @ r7
+ .word initrd_size @ r8
+ .word params_phys @ r9
+ .size data, . - data
diff --git a/arch/arm/boot/bootp/initrd.S b/arch/arm/boot/bootp/initrd.S
new file mode 100644
index 000000000..dd3d04971
--- /dev/null
+++ b/arch/arm/boot/bootp/initrd.S
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+ .type initrd_start,#object
+ .globl initrd_start
+initrd_start:
+ .incbin INITRD
+ .globl initrd_end
+initrd_end:
diff --git a/arch/arm/boot/bootp/kernel.S b/arch/arm/boot/bootp/kernel.S
new file mode 100644
index 000000000..dc6236c17
--- /dev/null
+++ b/arch/arm/boot/bootp/kernel.S
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+ .globl kernel_start
+kernel_start:
+ .incbin "arch/arm/boot/zImage"
+ .globl kernel_end
+kernel_end:
+ .align 2