1// Copyright 2018 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <asm.h>
6#include <arch/x86/asm.h>
7#include <zircon/boot/multiboot.h>
8
9// Multiboot runs in 32-bit protected mode.
10.code32
11
12// The Multiboot header identifies this as a Multiboot-compliant OS image
13// and requires that the boot loader provide the memory map.  The rest of
14// of the loading details duplicate the information in the ELF file and
15// program headers.  The boot loader should do the same thing whether it
16// uses the multiboot_header_t here or the ELF e_entry and PT_LOAD headers.
17.section .multiboot.header,"a",%progbits
18.balign 4
19DATA(multiboot_header)
20    .int MULTIBOOT_HEADER_MAGIC                             // magic
21    .int MULTIBOOT_HEADER_FLAGS                             // flags
22    .int -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) // checksum
23    .int multiboot_header                                   // header_addr
24    .int PHYS_LOAD_ADDRESS                                  // load_addr
25    .int edata                                              // load_end
26    .int end                                                // bss_end_addr
27    .int _start                                             // entry_addr
28END_DATA(multiboot_header)
29
30// This is the Multiboot entry point.  The boot loader passes arguments in
31// %eax and %ebx.  The C regparm ABI takes them in %eax and %edx.  A
32// Multiboot-compliant boot loader provides a usable 32-bit segmentation
33// environment with flat segments, but does not provide a stack.
34.section .text._start,"ax",%progbits
35FUNCTION(_start)
36    // Save the first argument from the boot loader.
37    mov %eax, %edx
38
39    // First off, zero the bss area.
40    cld
41    xor %eax, %eax
42    mov $edata, %edi
43    mov $end, %ecx
44    sub %edi, %ecx
45    rep stosb
46
47    // Switch to our stack.
48    mov $stack_end, %esp
49    xor %ebp, %ebp
50
51    // Clear the IDT to zero address and zero limit, so any trap is sure to
52    // get a triple-fault.  We've just cleared the bss containing the stack,
53    // so these bytes are known to be zero.
54    lidt -6(%esp)
55
56    // Move the arguments into place and call:
57    // noreturn void multiboot_main(uint32_t magic, multiboot_info_t* info);
58    mov %edx, %eax
59    mov %ebx, %edx
60    call multiboot_main
61
62    // Fault if the C code returns.
630:  ud2
64    jmp 0b
65END_FUNCTION(_start)
66
67.section .bss.stack,"aw",%nobits
68DATA(stack)
69    .skip 4096
70    .balign 16
71stack_end:
72END_DATA(stack)
73