Mass convert NASM -> GNU as
authorJack Miller <jack@codezen.org>
Mon, 19 Sep 2016 20:41:52 +0000 (15:41 -0500)
committerJack Miller <jack@codezen.org>
Mon, 19 Sep 2016 20:41:52 +0000 (15:41 -0500)
I made the choice to use NASM back when this was a toy project, but now
I'm a bit more concerned with portability, and the amount of work it
would take to self-host. Having one consistent assembler across
platforms is desirable... even if the assembly is platform specific.

This is a bit prospective since the kernel only supports x64 anyway, but
I'm about to start writing a bunch of assembly for the Vua VM, so I
figured if I'm going to shuffle assemblers, now is a better time than a
few years down the road when it's even more of an ordeal.

For the record, I'm still not a fan of AT&T syntax for assembly, but I
decided to go with it. Partially because of consistency with Linux, and
therefore a swath of developers that touch x64 assembly regularly,
partially because of consistency with the inline assembly in Viridis
already, and partially because some of the conventions have grown on me
(like movq instead of mov qword)

In fact, to my surprise, the thing that pissed me off the most in this
port was as' weirdness a tool, rather than its conventions.

I couldn't, for example, get the ISR macro to properly generate named
labels correctly when called with a counter variable instead of a plain
number because (I'm assuming) the labels don't get further expanded
after they're emitted.

Or how I don't think there's a symbol for the top of the file's position
(like NASM's $$) which forces you to use .org instead of .fill like
TIMES.

Or how as can't generate binaries directly, like NASM can, which forces
you to pass object files through ld which, for some reason, still cares
about finding a _start symbol even though that's completely useless
information for binary output.

tl;dr NASM is a much better human facing assembler than as, it's too bad
it only supports a single platform and isn't integrated tightly with my
C compiler =/

Makefile
asm/gdt.asm
asm/head.asm
asm/idt.asm
asm/realmode.asm-bin
asm/rm.asm
boot/efi.asm
boot/fixup_stub.sh
include/asm/gdt.h
include/asm/idt.h
kernel/platforms/efi/efi_call.asm

index 40f7da3..b51f198 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 CC = gcc
 LD = ld
-NASM=nasm
 CPP=cpp
+AS=as
 
 MAJOR=0
 MINOR=1
@@ -13,7 +13,7 @@ GIT_REV=$(shell git describe --always)
 CPPFLAGS = -I ${INCLUDE_DIRS} -D__GIT_VERSION__='"$(GIT_REV)"' -D__MAJOR_VERSION__=$(MAJOR) -D__MINOR_VERSION__=$(MINOR)
 CFLAGS = ${CPPFLAGS} -c -std=gnu99 -pedantic -Wall -nostdlib -ffreestanding -mcmodel=kernel -g
 LDFLAGS = -T linker.ld -nostdlib -n
-NASMFLAGS = -f elf64
+ASFLAGS =
 
 SRC_C = $(wildcard boot/grub_sig.c kernel/*.c kernel/platforms/*.c kernel/platforms/*/*.c mm/*.c vua/*.c)
 OBJ_C = ${SRC_C:.c=.o}
@@ -34,15 +34,16 @@ all: viridis-efi
        @${CC} ${CFLAGS} $< -o $@
 
 %.bin : %.asm-bin
-       @echo NASM bin $<
+       @echo AS bin $<
        @${CPP} ${CPPFLAGS} -D__ASSEMBLY__ $< > $@.tmp
-       @${NASM} -f bin $@.tmp -o $@
-       @rm $@.tmp
+       @${AS} ${ASFLAGS} $@.tmp -o $@.o
+       @ld -Ttext 0x2000 --oformat binary -o $@ $@.o
+       @rm $@.tmp $@.o
 
 %.o : %.asm ${BIN_OBJ}
-       @echo NASM $<
+       @echo AS $<
        @${CPP} ${CPPFLAGS} -D__ASSEMBLY__ $< > $@.tmp
-       @${NASM} ${NASMFLAGS} $@.tmp -o $@
+       @${AS} ${ASFLAGS} $@.tmp -o $@
        @rm $@.tmp
 
 viridis: ${OBJ} linker.ld
index b7669e6..ce435a2 100644 (file)
@@ -1,57 +1,57 @@
-BITS 32
-SECTION .text_early
+.code32
+.section .text_early, "ax"
 
 #include <memmap.h>
 #include <asm/gdt.h>
 
-GLOBAL GDTR_32
-GLOBAL GDTR_64
+.global GDTR_32
+.global GDTR_64
 
-ALIGN 8
+.align 8
 GDTR_32:
-DW (GDTEND - GDT - 1)
-DQ GDT                  // Pad out this GDTR so we can use
+.word (GDTEND - GDT - 1)
+.quad GDT               // Pad out this GDTR so we can use
                         // the 32-bit version from long mode
                         // in efi_entry
 
-ALIGN 8
+.align 8
 GDTR_64:
-DW (GDTEND - GDT - 1)
-DQ (GDT + VIRT_BASE)
+.word (GDTEND - GDT - 1)
+.quad (GDT + VIRT_BASE)
 
-GLOBAL CODE_SEL_32
-GLOBAL DATA_SEL
-GLOBAL CODE_SEL_64
+.global CODE_SEL_32
+.global DATA_SEL
+.global CODE_SEL_64
 
-ALIGN 8
+.align 8
 GDT:
     /* NULL descriptor */
     GDTENTRY    0, 0x0, 0x0
     /* Code descriptor (Compat) */
-CODE_SEL_32 EQU $-GDT
+.equ CODE_SEL_32, .-GDT
     GDTENTRY    FLAGS_CODE_32, 0x0, 0xFFFFF
     /* Data descriptor (Compat) */
-DATA_SEL EQU $-GDT
+.equ DATA_SEL, .-GDT
     GDTENTRY    FLAGS_DATA_32, 0x0, 0xFFFFF
     /* Code descriptor (Long) */
-CODE_SEL_64 EQU $-GDT
+.equ CODE_SEL_64, .-GDT
     GDTENTRY    FLAGS_CODE_64, 0x0, 0xFFFFF
 GDTEND:
 
-GLOBAL populate_gdt
+.global populate_gdt
 populate_gdt:
-    lgdt[GDTR_32]
+    lgdt GDTR_32
     ret
 
-BITS 64
+.code64
 
-GLOBAL populate_gdt64
+.global populate_gdt64
 populate_gdt64:
-    lgdt[GDTR_32]
+    lgdt GDTR_32
     ret
 
-GLOBAL fixup_gdtr
+.global fixup_gdtr
 fixup_gdtr:
-    mov rax, VIRT_BASE + GDTR_64
-    lgdt[rax]
+    mov $(VIRT_BASE + GDTR_64), %rax
+    lgdt (%rax)
     ret
index 4679ffe..4574931 100644 (file)
@@ -1,51 +1,51 @@
-BITS 32
+.code32
 
 #include <memmap.h>
 #include <asm/boot.h>
 
 /* main.c */
-EXTERN main
+.extern main
 
 /* gdt.asm */
-EXTERN populate_gdt
-EXTERN populate_gdt64
-EXTERN fixup_gdtr
-EXTERN DATA_SEL
-EXTERN CODE_SEL_32
-EXTERN CODE_SEL_64
+.extern populate_gdt
+.extern populate_gdt64
+.extern fixup_gdtr
+.extern DATA_SEL
+.extern CODE_SEL_32
+.extern CODE_SEL_64
 
 /* idt.asm */
-EXTERN populate_idt
-EXTERN fixup_idtr
+.extern populate_idt
+.extern fixup_idtr
 
 /* linker.ld */
-EXTERN kernel_size
+.extern kernel_size
 
 /* We specially link this at our load address to simplify jmps. */
-SECTION .text_early
+.section .text_early, "ax"
 
-GLOBAL boot_header
+.global boot_header
 
 boot_header:
 flags:
-    DD 0
+    .long 0
 info_ptr:
-    DQ 0
+    .quad 0
 memmap_ptr:
-    DQ 0
+    .quad 0
 end_structures:
-    DQ 0
+    .quad 0
 
-GLOBAL efi_gop_mode_phys
-GLOBAL efi_gop_info_phys
+.global efi_gop_mode_phys
+.global efi_gop_info_phys
 
 efi_gop_mode_phys:
-    DQ 0, 0, 0, 0, 0
+    .quad 0, 0, 0, 0, 0
 
 efi_gop_info_phys:
-    DQ 0, 0, 0, 0, 0
+    .quad 0, 0, 0, 0, 0
 
-GLOBAL entry
+.global entry
 
 entry:
     /* Disable interrupts while we move memory descriptors over from
@@ -54,8 +54,8 @@ entry:
 
     cli
 
-    or dword [flags], BOOT_GRUB
-    mov dword [info_ptr], ebx
+    orl $(BOOT_GRUB), (flags)
+    movl %ebx, (info_ptr)
 
     /* Assume that GRUB setup enough stack for us to do a call. */
     /* This only does lgdt */
@@ -65,20 +65,20 @@ entry:
     /* Clear ESI, which is use as the extra allocation space to
      * account for after the kernel. GRUB boot doesn't do this
      */
-    xor esi, esi
+    xor %esi, %esi
 
     /* Reload code segment, jumping to host_gdt load (not link) */
-    jmp CODE_SEL_32:host_gdt
+    ljmpl $0x8, $host_gdt
 
 /* The EFI entry point. We're already in long mode, but we're still
  * using the EFI stack and GDT.
  */
 
-BITS 64
+.code64
 
 hostjmp:
-    DQ host_gdt
-    DW CODE_SEL_32
+    .quad host_gdt
+    .long CODE_SEL_32
 
 /* From efi.asm:
  * R13 = GOP pointer, or 0x0
@@ -90,54 +90,57 @@ efi_entry:
     cli
     call populate_gdt64
 
-    or dword [flags], BOOT_EFI
-    mov qword [info_ptr], r14
-    mov qword [memmap_ptr], r15
+    orl $(BOOT_EFI), (flags)
+    movq %r14, (info_ptr)
+    movq %r15, (memmap_ptr)
 
-    cmp r13, 0
+    cmp 0, %r13
     jne vid_ok
 
-    or dword [flags], BOOT_NOVID
+    orl $(BOOT_NOVID), (flags)
 
 vid_ok:
     /* Extra allocation of a page for our memory map */
-    mov esi, PAGE_SIZE
+    mov $(PAGE_SIZE), %esi
 
-    jmp qword far [hostjmp]
+    pushq $0x8
+    pushq $(host_gdt)
+    lretq
 
 /* Host GDT, beginning of common GRUB / EFI code. The header
  * should be filled out and ESI = extra allocation
  */
 
-BITS 32
+.code32
+
 host_gdt:
     /* Setup data segments to new offset in our own GDT */
-    mov eax, DATA_SEL
-    mov ds, eax
-    mov es, eax
-    mov fs, eax
-    mov gs, eax
-    mov ss, eax
+    mov $(DATA_SEL), %eax
+    mov %eax, %ds
+    mov %eax, %es
+    mov %eax, %fs
+    mov %eax, %gs
+    mov %eax, %ss
 
     /* Setup our stack, paging code will start to use it. */
-    mov esp, STACK_TOP_PHYS
-    mov ebp, esp
+    mov $(STACK_TOP_PHYS), %esp
+    mov %esp, %ebp
 
     call populate_idt
 
     /* Calculate size of early structures */
 
     /* eax = size of kernel, rounded up to page size */
-    mov eax, kernel_size
-    add eax, PAGE_MASK
-    and eax, ~PAGE_MASK
+    mov $kernel_size, %eax
+    add $(PAGE_MASK), %eax
+    and $(~PAGE_MASK), %eax
 
     /* ebx = end of kernel address, rounded up*/
-    mov ebx, eax
-    add ebx, KERNEL_START
+    mov %eax, %ebx
+    add $(KERNEL_START), %ebx
 
     /* Add our extra alloc space for EFI structures */
-    add ebx, esi
+    add %esi, %ebx
 
     /* Now we want a count of how many page table pages it will take to map
      * this. Because of our chosen target address, we get half of the first page table
@@ -153,13 +156,13 @@ host_gdt:
      */
 
     /* ecx = pte index of first kernel page */
-    mov ecx, PTE(KERNEL_START)
+    mov $(PTE(KERNEL_START)), %ecx
 
     /* edx = page structure count, initial PT and  PD/PDP/PML4 already counted. */
-    mov edx, 4
+    mov $4, %edx
 
 count_early:
-    sub eax, PAGE_SIZE
+    sub $(PAGE_SIZE), %eax
 
     /* If this would be the 512th PTE, it's actually PTE 0 of another page
      * table page. Roughly:
@@ -174,22 +177,22 @@ count_early:
      */
 
     /* if */
-    cmp ecx, 512
+    cmp $512, %ecx
     jne no_new_pt
 
     /* then */
-    add edx, 1
-    mov ecx, 0
+    add $1, %edx
+    mov $0, %ecx
     jmp ce_loop_end
 
     /* else */
 no_new_pt:
-    add ecx, 1
+    add $1, %ecx
 
     /* remaining loop */
 ce_loop_end:
 
-    cmp eax, 0
+    cmp $0, %eax
     jne count_early
 
     /* Summary:
@@ -199,16 +202,16 @@ ce_loop_end:
      */
 
     /* ecx = end of kernel paging addresses */
-    mov ecx, edx
-    shl ecx, PAGE_SHIFT
-    add ecx, ebx
-    add ecx, PAGE_SIZE
+    mov %edx, %ecx
+    shl $(PAGE_SHIFT), %ecx
+    add %ebx, %ecx
+    add $(PAGE_SIZE), %ecx
 
-    mov eax, ebx
+    mov %ebx, %eax
 zero_page_mem:
-    mov dword [eax], 0x0
-    add eax, 4
-    cmp eax, ecx
+    movl $0, (%eax)
+    add $4, %eax
+    cmp %eax, %ecx
     jne zero_page_mem
 
     /* Summary:
@@ -223,14 +226,14 @@ zero_page_mem:
     /* First, map the PML4 into itself (see memmap.h) */
 
     /* eax = address of PML4[510]*/
-    mov eax, ebx
-    add eax, (8 * 510)
+    mov %ebx, %eax
+    add $(8 * 510), %eax
 
     /* edx = PML4 address + flags */
-    mov edx, ebx
-    or  edx, (PF_RW | PF_P)
+    mov %ebx, %edx
+    or  $(PF_RW | PF_P), %edx
 
-    mov dword [eax], edx
+    movl %edx, (%eax)
 
     /* Now, map two PDPs, one where we want our kernel, and one
      * where we'll end up after we start paging but before we jump to our
@@ -262,104 +265,104 @@ zero_page_mem:
 
     /* First, the scrap mapping */
 
-    mov eax, ebx
-    add eax, 8 * PML4E(KERNEL_START)
+    mov %ebx, %eax
+    add $(8 * PML4E(KERNEL_START)), %eax
 
-    mov edx, ebx
-    add edx, PAGE_SIZE
-    or  edx, (PF_RW | PF_P)
+    mov %ebx, %edx
+    add $(PAGE_SIZE), %edx
+    or  $(PF_RW | PF_P), %edx
 
-    mov dword [eax], edx
+    movl %edx, (%eax)
 
     /* Now, the real entry */
 
-    mov eax, ebx
-    add eax, 8 * PML4E(VIRT_BASE | KERNEL_START)
+    mov %ebx, %eax
+    add $(8 * PML4E(VIRT_BASE | KERNEL_START)), %eax
 
-    mov dword [eax], edx
+    movl %edx, (%eax)
 
     /* Onto the PDP */
 
-    mov eax, ebx
-    add eax, (8 * PDPE(KERNEL_START)) + PAGE_SIZE
+    mov %ebx, %eax
+    add $((8 * PDPE(KERNEL_START)) + PAGE_SIZE), %eax
 
-    mov edx, ebx
-    add edx, 2*PAGE_SIZE
-    or  edx, (PF_RW | PF_P)
+    mov %ebx, %edx
+    add $(2*PAGE_SIZE), %edx
+    or  $(PF_RW | PF_P), %edx
 
-    mov dword [eax], edx
+    movl %edx, (%eax)
 
-    mov eax, ebx
-    add eax, (8 * PDPE(VIRT_BASE | KERNEL_START)) + PAGE_SIZE
+    mov %ebx, %eax
+    add $((8 * PDPE(VIRT_BASE | KERNEL_START)) + PAGE_SIZE), %eax
 
-    mov edx, ebx
-    add edx, 2*PAGE_SIZE
-    or  edx, (PF_RW | PF_P)
+    mov %ebx, %edx
+    add $(2*PAGE_SIZE), %edx
+    or  $(PF_RW | PF_P), %edx
 
-    mov dword [eax], edx
+    movl %edx, (%eax)
 
     /* Now the PD, which is the same for both */
 
-    mov eax, ebx
-    add eax, (8 * PDE(KERNEL_START)) + (2*PAGE_SIZE)
+    mov %ebx, %eax
+    add $((8 * PDE(KERNEL_START)) + (2*PAGE_SIZE)), %eax
 
-    mov edx, ebx
-    add edx, 3*PAGE_SIZE
+    mov %ebx, %edx
+    add $(3*PAGE_SIZE), %edx
 
     /* Remember ecx? It's end address of paging structures, use it to know when
      * we've mapped all the PTs
      */
 
 write_next_pde:
-    mov esi, edx
-    or  esi, (PF_RW | PF_P)
+    mov %edx, %esi
+    or  $(PF_RW | PF_P), %esi
 
-    mov dword [eax], esi
+    movl %esi, (%eax)
 
-    add eax, 8
-    add edx, PAGE_SIZE
-    cmp edx, ecx
+    add $8, %eax
+    add $(PAGE_SIZE), %edx
+    cmp %ecx, %edx
     jne write_next_pde
 
     /* Fill out all of the PTEs */
 
     /* Start with the stack */
-    mov eax, ebx
-    add eax, (8 * PTE(STACK_ADDR_VIRT_32)) + (3*PAGE_SIZE)
+    mov %ebx, %eax
+    add $((8 * PTE(STACK_ADDR_VIRT_32)) + (3*PAGE_SIZE)), %eax
 
-%assign i 0
-%rep STACK_PAGES
-    mov dword [eax], ((STACK_PAGES_PHYS + PAGE_SIZE * i) | PF_RW | PF_P)
-    add eax, 8
-%assign i (i+1)
-%endrep
+.set i, 0
+.rept STACK_PAGES
+    movl $(((STACK_PAGES_PHYS + PAGE_SIZE * i) | PF_RW | PF_P)), (%eax)
+    add $8, %eax
+.set i, i+1
+.endr
 
     /* Whose PTEs are adjacent to the kernel's so we don't need to mess with
      * eax
      */
 
-    mov edx, KERNEL_START
+    mov $(KERNEL_START), %edx
 
 write_next_pte:
-    mov esi, edx
-    or  esi, (PF_RW | PF_P)
+    mov %edx, %esi
+    or  $(PF_RW | PF_P), %esi
 
-    mov dword [eax], esi
+    movl %esi, (%eax)
 
-    add eax, 8
-    add edx, PAGE_SIZE
-    cmp edx, ebx
+    add $8, %eax
+    add $(PAGE_SIZE), %edx
+    cmp %edx, %ebx
     jne write_next_pte
 
-    mov dword [end_structures], ecx
+    movl %ecx, (end_structures)
 
     /* Enable CR4.PAE (bit 5) */
-    mov eax, cr4
-    or  eax, (1 << 5)
-    mov cr4, eax
+    mov %cr4, %eax
+    or  $(1 << 5), %eax
+    mov %eax, %cr4
 
     /* Put PML4 address in CR3 */
-    mov cr3, ebx
+    mov %ebx, %cr3
 
     /* Set EFER.LME (bit 8) to enable Long Mode
      * EFER is a model specific register (MSR).
@@ -368,38 +371,39 @@ write_next_pte:
      * also take edx:eax and write it to the msr
      */
 
-    mov ecx, 0xc0000080
+    mov $0xc0000080, %ecx
     rdmsr
-    or  eax, (1 << 8)
+    or  $(1 << 8), %eax
     wrmsr
 
     /* Set CR0.PG (bit 31) to enable paging */
-    mov eax, cr0
-    or  eax, (1 << 31)
-    mov cr0, eax
+    mov %cr0, %eax
+    or  $(1 << 31), %eax
+    mov %eax, %cr0
 
     /* Get into 64-bit to perform jump to 0xFFFF8...*/
-    jmp        0x18:cleanup_32
+    ljmp $(0x18), $(cleanup_32)
+
+.align 4
 cleanup_32:
 
     /* Jump to proper 0xF... address of cleanup_64 */
-BITS 64
+.code64
 
-    mov rax, VIRT_BASE
-    add rax, cleanup_64
-    jmp rax
+    mov $(VIRT_BASE), %rax
+    add $(cleanup_64), %rax
+    jmp *%rax
 
 cleanup_64:
-
     /* Hooray! EFER.LMA should be set (long mode active),
      * and our code segment is 64-bit!
      */
 
     /* Update our stacks to the new paged mapping, resetting the stack */
 
-    mov rax, STACK_TOP_VIRT
-    mov rsp, rax
-    mov rbp, rax
+    mov $(STACK_TOP_VIRT), %rax
+    mov %rax, %rsp
+    mov %rax, %rbp
 
     /* Move GDTR / IDTR addresses to new 0xFFFF8....... */
     call fixup_gdtr
@@ -419,23 +423,23 @@ cleanup_64:
      */
 
     /* mov rax, PDPE_ADDR(KERNEL_START) */
-    mov rax, 0xffffff7fbfc00000
-    mov dword [rax], 0x0
+    mov $0xffffff7fbfc00000, %rax
+    movq $0, (%rax)
 
     /* mov rax, PML4E_ADDR(KERNEL_START) */
-    mov rax, 0xffffff7fbfdfe000
-    mov dword [rax], 0x0
+    mov $0xffffff7fbfdfe000, %rax
+    movq $0, (%rax)
 
     /* Reset CR3 to update. */
-    mov rax, cr3
-    mov cr3, rax
+    mov %cr3, %rax
+    mov %rax, %cr3
 
     /* Grab first argument, corrected boot_header address */
-    mov rdi, VIRT_BASE
-    add rdi, boot_header
+    mov $(VIRT_BASE), %rdi
+    add $(boot_header), %rdi
 
     /* Move to rax first to avoid linker relocation truncation. */
-    mov rax, main
+    mov $(main), %rax
 
-    call rax
-    jmp $   // We should never get here.
+    call *%rax
+    jmp .   // We should never get here.
index 2e69614..a4fdbf3 100644 (file)
@@ -1,5 +1,5 @@
-BITS 32
-SECTION .text_early
+.code32
+.section .text_early, "ax"
 
 #include <memmap.h>
 
@@ -13,168 +13,163 @@ SECTION .text_early
 
 /* IDTR, just like GDTR */
 
-ALIGN 8
+.align 8
 IDTR:
-DW (IDTEND - IDT - 1)
-DQ IDT
+.word (IDTEND - IDT - 1)
+.quad IDT
 
 /* Use 64-bit IDTE format, even though we assume 32-bit addresses since 
  * we're defining them here.
  */
 
 bigisr:
-DQ isr0
+.quad isr0
 
-ALIGN 8
+.align 8
 IDT:
-%assign i 0
-%rep IDT_ENTRIES
+.set i, 0
+.rept IDT_ENTRIES
 IDTENTRY 0
-%assign i (i+1)
-%endrep
+.set i, (i+1)
+.endr
 IDTEND:
 
-GLOBAL populate_idt
+.global populate_idt
 populate_idt:
-    mov eax, IDT
-    mov ebx, [bigisr]
-    or ebx, (VIRT_BASE & 0xFFFFFFFF)
+    mov $IDT, %eax
+    mov (bigisr), %ebx
+    or $(VIRT_BASE & 0xFFFFFFFF), %ebx
 
 idt_init_one:
     /* Target Low (word) */
-    mov ecx, ebx
-    mov word [eax], cx
-    add eax, 10
+    mov %ebx, %ecx
+    movw %cx, (%eax)
+    add $10, %eax
 
     /* Target High (word) */
-    shr ecx, 16
-    mov word[eax], cx
-    add eax, 2
+    shr $16, %ecx
+    movw %cx, (%eax)
+    add 2, %eax
 
     /* Long Mode Target High 32 */
-    mov dword[eax], (VIRT_BASE >> 32)
-    add eax, 4
+    movl $(VIRT_BASE >> 32), (%eax)
+    add $4, %eax
 
-    mov dword[eax], 0
-    add eax, 4
+    movl $0, (%eax)
+    add $4, %eax
 
-    add ebx, ISR_SIZE
+    add $(ISR_SIZE), %ebx
 
-    cmp eax, IDTEND
-    jl idt_init_one
+    cmp $IDTEND, %eax
+    jge idt_init_one
 
-    lidt[IDTR]
+    lidt IDTR
     ret
 
-BITS 64
+.code64
 
-GLOBAL fixup_idtr
+.global fixup_idtr
 fixup_idtr:
-    mov rax, VIRT_BASE + IDTR + 2
+    movq $(VIRT_BASE + IDTR + 2), %rax
 
-    mov rbx, VIRT_BASE + IDT
+    movq $(VIRT_BASE + IDT), %rbx
 
-    mov qword[rax], rbx
+    movq %rbx, (%rax)
 
-    sub rax, 2
-    lidt[rax]
+    sub $2, %rax
+    lidt (%rax)
     ret
 
-SECTION .text
+.section ".text"
 
 /* Save/restore order from regs.h */
 
-%macro SAVE_ALL 0
-    push rdi
-    push rsi
-    push rdx
-    push rcx
-    push r8
-    push r9
-    push rax
-    push r10
-    push r11
-    push rbx
-    push rbp
-    push r12
-    push r13
-    push r14
-    push r15
-%endmacro
-
-%macro RESTORE_ALL 0
-    pop r15
-    pop r14
-    pop r13
-    pop r12
-    pop rbp
-    pop rbx
-    pop r11
-    pop r10
-    pop rax
-    pop r9
-    pop r8
-    pop rcx
-    pop rdx
-    pop rsi
-    pop rdi
-%endmacro
-
+.macro SAVE_ALL
+    push %rdi
+    push %rsi
+    push %rdx
+    push %rcx
+    push %r8
+    push %r9
+    push %rax
+    push %r10
+    push %r11
+    push %rbx
+    push %rbp
+    push %r12
+    push %r13
+    push %r14
+    push %r15
+.endm
+
+.macro RESTORE_ALL
+    pop %r15
+    pop %r14
+    pop %r13
+    pop %r12
+    pop %rbp
+    pop %rbx
+    pop %r11
+    pop %r10
+    pop %rax
+    pop %r9
+    pop %r8
+    pop %rcx
+    pop %rdx
+    pop %rsi
+    pop %rdi
+.endm
 
 /* Generate 256 interrupt routines. */
 
-/* 1 = ISR #
-   2 = builtin error code
-*/
-
-%macro ISR 2
-isr%1:
-%if %2 = 0
+.macro def_isr num err
+.if \err == 0
     push 0
-%else
+.else
     nop  // pad to keep isrs the same size
     nop  // push is 2 bytes, nop is 1 byte
-%endif
-    push %1
+.endif
+    push $\num
     jmp exception
-%endmacro
-
-ISR 0,  0
-ISR 1,  0
-ISR 2,  0
-ISR 3,  0
-ISR 4,  0
-ISR 5,  0
-ISR 6,  0
-ISR 7,  0
-ISR 8,  1
-ISR 9,  0
-ISR 10, 1
-ISR 11, 1
-ISR 12, 1
-ISR 13, 1
-ISR 14, 1
-ISR 15, 0
-ISR 16, 0
-ISR 17, 1
-
-ISRS:
-%assign i 18
-%rep (IDT_ENTRIES - 18)
-ISR i, 0
-%assign i (i+1)
-%endrep
+.endm
+
+isr0:
+def_isr 0,  0
+isr1:
+def_isr 1,  0
+def_isr 2,  0
+def_isr 3,  0
+def_isr 4,  0
+def_isr 5,  0
+def_isr 6,  0
+def_isr 7,  0
+def_isr 8,  1
+def_isr 9,  0
+def_isr 10, 1
+def_isr 11, 1
+def_isr 12, 1
+def_isr 13, 1
+def_isr 14, 1
+def_isr 15, 0
+def_isr 16, 0
+def_isr 17, 1
+
+.set i, 18
+.rept (IDT_ENTRIES - i)
+    def_isr i, 0
+    .set i, (i +1)
+.endr
 
 /* Common exception handler. An error code has been pushed either by the
  * processor or us, and the interrupt vector has been pushed as well.
-*/
+ */
 
-EXTERN dump_exception
+.extern dump_exception
 
 exception:
     SAVE_ALL
-    mov rdi, rsp
+    mov %rdi, %rsp
     call dump_exception
     RESTORE_ALL
-    add rsp, 16  // discard vector, and error
+    add %rsp, 16  // discard vector, and error
     iretq
index a0424c5..14dceee 100644 (file)
 #define CODESEL_32  0x8
 #define DATASEL_32  0x10
 
-BITS 16
-ORG 0x2000
-
+.code16
+.global _start
+_start:
     jmp main /* Skip our header data */
 
 crthree:
-    DD 0
+    .long 0
 gdtr:
-    DQ 0
+    .quad 0
 kernel_entry:
-    DQ 0
+    .quad 0
 
 main:
-    lgdt [cs:builtin_gdtr - REALMODE_PA]
+    lgdtl %cs:(builtin_gdtr - REALMODE_PA)
 
-    mov eax, cr0
-    or eax, 1
-    mov cr0, eax
+    mov %cr0, %eax
+    or $1, %eax
+    mov %eax, %cr0
 
-    jmp 0x8:host_local_gdt
+    ljmpw $(0x8), $(host_local_gdt)
 
-BITS 32
-host_local_gdt:
+.code32
 
-    mov ax, DATASEL_32
-    mov ss, ax
-    mov ds, ax
-    mov es, ax
-    mov fs, ax
-    mov gs, ax
+host_local_gdt:
+    mov $(DATASEL_32), %ax
+    mov %ax, %ss
+    mov %ax, %ds
+    mov %ax, %es
+    mov %ax, %fs
+    mov %ax, %gs
 
-    lidt [rm_idtr]
+    lidt rm_idtr
 
     /* While we're in 32 bit pmode, grab our APIC ID */
 
@@ -78,73 +78,73 @@ host_local_gdt:
      * Needs testing with > 256 IDs.
      */
 
-    mov ecx, MSR_IA32_APIC_BASE
+    mov $(MSR_IA32_APIC_BASE), %ecx
     rdmsr
 
-    and eax, BASE_ADDR_MASK
-    add eax, MMIO_OFFSET(APIC_ID)
+    and $(BASE_ADDR_MASK), %eax
+    add $(MMIO_OFFSET(APIC_ID)), %eax
 
-    mov edi, [eax]
-    rol edi, 8
+    mov (%eax), %edi
+    rol $8, %edi
 
     /* This init is taken from head.asm */
 
     /* PAE */
-    mov eax, cr4
-    or  eax, (1 << 5)
-    mov cr4, eax
+    mov %cr4, %eax
+    or  $(1 << 5), %eax
+    mov %eax, %cr4
 
     /* CR3 */
-    mov eax, [crthree]
-    mov cr3, eax
+    mov (crthree), %eax
+    mov %eax, %cr3
 
     /* Long Mode */
-    mov ecx, 0xc0000080
+    mov $(0xc0000080), %ecx
     rdmsr
-    or  eax, (1 << 8)
+    or  $(1 << 8), %eax
     wrmsr
 
     /* paging */
-    mov eax, cr0
-    or  eax, (1 << 31)
-    mov cr0, eax
+    mov %cr0, %eax
+    or  $(1 << 31), %eax
+    mov %eax, %cr0
 
-    jmp        0x18:go_64
+    ljmp $(0x18), $(go_64)
 go_64:
 
-BITS 64
+.code64
 
-    mov rax, [gdtr]
-    lgdt [rax]
+    mov (gdtr), %rax
+    lgdt (%rax)
 
     jmp kernel_gdt
 
 kernel_gdt:
     /* We now share a GDT with the rest of the kernel */
 
-    mov ax, DATASEL_32
-    mov ss, ax
-    mov ds, ax
-    mov es, ax
-    mov fs, ax
-    mov gs, ax
+    mov $(DATASEL_32), %ax
+    mov %ax, %ss
+    mov %ax, %ds
+    mov %ax, %es
+    mov %ax, %fs
+    mov %ax, %gs
 
-    mov rcx, KERNEL_STACK_VIRTUAL
+    mov $(KERNEL_STACK_VIRTUAL), %rcx
 
-    mov rax, rdi
-    mov rdx, STACK_V_SIZE
-    mul rdx
+    mov %rdi, %rax
+    mov $(STACK_V_SIZE), %rdx
+    mul %rdx
 
-    or rcx, rax
-    add rcx, (STACK_SIZE - 8)
-    mov rsp, rcx
+    or %rax, %rcx
+    add $(STACK_SIZE - 8), %rcx
+    mov %rcx, %rsp
 
-    jmp [kernel_entry]
+    jmpq *(kernel_entry)
 
-ALIGN 8
+.align 8
 builtin_gdtr:
-DW (builtin_gdt_end - builtin_gdt) - 1
-DQ builtin_gdt
+.word (builtin_gdt_end - builtin_gdt) - 1
+.quad builtin_gdt
 
 builtin_gdt:
 GDTENTRY    0, 0x0, 0x0
@@ -153,34 +153,23 @@ GDTENTRY    FLAGS_DATA_32, 0, 0xFFFFF
 GDTENTRY    FLAGS_CODE_64, 0, 0xFFFFF
 builtin_gdt_end:
 
-/* Push ISRs to 0x2400 */
-TIMES 0x400-($-$$) DB 0
-
-%macro RM_ISR 1
-isr%1:
-    jmp $
-%endmacro
-
-ISRS:
-%assign i 0
-%rep 21
-RM_ISR i
-%assign i (i+1)
-%endrep
+.align 0x400
+.rept 21
+jmp .
+.endr
 
 #define ISR_SIZE       2
 
-ALIGN 8
+.align 8
 RM_IDT:
-%assign i 0
-%assign a 0x2400
-%rep 21
+.set a, (REALMODE_PA + 0x400)
+.rept 21
 IDTENTRY a
-%assign a (a+ISR_SIZE)
-%endrep
+.set a, (a+ISR_SIZE)
+.endr
 RM_IDTEND:
 
-ALIGN 8
+.align 8
 rm_idtr:
-DW (RM_IDTEND - RM_IDT - 1)
-DQ RM_IDT
+.word (RM_IDTEND - RM_IDT - 1)
+.quad RM_IDT
index e771af6..1ca1b0b 100644 (file)
@@ -1,10 +1,12 @@
 /* Graft in the realmode binary */
 
-GLOBAL realmode_bin
-GLOBAL end_realmode_bin
+#include <asm/realmode.h>
+
+.global realmode_bin
+.global end_realmode_bin
 
 realmode_bin:
 
-INCBIN "asm/realmode.bin"
+.incbin "asm/realmode.bin"
 
 end_realmode_bin:
index d31b566..5e49812 100644 (file)
-BITS 64
-ORG 0
+# This PE header is hard coded here, and then fixed up later
 
-; This PE header is hard coded here, and then fixed up later 
+# Most of this taken from Linux's arch/x86/boot/header.S CONFIG_EFI_STUB code
+# UEFI spec 2.6 defines most of the special values in section 2.2.1
 
-; Most of this taken from Linux's arch/x86/boot/header.S CONFIG_EFI_STUB code
-; UEFI spec 2.6 defines most of the special values in section 2.2.1
+.code64
+.org 0
 
-    DB 0x4d         ; MZ - MS-DOS header 
-    DB 0x5a
+# This isn't used, but it shuts up ld
+.global _start
+_start:
 
-; Push to 0x3c
-TIMES 0x3c-($-$$) DB 0
-    DD pe_header
+    .byte 0x4d         # MZ - MS-DOS header
+    .byte 0x5a
+
+    .org 0x3c
+    .long pe_header
 
 pe_header:
-    DB 'PE'
-    DW 0
+    .ascii "PE"
+    .word 0
 
 coff_header:
-    DW 0x8664       ; x86-64 (UEFI spec) 
-    DW 4            ; nr_sections 
-    DD 0            ; TimeDateStamp 
-    DD 0            ; PointerToSymbolTable 
-    DD 1            ; NumberOfSymbols 
-
-    DW section_table - optional_header  ; SizeOfOptionalHeader 
-
-    DW 0x206        ;Characteristics
-                    ;IMAGE_FILE_DEBUG_STRIPPED |
-                    ;IMAGE_FILE_EXECUTABLE_IMAGE |
-                    ;IMAGE_FILE_LINE_NUMS_STRIPPED
+    .word 0x8664       # x86-64 (UEFI spec)
+    .word 4            # nr_sections
+    .long 0            # TimeDateStamp
+    .long 0            # PointerToSymbolTable
+    .long 1            # NumberOfSymbols
+
+    .word section_table - optional_header  # SizeOfOptionalHeader
+
+    .word 0x206        #Characteristics
+                       #IMAGE_FILE_DEBUG_STRIPPED |
+                       #IMAGE_FILE_EXECUTABLE_IMAGE |
+                       #IMAGE_FILE_LINE_NUMS_STRIPPED
                      
 optional_header:
-    DW 0x20b        ; PE32+ 
-    DB 0x02         ; MajorLinkerVersion 
-    DB 0x14         ; MinorLinkerVersion 
+    .word 0x20b        # PE32+
+    .byte 0x02         # MajorLinkerVersion
+    .byte 0x14         # MinorLinkerVersion
 
 size_of_code:
-    DD 0            ; SizeOfCode fill:0x1c 
+    .long 0            # SizeOfCode fill:0x1c
 
-    DD 0            ; SizeOfInitializedData 
-    DD 0            ; SizeOfUninitializedData 
+    .long 0            # SizeOfInitializedData
+    .long 0            # SizeOfUninitializedData
 
-    DD 0            ; AddressOfEntryPoint 
-    DD 0x200        ; BaseOfCode 
+    .long 0            # AddressOfEntryPoint
+    .long 0x200        # BaseOfCode
 
 extra_header_fields:
-    DQ 0            ; ImageBase 
-    DD 0x20          ; SectionAlignment (CONFIG_PHYSICAL_ALIGN on Linux) 
-    DD 0x20         ; FileAlignment 
-    DW 0            ; MajorOperatingSystemVersion 
-    DW 0            ; MinorOperatingSystemVersion 
-    DW 0            ; MajorImageVersion 
-    DW 0            ; MinorImageVersion 
-    DW 0            ; MajorSubsystemVersion 
-    DW 0            ; MinorSubsystemVersion 
-    DD 0            ; Win32VersionValue 
-
-    DD 0            ; SizeOfImage fill:0x50 
-
-    DD 0x200        ; SizeOfHeaders 
-    DD 0            ; CheckSum 
-    DW 0xa          ; Subsystem (EFI application) 
-    DW 0            ; DllCharacteristics 
-
-    DQ 0            ; SizeOfStackReserve 
-    DQ 0            ; SizeOfStackCommit 
-    DQ 0            ; SizeOfHeapReserve 
-    DQ 0            ; SizeOfHeapCommit 
-
-    DD 0            ; LoaderFlags 
-    DD 0x6          ; NumberOfRvaAndSizes 
+    .quad 0            # ImageBase
+    .long 0x20         # SectionAlignment (CONFIG_PHYSICAL_ALIGN on Linux)
+    .long 0x20         # FileAlignment
+    .word 0            # MajorOperatingSystemVersion
+    .word 0            # MinorOperatingSystemVersion
+    .word 0            # MajorImageVersion
+    .word 0            # MinorImageVersion
+    .word 0            # MajorSubsystemVersion
+    .word 0            # MinorSubsystemVersion
+    .long 0            # Win32VersionValue
+
+    .long 0            # SizeOfImage fill:0x50
+
+    .long 0x200        # SizeOfHeaders
+    .long 0            # CheckSum
+    .word 0xa          # Subsystem (EFI application)
+    .word 0            # DllCharacteristics
+
+    .quad 0            # SizeOfStackReserve
+    .quad 0            # SizeOfStackCommit
+    .quad 0            # SizeOfHeapReserve
+    .quad 0            # SizeOfHeapCommit
+
+    .long 0            # LoaderFlags
+    .long 0x6          # NumberOfRvaAndSizes
     
-    DQ 0            ; ExportTable 
-    DQ 0            ; ImportTable 
-    DQ 0            ; ResourceTable 
-    DQ 0            ; ExceptionTable 
-    DQ 0            ; CertificationTable 
-    DQ 0            ; BaseRelocationTable 
+    .quad 0            # ExportTable
+    .quad 0            # ImportTable
+    .quad 0            # ResourceTable
+    .quad 0            # ExceptionTable
+    .quad 0            # CertificationTable
+    .quad 0            # BaseRelocationTable
 
 section_table:
-    DB ".setup"
-    DB 0
-    DB 0            ; -- end of name -- 
-    DD 0            ; Size
-    DD 0            ; startup_{32, 64} 
-    DD 0            ; Size of initialized data on disk 
-    DD 0            ; startup_{32, 64} 
-    DD 0            ; PointerToRelocations 
-    DD 0            ; PointerToLineNumbers 
-    DW 0            ; NumberOfRelocations 
-    DW 0            ; NumberOfLineNumbers 
-    DD 0x60500020   ; Characteristics 
-
-    DB ".reloc"
-    DB 0
-    DB 0            ; -- end of name -- 
-    DD 0            ; Size
-    DD 0
-    DD 0            ; SizeOfRawData 
-    DD 0            ; PointerToRawData 
-    DD 0            ; PointerToRelocations 
-    DD 0            ; PointerToLineNumbers 
-    DW 0            ; NumberOfRelocations 
-    DW 0            ; NumberOfLineNumbers 
-    DD 0x42100040   ; Characteristics 
-
-    DB ".text"
-    DB 0
-    DB 0
-    DB 0            ; -- end of name -- 
-    DD 0            ; Size
-    DD 0
-    DD 0            ; SizeOfRawData 
-    DD 0            ; PointerToRawData 
-    DD 0            ; PointerToRelocations 
-    DD 0            ; PointerToLineNumbers 
-    DW 0            ; NumberOfRelocations 
-    DW 0            ; NumberOfLineNumbers 
-    DD 0x60500020   ; Characteristics 
-
-    DB ".bss"
-    DB 0
-    DB 0
-    DB 0
-    DB 0            ; -- end name -- 
-    DD 0            ; Size
-    DD 0
-    DD 0            ; SizeOfRawData 
-    DD 0            ; PointerToRawData 
-    DD 0            ; PointerToRelocations 
-    DD 0            ; PointerToLineNumbers 
-    DW 0            ; NumberOfRelocations 
-    DW 0            ; NumberOfLineNumbers 
-    DD 0x60500020   ; Characteristics 
-
-; Push to 510 (Linux's build.c requires this, but necessary for EFI only boot?)
-; either way, we need to know exactly where start is in the binary anyway.
-
-TIMES 510-($-$$) DB 0
-DW 0xAA55
-
-; EFI handoff (from UEFI 2.6 sec 2.3.4)
-; We're in long mode, all memory is identity mapped
-; We have a large amount of stack (>=128k)
-
-; RCX - EFI_HANDLE
-; RDX - EFI_SYSTEM_TABLE pointer
-; RSP - Return address
-
-; EFI call
-; Args: RCX, RDX, R8, R9 > stack (+32 because you must reserve stack space for register args)
-; RAX is returned
-; RBX, RBP, RDI, RSI, R12-15 are preserved by calls
-;
-; EFI table header (24 bytes)
-; u64 signature
-; u32 revision
-; u32 header_size
-; u32 crc32
-; u32 reserved
-
-;EFI system table
-; header
-; char *firmware_vendor;            24
-; u32 firmware_revision             32 <-- padded to align next val
-; u64 console_in_handle             40
-; efi_simple_text_input *func       48
-; u64 console_out_handle            56
-; efi_simple_text_output *stdout    64
-; u64 standard_error_handle         72
-; efi_simple_text_output *stderr    80
-; runtime_services *                88
-; boot_services *                   96
-; u64 number of entries             104
-; efi_configuration_table *         112
-
-;console out
-; reset                             0
-; output_string                     8
-
-;EFI boot services table
-; header
-; efi_raise_tpl *                   24
-; efi_restore_tpl *                 32
-; efi_allocate_pages *              40
-; efi_free_pages *                  48
-; efi_get_memory_map *              56
-; ...
-; handle_protocol                   152
-; ...
-; locate_handle                     176
-; ...
-; efi_exit_boot_services *          232
-; efi_get_monotonic_count *         240
-; efi_stall *                       248
-; efi_set_watchdog_timer            256
+    .ascii ".setup"
+    .byte 0
+    .byte 0            # -- end of name --
+    .long 0            # Size
+    .long 0            # startup_{32, 64}
+    .long 0            # Size of initialized data on disk
+    .long 0            # startup_{32, 64}
+    .long 0            # PointerToRelocations
+    .long 0            # PointerToLineNumbers
+    .word 0            # NumberOfRelocations
+    .word 0            # NumberOfLineNumbers
+    .long 0x60500020   # Characteristics
+
+    .ascii ".reloc"
+    .byte 0
+    .byte 0            # -- end of name --
+    .long 0            # Size
+    .long 0
+    .long 0            # SizeOfRawData
+    .long 0            # PointerToRawData
+    .long 0            # PointerToRelocations
+    .long 0            # PointerToLineNumbers
+    .word 0            # NumberOfRelocations
+    .word 0            # NumberOfLineNumbers
+    .long 0x42100040   # Characteristics
+
+    .ascii ".text"
+    .byte 0
+    .byte 0
+    .byte 0            # -- end of name --
+    .long 0            # Size
+    .long 0
+    .long 0            # SizeOfRawData
+    .long 0            # PointerToRawData
+    .long 0            # PointerToRelocations
+    .long 0            # PointerToLineNumbers
+    .word 0            # NumberOfRelocations
+    .word 0            # NumberOfLineNumbers
+    .long 0x60500020   # Characteristics
+
+    .ascii ".bss"
+    .byte 0
+    .byte 0
+    .byte 0
+    .byte 0            # -- end name --
+    .long 0            # Size
+    .long 0
+    .long 0            # SizeOfRawData
+    .long 0            # PointerToRawData
+    .long 0            # PointerToRelocations
+    .long 0            # PointerToLineNumbers
+    .word 0            # NumberOfRelocations
+    .word 0            # NumberOfLineNumbers
+    .long 0x60500020   # Characteristics
+
+# Push to 510 (Linux's build.c requires this, but necessary for EFI only boot?)
+# either way, we need to know exactly where start is in the binary anyway.
+
+.org 510
+.word 0xAA55
+
+# EFI handoff (from UEFI 2.6 sec 2.3.4)
+# We're in long mode, all memory is identity mapped
+# We have a large amount of stack (>=128k)
+
+# RCX - EFI_HANDLE
+# RDX - EFI_SYSTEM_TABLE pointer
+# RSP - Return address
+
+# EFI call
+# Args: RCX, RDX, R8, R9 > stack (+32 because you must reserve stack space for register args)
+# RAX is returned
+# RBX, RBP, RDI, RSI, R12-15 are preserved by calls
+#
+# EFI table header (24 bytes)
+# u64 signature
+# u32 revision
+# u32 header_size
+# u32 crc32
+# u32 reserved
+
+#EFI system table
+# header
+# char *firmware_vendor;            24
+# u32 firmware_revision             32 <-- padded to align next val
+# u64 console_in_handle             40
+# efi_simple_text_input *func       48
+# u64 console_out_handle            56
+# efi_simple_text_output *stdout    64
+# u64 standard_error_handle         72
+# efi_simple_text_output *stderr    80
+# runtime_services *                88
+# boot_services *                   96
+# u64 number of entries             104
+# efi_configuration_table *         112
+
+#console out
+# reset                             0
+# output_string                     8
+
+#EFI boot services table
+# header
+# efi_raise_tpl *                   24
+# efi_restore_tpl *                 32
+# efi_allocate_pages *              40
+# efi_free_pages *                  48
+# efi_get_memory_map *              56
+# ...
+# handle_protocol                   152
+# ...
+# locate_handle                     176
+# ...
+# efi_exit_boot_services *          232
+# efi_get_monotonic_count *         240
+# efi_stall *                       248
+# efi_set_watchdog_timer            256
 
 kernel_start:
-    DQ 0
+    .quad 0
 kernel_entry:
-    DQ 0
+    .quad 0
 boot_header:
-    DQ 0
+    .quad 0
 
 start:
     cli
-    call next           ; This puts our return address on the stack so we
-                        ; can figure out where we are.
+    call next           # This puts our return address on the stack so we
+                        # can figure out where we are.
 next:
-    mov r12, [rsp]      ; R12 = address of next in EFI
-    sub r12, next       ; R12 = offset from where we think we are
+    mov (%rsp), %r12    # R12 = address of next in EFI
+    sub $(next), %r12   # R12 = offset from where we think we are
 
-    mov r13, [rdx + 64] ; R13 = simple text output ptr
-    mov r14, rdx        ; R14 = copy of EFI_SYSTEM_TABLE
-    mov rsi, rcx        ; RSI = copy of EFI_HANDLE
+    mov 64(%rdx), %r13  # R13 = simple text output ptr
+    mov %rdx, %r14      # R14 = copy of EFI_SYSTEM_TABLE
+    mov %rcx, %rsi      # RSI = copy of EFI_HANDLE
 
-    mov rbx, [r13]      ; Reset
-    mov rcx, r13
-    mov rdx, 1
-    call rbx            ; Reset the screen()
+    mov (%r13), %rbx    # Reset
+    mov %r13, %rcx
+    mov $1, %rdx
+    call *%rbx          # Reset the screen()
 
-    mov rbx, [r13 + 8]  ; Output String
-    mov rcx, r13
-    mov rdx, banner
-    add rdx, r12
-    call rbx            ; Print our banner
+    mov 8(%r13), %rbx   # Output String
+    mov %r13, %rcx
+    mov $(banner), %rdx
+    add %r12, %rdx
+    call *%rbx          # Print our banner
 
-    mov r13, [r14 + 96] ; R13 = boot services
-    mov rbx, [r13 + 40] ; allocate_pages
-    mov rcx, 2          ; AllocateAddress
-    mov rdx, 2          ; EFILoaderData
+    mov 96(%r14), %r13  # R13 = boot services
+    mov 40(%r13), %rbx  # allocate_pages
+    mov $2, %rcx        # AllocateAddress
+    mov $2, %rdx        # EFILoaderData
 
-    mov rax, size_of_code
-    add rax, r12
-    mov r8, [eax]       ; R8 = size of code declared in header
+    mov $(size_of_code), %rax
+    add %r12, %rax
+    mov (%eax), %r8     # R8 = size of code declared in header
 
-    add r8, 6655        ; -1536 for ignoring setup code
-                        ; +4096 for mmap  page
-                        ; +4095 for rounding page up
+    add $6655, %r8      # -1536 for ignoring setup code
+                        # +4096 for mmap  page
+                        # +4095 for rounding page up
 
-    shr r8, 12          ; R8 = num pages from end of EFI header to end of kernel
-    mov r15, r8         ; save it off so we can use it for the copy
+    shr $12, %r8        # R8 = num pages from end of EFI header to end of kernel
+    mov %r8, %r15       # save it off so we can use it for the copy
 
-    mov r9, kernel_start
-    add r9, r12
-    mov rdi, [r9]       ; RDI = KERNEL_START
-    call rbx
+    mov $(kernel_start), %r9
+    add %r12, %r9
+    mov (%r9), %rdi     # RDI = KERNEL_START
+    call *%rbx
 
-    mov rcx, rdi        ; RCX = Start of copy dest
-    mov rax, payload_data
-    add rax, r12        ; RAX = Start of copy source
+    mov %rdi, %rcx      # RCX = Start of copy dest
+    mov $(payload_data), %rax
+    add %r12, %rax      # RAX = Start of copy source
 
-    shl r15, 12
-    add r15, rdi        ; R15 = End of copy dest
+    shl $12, %r15
+    add %rdi, %r15      # R15 = End of copy dest
 
 cp_loop:
-    mov rbx, [rax]
-    mov [rcx], rbx
-    add rax, 8
-    add rcx, 8
-    cmp r15, rcx
+    mov (%rax), %rbx
+    mov %rbx, (%rcx)
+    add $8, %rax
+    add $8, %rcx
+    cmp %rcx, %r15
     jne cp_loop
 
-    sub rcx, 4096       ; RCX = Address of extra page and mmap maxsize address
-    mov r15, rcx        ; R15 = Copy of memory map header address
-    mov rdi, 0          ; Clear RDI, used to indicate whether video info is inited
+    sub $4096, %rcx     # RCX = Address of extra page and mmap maxsize address
+    mov %rcx, %r15      # R15 = Copy of memory map header address
+    mov $0, %rdi        # Clear RDI, used to indicate whether video info is inited
 
-    ; Eventually, we'll use this extra page to hold the memory map, for now
-    ; use it as a scratch buffer to locate a framebuffer
+    # Eventually, we'll use this extra page to hold the memory map, for now
+    # use it as a scratch buffer to locate a framebuffer
 
-    mov rbx, [r13 + 176]    ; LocateHandle
-    mov rcx, 2              ; RCX = Search by protocol
+    mov 176(%r13), %rbx     # LocateHandle
+    mov $2, %rcx            # RCX = Search by protocol
 
-    mov rdx, gop_guid       ; RDX = GOP GUID
-    add rdx, r12
+    mov $(gop_guid), %rdx   # RDX = GOP GUID
+    add %r12, %rdx
 
-    mov r9, r15             ; Size of our buffer
-    mov qword [r15], 4088   ; 4096 - 8
+    mov %r15, %r9           # Size of our buffer
+    movq $4088, (%r15)      # 4096 - 8
 
-    sub rsp, 40
-    mov [rsp + 32], r15
-    add qword [rsp + 32], 8 ; Stack: Address of our buffer
-    call rbx
-    add rsp, 40
+    sub $40, %rsp
+    mov %r15, 32(%rsp)
+    addq $8, 32(%rsp)       # Stack: Address of our buffer
+    call *%rbx
+    add $40, %rsp
 
-    mov rbx, [r15]          ; If the returned size is 0, no GOP
-    cmp rbx, 0
+    mov (%r15), %rbx        # If the returned size is 0, no GOP
+    cmp $0, %rbx
     je  skip_vid
 
-    mov rbx, [r13 + 152]    ; HandleProtocol
-    mov rcx, [r15 + 8]      ; Pass in first returned EFI handle
-    mov rdx, gop_guid
-    add rdx, r12            ; GOP Guid
-    mov r8, r15             ; Beginning of page (overwriting query return)
+    mov 152(%r13), %rbx     # HandleProtocol
+    mov 8(%r15), %rcx       # Pass in first returned EFI handle
+    mov $(gop_guid), %rdx
+    add %r12, %rdx          # GOP Guid
+    mov %r15, %r8           # Beginning of page (overwriting query return)
 
-    sub rsp, 40
-    call rbx
-    add rsp, 40
+    sub $40, %rsp
+    call *%rbx
+    add $40, %rsp
 
-    ; Now that we've found the interface, copy the mode and info structs
-    ; to a known location after the boot header
+    # Now that we've found the interface, copy the mode and info structs
+    # to a known location after the boot header
 
-    mov rbx, [r15]          ; RBX = protocol struct
-    mov rcx, [rbx + 24]     ; RCX = mode struct
-    mov rdx, [rcx + 8]      ; RDX = info struct
+    mov (%r15), %rbx        # RBX = protocol struct
+    mov 24(%rbx), %rcx      # RCX = mode struct
+    mov 8(%rcx), %rdx       # RDX = info struct
 
-    push qword 5            ; 5 qwords
-    push rdx                ; info struct
+    pushq $5                # 5 qwords
+    push %rdx               # info struct
 
-    push qword 5            ; 5 qwords
-    push rcx                ; mode struct
+    pushq $5                # 5 qwords
+    push %rcx               # mode struct
 
-    mov rcx, 2                     ; structures to copy
-    mov rdx, boot_header       ; beginning of copy space
-    add rdx, r12
-    mov rdx, [rdx]
-    add rdx, 28             ; skip to efi_gop_mode 
+    mov $2, %rcx            # structures to copy
+    mov $(boot_header), %rdx# beginning of copy space
+    add %r12, %rdx
+    mov (%rdx), %rdx
+    add $28, %rdx           # skip to efi_gop_mode
 
 small_copy:
-    pop rax                 ; physical address
-    pop rbx                 ; qwords to copy
+    pop %rax                # physical address
+    pop %rbx                # qwords to copy
 scl:
-    mov rdi, [rax]
-    mov [rdx], rdi
-    add rdx, 8
-    add rax, 8
-    sub rbx, 1
-    cmp rbx, 0
+    mov (%rax), %rdi
+    mov %rdi, (%rdx)
+    add $8, %rdx
+    add $8, %rax
+    sub $1, %rbx
+    cmp $0, %rbx
     jne scl
 
-    sub rcx, 1
-    cmp rcx, 0
+    sub $1, %rcx
+    cmp $0, %rcx
     jne small_copy
 
-    mov rdi, 1              ; Set RDI, video info found
+    mov $1, %rdi            # Set RDI, video info found
 
 skip_vid:
-    mov rcx, r15
+    mov %r15, %rcx
 
-    mov rbx, [r13 + 56]     ; GetMemoryMap
-    mov qword [rcx], 4064   ; 4096 - 32
-    mov r8, rcx
-    add r8, 8               ; R8 = mapkey address
-    mov r9, r8
-    add r9, 8               ; R9 = descriptor size address
-    mov rdx, r9
-    add rdx, 8
+    mov 56(%r13), %rbx      # GetMemoryMap
+    movq $4064, (%rcx)      # 4096 - 32
+    mov %rcx, %r8
+    add $8, %r8             # R8 = mapkey address
+    mov %r8, %r9
+    add $8, %r9             # R9 = descriptor size address
+    mov %r9, %rdx
+    add $8, %rdx
 
-    sub rsp, 40
-    mov [rsp + 32], rdx     ; Stack: descriptor version address
-    add rdx, 8              ; RDX = Memory map address (after header stuff)
-    call rbx
-    add rsp, 40
+    sub $40, %rsp
+    mov %rdx, 32(%rsp)      # Stack: descriptor version address
+    add $8, %rdx            # RDX = Memory map address (after header stuff)
+    call *%rbx
+    add $40, %rsp
 
-    ; We've got our memory map, so exit boot services and stop the watchdog
+    # We've got our memory map, so exit boot services and stop the watchdog
 
-    mov rbx, [r13 + 232]    ; ExitBootServices
-    mov rcx, rsi            ; RCX = EFI Handle
-    mov rdx, [r15 + 8]      ; RDX = mapkey from GetMemoryMap()
-    call rbx
+    mov 232(%r13), %rbx     # ExitBootServices
+    mov %rsi, %rcx          # RCX = EFI Handle
+    mov 8(%r15), %rdx       # RDX = mapkey from GetMemoryMap()
+    call *%rbx
 
-    mov r13, rdi
+    mov %rdi, %r13
 
-    ; Expected in efi_entry:
-    ; R13 = video init boolean
-    ; R14 = EFI_SYSTEM_TABLE address
-    ; R15 = memory map address
+    # Expected in efi_entry:
+    # R13 = video init boolean
+    # R14 = EFI_SYSTEM_TABLE address
+    # R15 = memory map address
 
-    mov rax, kernel_entry
-    add rax, r12
-    jmp [rax]
+    mov $(kernel_entry), %rax
+    add %r12, %rax
+    jmpq *(%rax)
 
-; This looks messed up, but EFI strings are 2 bytes and
-; DW "whatever" just pads byte content out to a word size
+# This looks messed up, but EFI strings are 2 bytes and
+# .word "whatever" just pads byte content out to a word size
 
 banner:
-    DW  'V', 'i', 'r', 'i', 'd', 'i', 's', ' ', 'E', 'F', 'I', 0x0
+    .word  'V', 'i', 'r', 'i', 'd', 'i', 's', ' ', 'E', 'F', 'I', 0x0
 
 gop_guid:
-    DD 0x9042a9de
-    DW 0x23dc, 0x4a38
-    DB 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a
-
-;conout_guid:
-;    DD 0x387477c2
-;    DW 0x69c7, 0x11d2
-;    DB 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b
-
-; 0x7e0 - begin of .reloc section
-TIMES 0x7e0-($-$$) DB 0
-DD 0x7ea        ; reloc + 10
-DD 10           ; 10
-
-; Round to a full 1k
-TIMES 0x800-($-$$) DB 0
+    .long 0x9042a9de
+    .word 0x23dc, 0x4a38
+    .byte 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a
+
+#conout_guid:
+#    .long 0x387477c2
+#    .word 0x69c7, 0x11d2
+#    .byte 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b
+
+# 0x7e0 - begin of .reloc section
+.org 0x7e0
+.long 0x7ea        # reloc + 10
+.long 10           # 10
+
+# Round to a full 1k
+.org 0x800
 payload_data:
index 0c5c8aa..bf86f76 100755 (executable)
@@ -9,7 +9,8 @@ EFI_ENTRY=`objdump -t viridis | grep efi_entry | awk '{ print $1 }'`
 BOOT_HEADER=`objdump -t viridis | grep boot_header | awk '{ print $1 }'`
 
 gcc -o fixup_stub boot/fixup_stub.c
-nasm -f bin -o efi-stub boot/efi.asm
+as -o efi-stub.o boot/efi.asm
+ld -Ttext 0x0 --oformat binary -nostdlib -o efi-stub efi-stub.o
 objcopy -O binary viridis viridis.bin
 ./fixup_stub efi-stub viridis.bin $KERNEL_START $EFI_ENTRY $BOOT_HEADER > new-efi
 if [ ! $? -eq 0 ]; then
@@ -17,4 +18,4 @@ if [ ! $? -eq 0 ]; then
 else
        cat new-efi viridis.bin > viridis.efi
 fi
-rm fixup_stub efi-stub new-efi viridis.bin
+#rm fixup_stub efi-stub.o efi-stub new-efi viridis.bin
index 0a4df39..49885d3 100644 (file)
 #define FLAGS_CODE_64 (FLAG_USER | FLAG_R0 | FLAG_P | FLAG_L | FLAG_4k | FLAG_CODE)
 
 #ifdef __ASSEMBLY__
-/* 1 = FLAGS, 2 = BASE, 3 = LIMIT */
-
-%macro GDTENTRY 3
-    DW  ((%3) & 0xFFFF)
-    DW  ((%2) & 0xFFFF)
-    DB  (((%2) & 0xFF0000) >> 16)
-    DW  ((%1) | (((%3) & 0xF0000) >> 8))
-    DB  (((%2) & 0xFF000000) >> 24)
-%endmacro
+.macro GDTENTRY flags base limit
+    .word  ((\limit) & 0xFFFF)
+    .word  ((\base) & 0xFFFF)
+    .byte  (((\base) & 0xFF0000) >> 16)
+    .word  ((\flags) | (((\limit) & 0xF0000) >> 8))
+    .byte  (((\base) & 0xFF000000) >> 24)
+.endm
 #endif
index fdf2346..58e651a 100644 (file)
@@ -9,13 +9,15 @@
 #define FLAG_R0                (0 << 5)    // Rings 0 - 3
 #define FLAG_P          (1 << 7)
 #define IDT_ENTRIES     256
-       
-%macro IDTENTRY 1
-    DW (%1 & 0xFFFF)                   /* target low */
-    DW CODE_SEL_64                     /* selector */
-    DB 0                               /* IST */
-    DB (FLAG_P|FLAG_R0|FLAG_INTERRUPT)  /* type */
-    DW (%1 >> 16)                      /* target high */
-    DD 0                               /* target even higher */
-    DD 0                               /* reserved */
-%endmacro
+
+#ifdef __ASSEMBLY__
+.macro IDTENTRY isr
+    .word (\isr & 0xFFFF)                      /* target low */
+    .word CODE_SEL_64                          /* selector */
+    .byte 0                                    /* IST */
+    .byte (FLAG_P|FLAG_R0|FLAG_INTERRUPT)      /* type */
+    .word (\isr >> 16)                         /* target high */
+    .long 0                                    /* target even higher */
+    .long 0                                    /* reserved */
+.endm
+#endif
index 4f30e99..0e6444d 100644 (file)
@@ -1,4 +1,4 @@
-BITS 64
+.code64
 
 // EFI: RCX RDX R8 R9 RSP+32 ...
 // ELF: RDI RSI RDX RCX R8 R9 RSP+8 ...
@@ -17,19 +17,19 @@ BITS 64
 // So all we need to do is swap RDX and RCX, and then sub 32 from the stack
 // to perfectly line up our calling conventions.
 
-GLOBAL efi_call
+.global efi_call
 
 efi_call:           // Stack is 16 byte aligned at call, but
-    pop rsi         // call pushed the return address, pop it into RSI
+    pop %rsi        // call pushed the return address, pop it into RSI
                     // so it's 16 byte aligned again for the EFI ABI
-    push rcx
-    mov rcx, rdx    // RSI is guaranteed to be preserved by the EFI ABI
-    pop rdx         // and the standard ABI doesn't require it to be preserved
+    push %rcx
+    mov %rdx, %rcx  // RSI is guaranteed to be preserved by the EFI ABI
+    pop %rdx        // and the standard ABI doesn't require it to be preserved
                     // by the callee, so we don't violate either.
 
-    sub rsp, 32
-    call rdi
-    add rsp, 32
+    sub $32, %rsp
+    call *%rdi
+    add $32, %rsp
 
-    push rsi
+    push %rsi
     ret