You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2024/09/13 13:25:56 UTC

(nuttx) branch master updated: arch/x86_64: Add elf32 multiboot1 wrapper for NuttX binary

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 126221df97 arch/x86_64: Add elf32 multiboot1 wrapper for NuttX binary
126221df97 is described below

commit 126221df9708d101e1c150bc26ee967b5665735c
Author: ouyangxiangzhen <ou...@xiaomi.com>
AuthorDate: Fri Sep 13 18:55:20 2024 +0800

    arch/x86_64: Add elf32 multiboot1 wrapper for NuttX binary
    
    It was discovered that attempting to load x86-64 format ELF files with a multiboot1 header using the qemu `-kernel` command would result in an error, as multiboot1 only allows x86-32 format ELF files. To address this limitation, we have developed a simple x86_32 bootloader. This bootloader is designed to copy the `nuttx.bin` file to the designated memory address (`0x100000`) and then transfer control to NuttX by executing a jump instruction (`jmp 0x100000`).
    
    Signed-off-by: ouyangxiangzhen <ou...@xiaomi.com>
---
 .gitignore                           |   1 +
 arch/x86_64/Kconfig                  |   9 +++-
 arch/x86_64/src/Makefile             |   7 +++
 arch/x86_64/src/common/multiboot1.S  | 102 +++++++++++++++++++++++++++++++++++
 arch/x86_64/src/common/multiboot1.ld |  32 +++++++++++
 5 files changed, 150 insertions(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore
index bac82b4bac..5fc5e08259 100644
--- a/.gitignore
+++ b/.gitignore
@@ -49,6 +49,7 @@
 /defconfig
 /Make.defs
 /nuttx
+/nuttx32
 /nuttx-*
 /nuttx.*
 /nuttx_user*
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 1a33c9632c..fad91e08cf 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -106,6 +106,13 @@ config ARCH_CHIP
 
 endif # ARCH_INTEL64
 
+config ARCH_MULTIBOOT1
+	bool "Enable ELF32/Multiboot1"
+	default n
+	---help---
+		This enables generating `nuttx32` and allows x86 QEMU
+		`-kernel` boot in multiboot1 protocol.
+
 config ARCH_MULTIBOOT2
 	bool "Append multiboot2 header"
 	default y
@@ -128,6 +135,6 @@ config ARCH_PVHBOOT
 	bool "Append Xen PVH ELF Note"
 	default y
 	---help---
-		This allow x86 QEMU -kernel boot.
+		This allows x86 QEMU `-kernel` boot in PVH protocol.
 
 endif # ARCH_X86_64
diff --git a/arch/x86_64/src/Makefile b/arch/x86_64/src/Makefile
index 59029876bd..8261aea14a 100644
--- a/arch/x86_64/src/Makefile
+++ b/arch/x86_64/src/Makefile
@@ -134,6 +134,13 @@ ifneq ($(CONFIG_WINDOWS_NATIVE),y)
 	sort > $(TOPDIR)/System.map
 endif
 
+ifeq ($(CONFIG_ARCH_MULTIBOOT1),y)
+	@echo "Generating: nuttx32 in ELF32/multiboot1"
+	$(Q) $(OBJCOPY) -R .realmode -R.note.* -O binary $(NUTTX) $(NUTTX).bin \
+	&& $(CC) -m32 -no-pie -nostdlib common/multiboot1.S \
+			-T common/multiboot1.ld -o $(NUTTX)32
+endif
+
 # This is part of the top-level export target
 
 export_startup: $(STARTUP_OBJS)
diff --git a/arch/x86_64/src/common/multiboot1.S b/arch/x86_64/src/common/multiboot1.S
new file mode 100644
index 0000000000..914cfa9329
--- /dev/null
+++ b/arch/x86_64/src/common/multiboot1.S
@@ -0,0 +1,102 @@
+/****************************************************************************
+ * arch/x86_64/src/common/multiboot1.S
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/* Multiboot1 NuttX Naive Loader */
+
+.set ENTRY_ADDR,        0x100000 /* NuttX Entry Address  */
+
+.set MB_FLAG_ALIGNED,   1        /* All boot modules must be loaded aligned */
+.set MB_FLAG_MEMINFO,   2        /* Boot with memory maps passing  */
+.set MB_FLAG_VIDEO,     4        /* Enable video mode  */
+
+.set MB_FLAGS,          MB_FLAG_ALIGNED | MB_FLAG_MEMINFO
+.set MB_MAGIC,          0x1BADB002
+.set MB_CHECKSUM,       -(MB_MAGIC + MB_FLAGS)
+
+.balign 16
+.code32
+
+.globl _start
+
+.section                ".multiboot", "ax"
+header:
+.align 4
+    .long               MB_MAGIC
+    .long               MB_FLAGS
+    .long               MB_CHECKSUM
+
+    .long               0       /* header_addr  */
+    .long               0       /* load_addr */
+    .long               0       /* load_end_addr */
+    .long               0       /* bss_end_addr */
+    .long               0       /* entry_addr */
+
+    .long               0       /* Video mode type */
+    .long               1024    /* Video width */
+    .long               768     /* Video height */
+    .long               32      /* Video depth */
+
+/* NuttX bin */
+
+.section                ".bin" , "ax"
+bin_start:
+    .incbin             "../../../nuttx.bin"
+
+.align 8
+bin_size:
+    .long               . - bin_start
+
+/* Multiboot args */
+
+multiboot_info_struct:
+    .long               0
+multiboot_magic:
+    .long               0
+
+.section                ".text"
+_start:
+
+    /* Saving multiboot args */
+
+    movl                %ebx, multiboot_info_struct
+    movl                %eax, multiboot_magic
+
+    /* memcpy(ENTRY_ADDR, bin_start, bin_size) */
+
+    movl                (bin_size), %ecx
+    movl                $bin_start, %esi
+    movl                $ENTRY_ADDR, %edi
+
+copy_loop:
+
+    /* Copy by bytes, make sure the addresses are not overlapped */
+
+    movb                (%esi), %al
+    movb                %al, (%edi)
+    inc                 %esi
+    inc                 %edi
+    loop                copy_loop
+
+    /* Jump to ENTRY_ADDR */
+
+    movl                (multiboot_info_struct), %ebx
+    movl                (multiboot_magic), %eax
+    movl                $ENTRY_ADDR, %ecx
+    jmp                 *%ecx
diff --git a/arch/x86_64/src/common/multiboot1.ld b/arch/x86_64/src/common/multiboot1.ld
new file mode 100644
index 0000000000..7667396101
--- /dev/null
+++ b/arch/x86_64/src/common/multiboot1.ld
@@ -0,0 +1,32 @@
+/****************************************************************************
+ * arch/x86_64/src/common/multiboot1.ld
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+ENTRY(_start)
+
+SECTIONS {
+	. = 1M;
+
+	.text : {
+		*(.multiboot)
+		*(.bin)
+		*(.text)
+		*(.note.gnu.*)
+	}
+}