From 126221df9708d101e1c150bc26ee967b5665735c Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Fri, 13 Sep 2024 18:55:20 +0800 Subject: [PATCH] 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 --- .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(-) create mode 100644 arch/x86_64/src/common/multiboot1.S create mode 100644 arch/x86_64/src/common/multiboot1.ld 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.*) + } +}