diff --git a/arch/x86_64/src/Makefile b/arch/x86_64/src/Makefile index 8261aea14a..b841aeef3d 100644 --- a/arch/x86_64/src/Makefile +++ b/arch/x86_64/src/Makefile @@ -136,7 +136,8 @@ endif ifeq ($(CONFIG_ARCH_MULTIBOOT1),y) @echo "Generating: nuttx32 in ELF32/multiboot1" - $(Q) $(OBJCOPY) -R .realmode -R.note.* -O binary $(NUTTX) $(NUTTX).bin \ + $(Q) $(OBJCOPY) -R.realmode -R.note.* -O binary $(NUTTX) $(NUTTX).bin \ + && $(OBJCOPY) -j.realmode -O binary $(NUTTX) $(NUTTX)_realmode.bin \ && $(CC) -m32 -no-pie -nostdlib common/multiboot1.S \ -T common/multiboot1.ld -o $(NUTTX)32 endif diff --git a/arch/x86_64/src/common/multiboot1.S b/arch/x86_64/src/common/multiboot1.S index 914cfa9329..82e2b6a086 100644 --- a/arch/x86_64/src/common/multiboot1.S +++ b/arch/x86_64/src/common/multiboot1.S @@ -20,69 +20,37 @@ /* 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 */ +/* NuttX binary with multiboot1 header */ .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" +.section ".text" , "ax" _start: + /* We should manually copy .realmode section */ + /* Saving multiboot args */ movl %ebx, multiboot_info_struct movl %eax, multiboot_magic - /* memcpy(ENTRY_ADDR, bin_start, bin_size) */ + /* memcpy(0, realmode_start, realmode_size) */ - movl (bin_size), %ecx - movl $bin_start, %esi - movl $ENTRY_ADDR, %edi + movl (realmode_size), %ecx + movl $realmode_start, %esi + movl $0, %edi copy_loop: @@ -94,9 +62,23 @@ copy_loop: inc %edi loop copy_loop - /* Jump to ENTRY_ADDR */ + /* Jump to bin_start + 0x30, skip the multiboot1 header */ movl (multiboot_info_struct), %ebx movl (multiboot_magic), %eax - movl $ENTRY_ADDR, %ecx + movl $bin_start, %ecx + addl $0x30, %ecx jmp *%ecx + + +/* NuttX realmode section */ + +.section ".realmode", "ax" +realmode_start: + .incbin "../../../nuttx_realmode.bin" + +.align 8 +realmode_size: + .long . - realmode_start + + diff --git a/arch/x86_64/src/common/multiboot1.ld b/arch/x86_64/src/common/multiboot1.ld index 7667396101..7ea4b021e2 100644 --- a/arch/x86_64/src/common/multiboot1.ld +++ b/arch/x86_64/src/common/multiboot1.ld @@ -27,6 +27,7 @@ SECTIONS { *(.multiboot) *(.bin) *(.text) + *(.realmode) *(.note.gnu.*) } } diff --git a/arch/x86_64/src/intel64/intel64_head.S b/arch/x86_64/src/intel64/intel64_head.S index 5792067c2c..9b0cf93705 100644 --- a/arch/x86_64/src/intel64/intel64_head.S +++ b/arch/x86_64/src/intel64/intel64_head.S @@ -149,7 +149,7 @@ __reset_entry: mov %eax, %cr0 /* Long jump into protected mode. Hardcode the address. */ - ljmpl $0x8, $0x100000 + ljmpl $0x8, $start32_0 /* Loader GDT and GDTR */ .align(16) @@ -187,7 +187,7 @@ __ap_entry: mov %eax, %cr0 /* Long jump into protected mode. Hardcode the address. */ - ljmpl $0x8, $0x100000 + ljmpl $0x8, $start32_0 #endif /**************************************************************************** @@ -195,6 +195,34 @@ __ap_entry: ****************************************************************************/ .code32 + .section ".multiboot1", "a" +#ifdef CONFIG_ARCH_MULTIBOOT1 +.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) + +multiboot1_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 */ +#endif + .section ".loader.text", "ax" start32_0: diff --git a/boards/x86_64/intel64/qemu-intel64/scripts/qemu.ld b/boards/x86_64/intel64/qemu-intel64/scripts/qemu.ld index ecce7c852b..df9abc7f1c 100644 --- a/boards/x86_64/intel64/qemu-intel64/scripts/qemu.ld +++ b/boards/x86_64/intel64/qemu-intel64/scripts/qemu.ld @@ -34,6 +34,11 @@ SECTIONS . = 0x1M; _kernel_physical_start = .; + .multiboot1 : { + . = ALIGN(8); + KEEP(*(.multiboot1)) + } + .loader.text : { . = ALIGN(8); *(.loader.text)