aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTianhao Wang <shrik3@riseup.net>2023-03-14 01:38:04 +0100
committerTianhao Wang <shrik3@riseup.net>2023-03-14 01:38:04 +0100
commit15328de186d12fa72d120f3ee3b593eca94b45d3 (patch)
tree22b9fb9be19f1c1aaae889fd6e0d958e66da279d /src
parentafa2f55b20ba56ac824573a9acea6ecad050d555 (diff)
rework makefile, include other asm sources
Diffstat (limited to 'src')
-rw-r--r--src/arch/x86_64/asm/startup.s537
1 files changed, 0 insertions, 537 deletions
diff --git a/src/arch/x86_64/asm/startup.s b/src/arch/x86_64/asm/startup.s
deleted file mode 100644
index 7b5bbff..0000000
--- a/src/arch/x86_64/asm/startup.s
+++ /dev/null
@@ -1,537 +0,0 @@
-; THis code is copied from the OSC lab project OOStuBS @ TU Dresden
-
-;******************************************************************************
-;* Operating-System Construction *
-;*----------------------------------------------------------------------------*
-;* *
-;* S T A R T U P . A S M *
-;* *
-;*----------------------------------------------------------------------------*
-;* The 'startup' function is the entry point for the whole system. Switching *
-;* to 32-bit Protected Mode has already been done (by a boot loader that runs *
-;* before). Here we prepare everything to be able to start running C++ code *
-;* in 64-bit Long Mode as quickly as possible. *
-;******************************************************************************
-
-;
-; Constants
-;
-
-; stack for the main function (renamed to _entry())
-STACKSIZE: equ 65536
-
-; video memory base address
-CGA: equ 0xB8000
-
-; 256 GB maximum RAM size for page table
-MAX_MEM: equ 254
-
-; Multiboot constants
-MULTIBOOT_PAGE_ALIGN equ 1<<0
-MULTIBOOT_MEMORY_INFO equ 1<<1
-
-; magic number for Multiboot
-MULTIBOOT_HEADER_MAGIC equ 0x1badb002
-
-; Multiboot flags (ELF specific!)
-MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO
-MULTIBOOT_HEADER_CHKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
-MULTIBOOT_EAX_MAGIC equ 0x2badb002
-
-; memory for the page table
-
-[GLOBAL pagetable_start]
-pagetable_start: equ 0x103000
-
-[GLOBAL pagetable_end]
-pagetable_end: equ 0x200000
-
-;
-; System
-;
-
-; functions provided by us
-[GLOBAL startup]
-[GLOBAL idt]
-[GLOBAL __cxa_pure_virtual]
-[GLOBAL _ZdlPv]
-[GLOBAL _ZdlPvj]
-[GLOBAL _ZdlPvm]
-
-; functions from the C parts of the system
-[EXTERN _entry]
-;[EXTERN guardian]
-
-; addresses provided by the compiler
-[EXTERN ___BSS_START__]
-[EXTERN ___BSS_END__]
-[EXTERN __init_array_start]
-[EXTERN __init_array_end]
-[EXTERN __fini_array_start]
-[EXTERN __fini_array_end]
-
-[SECTION .text]
-
-;
-; system start, part 1 (in 32-bit Protected Mode)
-;
-; GDT and page-table initialization, and switch to 64-bit Long Mode
-;
-
-[BITS 32]
-
- jmp startup ; jump over Multiboot header
- align 4 ; 32-bit alignment for GRUB
-
-;
-; Multiboot header for starting with GRUB or QEMU (w/o BIOS)
-;
-
- dd MULTIBOOT_HEADER_MAGIC
- dd MULTIBOOT_HEADER_FLAGS
- dd MULTIBOOT_HEADER_CHKSUM
- dd 0 ; header_addr (gets ignored)
- dd 0 ; load_addr (gets ignored)
- dd 0 ; load_end_addr (gets ignored)
- dd 0 ; bss_end_addr (gets ignored)
- dd 0 ; entry_addr (gets ignored)
- dd 0 ; mode_type (gets ignored)
- dd 0 ; width (gets ignored)
- dd 0 ; height (gets ignored)
- dd 0 ; depth (gets ignored)
-
-;
-; GRUB entry point
-;
-
-startup:
- cld ; GCC-compiled code expects the direction flag to be 0
- cli ; disable interrupts
- lgdt [gdt_80] ; set new segment descriptors
-
- ; global data segment
- mov eax, 3 * 0x8
- ; 0x8 is the length of each entry
- ; these registers point to 4th entry the GDT (see also the code there)
- ; in x86 long mode these are dummy pointers
- ; which are not actually used in addressing. (don't use segmentation at all)
- ; all the addresses are physical addresses from 0.
- mov ds, ax
- mov es, ax
- mov fs, ax
- mov gs, ax
-
- ; define stack
- mov ss, ax
- mov esp, init_stack+STACKSIZE
-
-;
-; Switch to 64-bit Long Mode
-;
-
-init_longmode:
- ; activate address extension (PAE)
- mov eax, cr4
- or eax, 1 << 5
- mov cr4, eax
-
- ; create page table (mandatory)
- call setup_paging
-
- ; activate Long Mode (for now in compatibility mode)
- mov ecx, 0x0C0000080 ; select EFER (Extended Feature Enable Register)
- rdmsr
- or eax, 1 << 8 ; LME (Long Mode Enable)
- wrmsr
-
- ; activate paging
- mov eax, cr0
- or eax, 1 << 31
- mov cr0, eax
-
- ; jump to 64-bit code segment -> full activation of Long Mode
- jmp 2 * 0x8 : longmode_start
-
-;
-; Generation of a (provisional) page table with a page size of 2 MB, which
-; maps the first MAX_MEM GB directly to physical memory. Currently, the
-; system must not have more memory.
-; All of this is necessary because Long Mode mandates a working page table.
-;
-
-setup_paging:
- ; PML4 (Page Map Level 4 / 1st level)
- mov eax, pdp
- or eax, 0xf
- mov dword [pml4+0], eax
- mov dword [pml4+4], 0
-
- ; PDPE (Page Directory Pointer Entry / 2nd level) for currently 16 GB
- mov eax, pd
- or eax, 0x7 ; address of the first table (3rd level) with flags
- mov ecx, 0
-fill_tables2:
- cmp ecx, MAX_MEM ; reference MAX_MEM tables
- je fill_tables2_done
- mov dword [pdp + 8*ecx + 0], eax
- mov dword [pdp + 8*ecx + 4], 0
- add eax, 0x1000 ; tables are sized 4 kB each
- inc ecx
- ja fill_tables2
-fill_tables2_done:
-
- ; PDE (Page Directory Entry / 3rd level)
- mov eax, 0x0 | 0x87 ; start-address bytes 0..3 (=0) + flags
- mov ebx, 0 ; start-address bytes 4..7 (=0)
- mov ecx, 0
-fill_tables3:
- cmp ecx, 512*MAX_MEM ; fill MAX_MEM tables with 512 entries each
- je fill_tables3_done
- mov dword [pd + 8*ecx + 0], eax ; low bytes
- mov dword [pd + 8*ecx + 4], ebx ; high bytes
- add eax, 0x200000 ; 2 MB per page
- adc ebx, 0 ; overflow? -> increment higher-order half of the address
- inc ecx
- ja fill_tables3
-fill_tables3_done:
-
- ; set base pointer to PML4
- mov eax, pml4
- mov cr3, eax
- ret
-
-;
-; system start, part 2 (in 64-bit Long Mode)
-;
-; This code clears the BSS segment and initializes IDT and PICs. Then the
-; constructors of global C++ objects are called, and finally _entry() is run.
-;
-
-longmode_start:
-[BITS 64]
- ; clear BSS
- mov rdi, ___BSS_START__
-clear_bss:
- mov byte [rdi], 0
- inc rdi
- cmp rdi, ___BSS_END__
- jne clear_bss
-
- ; initialize IDT and PICs
- call setup_idt
- call reprogram_pics
- call setup_cursor
-
- fninit ; activate FPU
-
- ; init SSE
- ;mov rax, cr0
- ;and rax, ~(1 << 2) ;clear coprocessor emulation CR0.EM
- ;or rax, 1 << 1 ;set coprocessor monitoring CR0.MP
- ;mov cr0, rax
- ;mov rax, cr4
- ;or rax, 3 << 9 ;set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time
- ;mov cr4, rax
-
- call _init ; call constructors of global objects
- call _entry ; call the OS kernel's C / C++ part
- call _fini ; call destructors
- cli ; Usually we should not get here.
- hlt
-
-;
-; Interrupt handling
-;
-
-; template for header for each interrupt-handling routine
-%macro wrapper 1
-wrapper_%1:
- push rbp
- mov rbp, rsp
- push rax
- mov al, %1
- jmp wrapper_body
-%endmacro
-
-; automatic generation of 256 interrupt-handling routines, based on above macro
-%assign i 0
-%rep 256
-wrapper i
-%assign i i+1
-%endrep
-
-; common handler body
-wrapper_body:
- ; GCC expects the direction flag to be 0
- cld
- ; save volatile registers
- push rcx
- push rdx
- push rdi
- push rsi
- push r8
- push r9
- push r10
- push r11
-
- ; the generated wrapper only gives us 8 bits, mask the rest
- and rax, 0xff
-
- ; pass interrupt number as the first parameter
- mov rdi, rax
-; call guardian
-
- ; restore volatile registers
- pop r11
- pop r10
- pop r9
- pop r8
- pop rsi
- pop rdi
- pop rdx
- pop rcx
-
- ; ... also those from the wrapper
- pop rax
- pop rbp
-
- ; done
- iretq
-
-;
-; Relocating of IDT entries and setting IDTR
-;
-
-setup_idt:
- mov rax, wrapper_0
-
- ; bits 0..15 -> ax, 16..31 -> bx, 32..64 -> edx
- mov rbx, rax
- mov rdx, rax
- shr rdx, 32
- shr rbx, 16
-
- mov r10, idt ; pointer to the actual interrupt gate
- mov rcx, 255 ; counter
-.loop:
- add [r10+0], ax
- adc [r10+6], bx
- adc [r10+8], edx
- add r10, 16
- dec rcx
- jge .loop
-
- lidt [idt_descr]
- ret
-
-;
-; make cursor blink (GRUB disables this)
-;
-
-setup_cursor:
- mov al, 0x0a
- mov dx, 0x3d4
- out dx, al
- call delay
- mov dx, 0x3d5
- in al, dx
- call delay
- and al, 0xc0
- or al, 14
- out dx, al
- call delay
- mov al, 0x0b
- mov dx, 0x3d4
- out dx, al
- call delay
- mov dx, 0x3d5
- in al, dx
- call delay
- and al, 0xe0
- or al, 15
- out dx, al
- ret
-
-;
-; Reprogram the PICs (programmable interrupt controllers) to have all 15
-; hardware interrupts in sequence in the IDT.
-;
-
-reprogram_pics:
- mov al, 0x11 ; ICW1: 8086 mode with ICW4
- out 0x20, al
- call delay
- out 0xa0, al
- call delay
- mov al, 0x20 ; ICW2 master: IRQ # offset (32)
- out 0x21, al
- call delay
- mov al, 0x28 ; ICW2 slave: IRQ # offset (40)
- out 0xa1, al
- call delay
- mov al, 0x04 ; ICW3 master: slaves with IRQs
- out 0x21, al
- call delay
- mov al, 0x02 ; ICW3 slave: connected to master's IRQ2
- out 0xa1, al
- call delay
- mov al, 0x03 ; ICW4: 8086 mode and automatic EOI
- out 0x21, al
- call delay
- out 0xa1, al
- call delay
-
- mov al, 0xff ; Mask/disable hardware interrupts
- out 0xa1, al ; in the PICs. Only interrupt #2, which
- call delay ; serves for cascading both PICs, is
- mov al, 0xfb ; allowed.
- out 0x21, al
-
- ret
-
-;
-; Run constructors of global objects
-;
-
-_init:
- mov rbx, __init_array_start
-_init_loop:
- cmp rbx, __init_array_end
- je _init_done
- mov rax, [rbx]
- call rax
- add rbx, 8
- ja _init_loop
-_init_done:
- ret
-
-;
-; Run destructors of global objects
-;
-
-_fini:
- mov rbx, __fini_array_start
-_fini_loop:
- cmp rbx, __fini_array_end
- je _fini_done
- mov rax, [rbx]
- call rax
- add rbx, 8
- ja _fini_loop
-_fini_done:
- ret
-
-;
-; Short delay for in/out instructions
-;
-
-delay:
- jmp .L2
-.L2:
- ret
-
-;
-; Functions for the C++ compiler. These labels must be defined for the linker;
-; since OOStuBS does not release/free any memory, they may be empty, however.
-;
-
-__cxa_pure_virtual: ; a "virtual" method without implementation was called
-_ZdlPv: ; void operator delete(void*)
-_ZdlPvj: ; void operator delete(void*, unsigned int) for g++ 6.x
-_ZdlPvm: ; void operator delete(void*, unsigned long) for g++ 6.x
- ret
-
-[SECTION .data]
-
-;
-; Segment descriptors
-;
-
-gdt:
- dw 0,0,0,0 ; NULL descriptor
-
- ; 32-bit code segment descriptor
- dw 0xFFFF ; 4Gb - (0x100000*0x1000 = 4Gb)
- dw 0x0000 ; base address=0
- dw 0x9A00 ; code read/exec
- dw 0x00CF ; granularity=4096, 386 (+5th nibble of limit)
-
- ; 64-bit code segment descriptor
- dw 0xFFFF ; 4Gb - (0x100000*0x1000 = 4Gb)
- dw 0x0000 ; base address=0
- dw 0x9A00 ; code read/exec
- dw 0x00AF ; granularity=4096, 386 (+5th nibble of limit), Long-Mode
-
- ; data segment descriptor
- dw 0xFFFF ; 4Gb - (0x100000*0x1000 = 4Gb)
- dw 0x0000 ; base address=0
- dw 0x9200 ; data read/write
- dw 0x00CF ; granularity=4096, 386 (+5th nibble of limit)
-
-gdt_80:
- dw 4*8 - 1 ; GDT limit=24, 4 GDT entries - 1
- dq gdt ; GDT address
-
-;
-; Interrupt descriptor table with 256 entries
-;
-
-idt:
-%macro idt_entry 1
- dw (wrapper_%1 - wrapper_0) & 0xffff ; offset 0 .. 15
- dw 0x0000 | 0x8 * 2 ; selector points to 64-bit code segment selector (GDT)
- dw 0x8e00 ; 8 -> interrupt is present, e -> 80386 32-bit interrupt gate
- dw ((wrapper_%1 - wrapper_0) & 0xffff0000) >> 16 ; offset 16 .. 31
- dd ((wrapper_%1 - wrapper_0) & 0xffffffff00000000) >> 32 ; offset 32..63
- dd 0x00000000 ; reserved
-%endmacro
-
-%assign i 0
-%rep 256
-idt_entry i
-%assign i i+1
-%endrep
-
-idt_descr:
- dw 256*8 - 1 ; 256 entries
- dq idt
-
-[SECTION .bss]
-
-[GLOBAL MULTIBOOT_FLAGS]
-[GLOBAL MULTIBOOT_LOWER_MEM]
-[GLOBAL MULTIBOOT_UPPER_MEM]
-[GLOBAL MULTIBOOT_BOOTDEVICE]
-[GLOBAL MULTIBOOT_CMDLINE]
-[GLOBAL MULTIBOOT_MODULES_COUNT]
-[GLOBAL MULTIBOOT_MODULES_ADDRESS]
-
-MULTIBOOT_FLAGS: resd 1
-MULTIBOOT_LOWER_MEM: resd 1
-MULTIBOOT_UPPER_MEM: resd 1
-MULTIBOOT_BOOTDEVICE: resd 1
-MULTIBOOT_CMDLINE: resd 1
-MULTIBOOT_MODULES_COUNT: resd 1
-MULTIBOOT_MODULES_ADDRESS: resd 1
-
-global init_stack:data (init_stack.end - init_stack)
-init_stack:
- resb STACKSIZE
-.end:
-
-[SECTION .global_pagetable]
-
-[GLOBAL pml4]
-[GLOBAL pdp]
-[GLOBAL pd]
-
-pml4:
- resb 4096
- alignb 4096
-
-pdp:
- resb MAX_MEM*8
- alignb 4096
-
-pd:
- resb MAX_MEM*4096