Compare commits
3 Commits
5050047cef
...
e3f455ae13
Author | SHA1 | Date |
---|---|---|
Bananymous | e3f455ae13 | |
Bananymous | b35cad0c2e | |
Bananymous | 2106a9e373 |
|
@ -5,15 +5,26 @@
|
|||
.set e_machine, 18
|
||||
.set e_version, 20
|
||||
.set e_entry, 24
|
||||
.set e_phoff, 32
|
||||
.set e_shoff, 40
|
||||
.set e_flags, 48
|
||||
.set e_ehsize, 52
|
||||
.set e_phentsize, 54
|
||||
.set e_phnum, 56
|
||||
.set e_shentsize, 58
|
||||
.set e_shnum, 60
|
||||
.set e_shstrndx, 62
|
||||
|
||||
.set e32_phoff, 28
|
||||
.set e32_shoff, 32
|
||||
.set e32_flags, 36
|
||||
.set e32_ehsize, 40
|
||||
.set e32_phentsize, 42
|
||||
.set e32_phnum, 44
|
||||
.set e32_shentsize, 46
|
||||
.set e32_shnum, 48
|
||||
.set e32_shstrndx, 50
|
||||
|
||||
.set e64_phoff, 32
|
||||
.set e64_shoff, 40
|
||||
.set e64_flags, 48
|
||||
.set e64_ehsize, 52
|
||||
.set e64_phentsize, 54
|
||||
.set e64_phnum, 56
|
||||
.set e64_shentsize, 58
|
||||
.set e64_shnum, 60
|
||||
.set e64_shstrndx, 62
|
||||
|
||||
# e_ident offsets
|
||||
.set EI_CLASS, 4
|
||||
|
@ -22,6 +33,7 @@
|
|||
|
||||
# e_ident constants
|
||||
.set ELFMAGIC, 0x464C457F
|
||||
.set ELFCLASS32, 1
|
||||
.set ELFCLASS64, 2
|
||||
.set ELFDATA2LSB, 1
|
||||
.set EV_CURRENT, 1
|
||||
|
@ -31,18 +43,30 @@
|
|||
|
||||
# program header field offsets
|
||||
.set p_type, 0
|
||||
.set p_flags, 4
|
||||
.set p_offset, 8
|
||||
.set p_vaddr, 16
|
||||
.set p_paddr, 24
|
||||
.set p_filesz, 32
|
||||
.set p_memsz, 40
|
||||
.set p_align, 48
|
||||
|
||||
.set p32_offset, 4
|
||||
.set p32_vaddr, 8
|
||||
.set p32_paddr, 12
|
||||
.set p32_filesz, 16
|
||||
.set p32_memsz, 20
|
||||
.set p32_flags, 24
|
||||
.set p32_align, 28
|
||||
|
||||
.set p64_flags, 4
|
||||
.set p64_offset, 8
|
||||
.set p64_vaddr, 16
|
||||
.set p64_paddr, 24
|
||||
.set p64_filesz, 32
|
||||
.set p64_memsz, 40
|
||||
.set p64_align, 48
|
||||
|
||||
# p_type constants
|
||||
.set PT_NULL, 0
|
||||
.set PT_LOAD, 1
|
||||
|
||||
# mask for entry point and segment loading
|
||||
.set LOAD_MASK, 0x07FFFFFF
|
||||
|
||||
.code16
|
||||
.section .stage2
|
||||
|
||||
|
@ -52,8 +76,12 @@ elf_validate_file_header:
|
|||
cmpl $ELFMAGIC, (elf_file_header)
|
||||
jne .elf_validate_file_header_invalid_magic
|
||||
|
||||
cmpb $ELFCLASS32, (elf_file_header + EI_CLASS)
|
||||
je .elf_validate_file_header_class_valid
|
||||
cmpb $ELFCLASS64, (elf_file_header + EI_CLASS)
|
||||
jne .elf_validate_file_header_only_64bit_supported
|
||||
je .elf_validate_file_header_class_valid
|
||||
jmp .elf_validate_file_header_invalid_class
|
||||
.elf_validate_file_header_class_valid:
|
||||
|
||||
cmpb $ELFDATA2LSB, (elf_file_header + EI_DATA)
|
||||
jne .elf_validate_file_header_only_little_endian_supported
|
||||
|
@ -72,8 +100,8 @@ elf_validate_file_header:
|
|||
.elf_validate_file_header_invalid_magic:
|
||||
movw $elf_validate_file_header_invalid_magic_msg, %si
|
||||
jmp print_and_halt
|
||||
.elf_validate_file_header_only_64bit_supported:
|
||||
movw $elf_validate_file_header_only_64bit_supported_msg, %si
|
||||
.elf_validate_file_header_invalid_class:
|
||||
movw $elf_validate_file_header_invalid_class_msg, %si
|
||||
jmp print_and_halt
|
||||
.elf_validate_file_header_only_little_endian_supported:
|
||||
movw $elf_validate_file_header_only_little_endian_supported_msg, %si
|
||||
|
@ -86,6 +114,90 @@ elf_validate_file_header:
|
|||
jmp print_and_halt
|
||||
|
||||
|
||||
# sets memory to zero
|
||||
# edi: start address
|
||||
# ecx: byte count
|
||||
# on return
|
||||
# edi: start address + byte count
|
||||
# ecx: 0
|
||||
elf_memset_zero:
|
||||
test %ecx, %ecx
|
||||
jz .elf_memset_zero_done
|
||||
.elf_memset_zero_loop:
|
||||
movb $0, (%edi)
|
||||
incl %edi
|
||||
decl %ecx
|
||||
jnz .elf_memset_zero_loop
|
||||
.elf_memset_zero_done:
|
||||
ret
|
||||
|
||||
# reads memory specified by 32 bit elf_program_header to memory
|
||||
elf_read_program_header32_to_memory:
|
||||
pushal
|
||||
pushl %ebp
|
||||
movl %esp, %ebp
|
||||
|
||||
# memset p_filesz -> p_memsz to 0
|
||||
movl (elf_program_header + p32_filesz), %ebx
|
||||
movl (elf_program_header + p32_vaddr), %edi
|
||||
andl $LOAD_MASK, %edi
|
||||
addl %ebx, %edi
|
||||
movl (elf_program_header + p32_memsz), %ecx
|
||||
subl %ebx, %ecx
|
||||
|
||||
movl %edi, %eax; call print_hex32; movb $',', %al; call putc; movb $' ', %al; call putc
|
||||
movl %ecx, %eax; call print_hex32; movb $';', %al; call putc; movb $' ', %al; call putc
|
||||
call elf_memset_zero
|
||||
|
||||
# read file specified in program header to memory
|
||||
movl (elf_program_header + p32_offset), %eax
|
||||
movl (elf_program_header + p32_vaddr), %edi
|
||||
andl $LOAD_MASK, %edi
|
||||
movl (elf_program_header + p32_filesz), %ecx
|
||||
|
||||
|
||||
pushl %eax
|
||||
movl %eax, %eax; call print_hex32; movb $',', %al; call putc; movb $' ', %al; call putc
|
||||
movl %ecx, %eax; call print_hex32; movb $',', %al; call putc; movb $' ', %al; call putc
|
||||
movl %edi, %eax; call print_hex32; call print_newline
|
||||
popl %eax
|
||||
|
||||
call *%esi
|
||||
|
||||
movl $0x69696969, %eax; call print_hex32; call print_newline
|
||||
|
||||
leavel
|
||||
popal
|
||||
ret
|
||||
|
||||
|
||||
# reads memory specified by 64 bit elf_program_header to memory
|
||||
elf_read_program_header64_to_memory:
|
||||
pushal
|
||||
pushl %ebp
|
||||
movl %esp, %ebp
|
||||
|
||||
# memset p_filesz -> p_memsz to 0
|
||||
movl (elf_program_header + p64_filesz), %ebx
|
||||
movl (elf_program_header + p64_vaddr), %edi
|
||||
andl $LOAD_MASK, %edi
|
||||
addl %ebx, %edi
|
||||
movl (elf_program_header + p64_memsz), %ecx
|
||||
subl %ebx, %ecx
|
||||
call elf_memset_zero
|
||||
|
||||
# read file specified in program header to memory
|
||||
movl (elf_program_header + p64_offset), %eax
|
||||
movl (elf_program_header + p64_vaddr), %edi
|
||||
andl $LOAD_MASK, %edi
|
||||
movl (elf_program_header + p64_filesz), %ecx
|
||||
call *%esi
|
||||
|
||||
leavel
|
||||
popal
|
||||
ret
|
||||
|
||||
|
||||
# read callback format
|
||||
# eax: first byte
|
||||
# ecx: byte count
|
||||
|
@ -104,42 +216,72 @@ elf_read_kernel_to_memory:
|
|||
movl %esp, %ebp
|
||||
subl $2, %esp
|
||||
|
||||
# read file header
|
||||
# read start of file header
|
||||
movl $0, %eax
|
||||
movl $64, %ecx
|
||||
movl $24, %ecx
|
||||
movl $elf_file_header, %edi
|
||||
call *%esi
|
||||
|
||||
call elf_validate_file_header
|
||||
|
||||
cmpl $0, (elf_file_header + e_phoff + 4)
|
||||
# determine file header size
|
||||
movl $52, %ecx
|
||||
movl $64, %edx
|
||||
cmpb $ELFCLASS64, (elf_file_header + EI_CLASS)
|
||||
cmovel %edx, %ecx
|
||||
|
||||
# read full file header
|
||||
movl $0, %eax
|
||||
movl $elf_file_header, %edi
|
||||
call *%esi
|
||||
|
||||
# verify that e_phoff fits in 32 bits
|
||||
cmpb $ELFCLASS64, (elf_file_header + EI_CLASS)
|
||||
jne .elf_read_kernel_to_memory_valid_offset
|
||||
cmpl $0, (elf_file_header + e64_phoff + 4)
|
||||
jnz .elf_read_kernel_to_memory_unsupported_offset
|
||||
.elf_read_kernel_to_memory_valid_offset:
|
||||
|
||||
# read architecture phentsize and phnum to fixed locations
|
||||
movw (elf_file_header + e32_phentsize), %ax
|
||||
movw (elf_file_header + e32_phnum), %bx
|
||||
movl (elf_file_header + e32_phoff), %ecx
|
||||
cmpb $ELFCLASS64, (elf_file_header + EI_CLASS)
|
||||
cmovew (elf_file_header + e64_phentsize), %ax
|
||||
cmovew (elf_file_header + e64_phnum), %bx
|
||||
cmovel (elf_file_header + e64_phoff), %ecx
|
||||
movw %ax, (elf_file_header_phentsize)
|
||||
movw %bx, (elf_file_header_phnum)
|
||||
movl %ecx, (elf_file_header_phoff)
|
||||
|
||||
# current program header
|
||||
movw $0, -2(%ebp)
|
||||
|
||||
.elf_read_kernel_to_memory_loop_program_headers:
|
||||
movw -2(%ebp), %cx
|
||||
cmpw (elf_file_header + e_phnum), %cx
|
||||
cmpw (elf_file_header_phnum), %cx
|
||||
jae .elf_read_kernel_to_memory_done
|
||||
|
||||
# eax := program_header_index * e_phentsize + e_phoff
|
||||
xorl %eax, %eax
|
||||
movw %cx, %ax
|
||||
xorl %ebx, %ebx
|
||||
movw (elf_file_header + e_phentsize), %bx
|
||||
movw (elf_file_header_phentsize), %bx
|
||||
mull %ebx
|
||||
addl (elf_file_header + e_phoff), %eax
|
||||
addl (elf_file_header_phoff), %eax
|
||||
jc .elf_read_kernel_to_memory_unsupported_offset
|
||||
|
||||
# setup program header size and address
|
||||
movl $56, %ecx
|
||||
movl $elf_program_header, %edi
|
||||
# determine program header size
|
||||
movl $32, %ecx
|
||||
movl $56, %edx
|
||||
cmpb $ELFCLASS64, (elf_file_header + EI_CLASS)
|
||||
cmovel %edx, %ecx
|
||||
|
||||
# read the program header
|
||||
# read program header
|
||||
movl $elf_program_header, %edi
|
||||
call *%esi
|
||||
|
||||
# test if program header is empty
|
||||
# test if program header is NULL header
|
||||
cmpl $PT_NULL, (elf_program_header + p_type)
|
||||
je .elf_read_kernel_to_memory_null_program_header
|
||||
|
||||
|
@ -147,33 +289,12 @@ elf_read_kernel_to_memory:
|
|||
cmpl $PT_LOAD, (elf_program_header + p_type)
|
||||
jne .elf_read_kernel_to_memory_not_loadable_header
|
||||
|
||||
# memset p_filesz -> p_memsz to 0
|
||||
movl (elf_program_header + p_filesz), %ebx
|
||||
|
||||
movl (elf_program_header + p_vaddr), %edi
|
||||
andl $0x7FFFFFFF, %edi
|
||||
addl %ebx, %edi
|
||||
|
||||
movl (elf_program_header + p_memsz), %ecx
|
||||
subl %ebx, %ecx
|
||||
jz .elf_read_kernel_to_memory_memset_done
|
||||
|
||||
.elf_read_kernel_to_memory_memset:
|
||||
movb $0, (%edi)
|
||||
incl %edi
|
||||
decl %ecx
|
||||
jnz .elf_read_kernel_to_memory_memset
|
||||
.elf_read_kernel_to_memory_memset_done:
|
||||
|
||||
# read file specified in program header to memory
|
||||
movl (elf_program_header + p_offset), %eax
|
||||
movl (elf_program_header + p_vaddr), %edi
|
||||
andl $0x7FFFFFFF, %edi
|
||||
movl (elf_program_header + p_filesz), %ecx
|
||||
|
||||
#call print_hex32; call print_newline
|
||||
|
||||
call *%esi
|
||||
# read program header to memory
|
||||
movl $elf_read_program_header32_to_memory, %eax
|
||||
movl $elf_read_program_header64_to_memory, %ebx
|
||||
cmpb $ELFCLASS64, (elf_file_header + EI_CLASS)
|
||||
cmovel %ebx, %eax
|
||||
call *%eax
|
||||
|
||||
.elf_read_kernel_to_memory_null_program_header:
|
||||
incw -2(%ebp)
|
||||
|
@ -185,7 +306,7 @@ elf_read_kernel_to_memory:
|
|||
|
||||
# set kernel entry address
|
||||
movl (elf_file_header + e_entry), %eax
|
||||
andl $0x7FFFFF, %eax
|
||||
andl $LOAD_MASK, %eax
|
||||
|
||||
ret
|
||||
|
||||
|
@ -200,8 +321,8 @@ elf_read_kernel_to_memory:
|
|||
|
||||
elf_validate_file_header_invalid_magic_msg:
|
||||
.asciz "ELF: file has invalid ELF magic"
|
||||
elf_validate_file_header_only_64bit_supported_msg:
|
||||
.asciz "ELF: file is not targettint 64 bit"
|
||||
elf_validate_file_header_invalid_class_msg:
|
||||
.asciz "ELF: file has invalid ELF class"
|
||||
elf_validate_file_header_only_little_endian_supported_msg:
|
||||
.asciz "ELF: file is not in little endian format"
|
||||
elf_validate_file_header_not_current_version_msg:
|
||||
|
@ -219,5 +340,12 @@ elf_read_kernel_to_memory_not_loadable_header_msg:
|
|||
elf_file_header:
|
||||
.skip 64
|
||||
|
||||
elf_file_header_phentsize:
|
||||
.skip 2
|
||||
elf_file_header_phnum:
|
||||
.skip 2
|
||||
elf_file_header_phoff:
|
||||
.skip 4 # NOTE: only 32 bit offsets are supported
|
||||
|
||||
elf_program_header:
|
||||
.skip 56
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
cmake_minimum_required(VERSION 3.26)
|
||||
|
||||
project(x86_64-banan_os-bootloader-installer CXX)
|
||||
if (NOT DEFINED ENV{BANAN_ARCH})
|
||||
message(FATAL_ERROR "environment variable BANAN_ARCH not defined")
|
||||
endif ()
|
||||
set(BANAN_ARCH $ENV{BANAN_ARCH})
|
||||
|
||||
project(banan_os-bootloader-installer CXX)
|
||||
|
||||
set(SOURCES
|
||||
crc32.cpp
|
||||
|
@ -10,8 +15,8 @@ set(SOURCES
|
|||
main.cpp
|
||||
)
|
||||
|
||||
add_executable(x86_64-banan_os-bootloader-installer ${SOURCES})
|
||||
target_compile_options(x86_64-banan_os-bootloader-installer PRIVATE -O2 -std=c++20)
|
||||
target_compile_definitions(x86_64-banan_os-bootloader-installer PRIVATE __arch=x86_64)
|
||||
target_include_directories(x86_64-banan_os-bootloader-installer PRIVATE ${CMAKE_SOURCE_DIR}/../../LibELF/include)
|
||||
target_include_directories(x86_64-banan_os-bootloader-installer PRIVATE ${CMAKE_SOURCE_DIR}/../../kernel/include)
|
||||
add_executable(banan_os-bootloader-installer ${SOURCES})
|
||||
target_compile_options(banan_os-bootloader-installer PRIVATE -O2 -std=c++20)
|
||||
target_compile_definitions(banan_os-bootloader-installer PRIVATE __arch=${BANAN_ARCH})
|
||||
target_include_directories(banan_os-bootloader-installer PRIVATE ${CMAKE_SOURCE_DIR}/../../LibELF/include)
|
||||
target_include_directories(banan_os-bootloader-installer PRIVATE ${CMAKE_SOURCE_DIR}/../../kernel/include)
|
||||
|
|
|
@ -81,7 +81,7 @@ bool ELFFile::validate_elf_header() const
|
|||
|
||||
#if ARCH(x86_64)
|
||||
if (elf_header.e_ident[EI_CLASS] != ELFCLASS64)
|
||||
#elif ARCH(i386)
|
||||
#elif ARCH(i686)
|
||||
if (elf_header.e_ident[EI_CLASS] != ELFCLASS32)
|
||||
#endif
|
||||
{
|
||||
|
|
|
@ -4,40 +4,31 @@ read_ip:
|
|||
popl %eax
|
||||
jmp *%eax
|
||||
|
||||
# void start_thread(uint32_t sp, uint32_t ip)
|
||||
.global start_thread
|
||||
start_thread:
|
||||
movl 8(%esp), %edi # ip
|
||||
movl 4(%esp), %esp # sp
|
||||
# void start_kernel_thread()
|
||||
.global start_kernel_thread
|
||||
start_kernel_thread:
|
||||
call get_start_kernel_thread_sp
|
||||
movl %eax, %esp
|
||||
|
||||
# STACK LAYOUT
|
||||
# NULL
|
||||
# thread ptr
|
||||
# &Thread::on_exit
|
||||
# data
|
||||
# on_exit arg
|
||||
# on_exit func
|
||||
# entry arg
|
||||
# entry func
|
||||
|
||||
xorl %ebp, %ebp
|
||||
movl 4(%esp), %edi
|
||||
movl 0(%esp), %esi
|
||||
|
||||
subl $12, %esp
|
||||
pushl %edi
|
||||
sti
|
||||
call *%edi
|
||||
call *%esi
|
||||
addl $16, %esp
|
||||
|
||||
movl 4(%esp), %edi # &Thread::on_exit
|
||||
movl 12(%esp), %edi
|
||||
movl 8(%esp), %esi
|
||||
|
||||
movl 8(%esp), %eax # thread ptr
|
||||
movl %eax, (%esp)
|
||||
|
||||
call *%edi
|
||||
|
||||
|
||||
# void continue_thread(uint32_t sp, uint32_t ip)
|
||||
.global continue_thread
|
||||
continue_thread:
|
||||
movl 8(%esp), %edi # ip
|
||||
movl 4(%esp), %esp # sp
|
||||
xorl %eax, %eax
|
||||
jmp *%edi
|
||||
|
||||
# void thread_userspace_trampoline(uint32_t sp, uint32_t ip, int argc, char** argv, char** envp)
|
||||
.global thread_userspace_trampoline
|
||||
thread_userspace_trampoline:
|
||||
ud2
|
||||
subl $12, %esp
|
||||
pushl %edi
|
||||
call *%esi
|
||||
addl $16, %esp
|
||||
|
|
|
@ -26,17 +26,31 @@ isr_stub:
|
|||
irq_stub:
|
||||
pusha
|
||||
|
||||
leal 40(%esp), %eax // interrupt stack ptr
|
||||
movl 32(%esp), %ebx // irq number
|
||||
movl 32(%esp), %eax # interrupt number
|
||||
|
||||
subl $8, %esp
|
||||
pushl %eax
|
||||
call cpp_irq_handler
|
||||
addl $12, %esp
|
||||
|
||||
popa
|
||||
addl $8, %esp
|
||||
iret
|
||||
|
||||
.global asm_reschedule_handler
|
||||
asm_reschedule_handler:
|
||||
pusha
|
||||
|
||||
movl %esp, %eax # interrupt registers ptr
|
||||
leal 32(%esp), %ebx # interrupt stack ptr
|
||||
|
||||
subl $12, %esp
|
||||
pushl %eax
|
||||
pushl %ebx
|
||||
call cpp_irq_handler
|
||||
call cpp_reschedule_handler
|
||||
addl $20, %esp
|
||||
|
||||
popa
|
||||
addl $8, %esp
|
||||
iret
|
||||
|
||||
// arguments in EAX, EBX, ECX, EDX, ESI, EDI
|
||||
|
@ -158,4 +172,3 @@ irq 28
|
|||
irq 29
|
||||
irq 30
|
||||
irq 31
|
||||
irq 32
|
||||
|
|
|
@ -4,9 +4,12 @@ read_ip:
|
|||
popq %rax
|
||||
jmp *%rax
|
||||
|
||||
# void start_thread()
|
||||
# void start_kernel_thread()
|
||||
.global start_kernel_thread
|
||||
start_kernel_thread:
|
||||
call get_start_kernel_thread_sp
|
||||
movq %rax, %rsp
|
||||
|
||||
# STACK LAYOUT
|
||||
# on_exit arg
|
||||
# on_exit func
|
||||
|
@ -15,6 +18,7 @@ start_kernel_thread:
|
|||
|
||||
movq 8(%rsp), %rdi
|
||||
movq 0(%rsp), %rsi
|
||||
sti
|
||||
call *%rsi
|
||||
|
||||
movq 24(%rsp), %rdi
|
||||
|
|
|
@ -14,6 +14,7 @@ namespace Kernel
|
|||
uintptr_t ss;
|
||||
};
|
||||
|
||||
#if ARCH(x86_64)
|
||||
struct InterruptRegisters
|
||||
{
|
||||
uintptr_t r15;
|
||||
|
@ -33,5 +34,18 @@ namespace Kernel
|
|||
uintptr_t rcx;
|
||||
uintptr_t rax;
|
||||
};
|
||||
#elif ARCH(i686)
|
||||
struct InterruptRegisters
|
||||
{
|
||||
uintptr_t edi;
|
||||
uintptr_t esi;
|
||||
uintptr_t ebp;
|
||||
uintptr_t unused;
|
||||
uintptr_t ebx;
|
||||
uintptr_t edx;
|
||||
uintptr_t ecx;
|
||||
uintptr_t eax;
|
||||
};
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
@ -77,7 +77,6 @@ namespace Kernel
|
|||
size_t virtual_page_count() const { return (m_kernel_stack->size() / PAGE_SIZE) + (m_userspace_stack->size() / PAGE_SIZE); }
|
||||
size_t physical_page_count() const { return virtual_page_count(); }
|
||||
|
||||
uintptr_t& interrupt_sp() { return m_interrupt_sp; }
|
||||
InterruptStack& interrupt_stack() { return m_interrupt_stack; }
|
||||
InterruptRegisters& interrupt_registers() { return m_interrupt_registers; }
|
||||
|
||||
|
@ -89,6 +88,8 @@ namespace Kernel
|
|||
|
||||
private:
|
||||
Thread(pid_t tid, Process*);
|
||||
|
||||
static void on_exit_trampoline(Thread*);
|
||||
void on_exit();
|
||||
|
||||
private:
|
||||
|
@ -104,7 +105,6 @@ namespace Kernel
|
|||
|
||||
InterruptStack m_interrupt_stack { };
|
||||
InterruptRegisters m_interrupt_registers { };
|
||||
uintptr_t m_interrupt_sp { };
|
||||
|
||||
uint64_t m_signal_pending_mask { 0 };
|
||||
uint64_t m_signal_block_mask { 0 };
|
||||
|
|
|
@ -14,17 +14,6 @@ namespace Kernel
|
|||
static Scheduler* s_instance = nullptr;
|
||||
static BAN::Atomic<bool> s_started { false };
|
||||
|
||||
ALWAYS_INLINE static void load_temp_stack()
|
||||
{
|
||||
#if ARCH(x86_64)
|
||||
asm volatile("movq %0, %%rsp" :: "rm"(Processor::current_stack_top()));
|
||||
#elif ARCH(i686)
|
||||
asm volatile("movl %0, %%esp" :: "rm"(Processor::current_stack_top()));
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Scheduler::initialize()
|
||||
{
|
||||
ASSERT(s_instance == nullptr);
|
||||
|
@ -40,6 +29,11 @@ namespace Kernel
|
|||
return *s_instance;
|
||||
}
|
||||
|
||||
extern "C" uintptr_t get_start_kernel_thread_sp()
|
||||
{
|
||||
return Scheduler::get().current_thread().kernel_stack_top() - 4 * sizeof(uintptr_t);
|
||||
}
|
||||
|
||||
void Scheduler::start()
|
||||
{
|
||||
ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled);
|
||||
|
@ -86,7 +80,6 @@ namespace Kernel
|
|||
if (thread->state() != Thread::State::NotStarted)
|
||||
{
|
||||
thread->interrupt_stack() = Processor::get_interrupt_stack();
|
||||
thread->interrupt_stack().sp = thread->interrupt_sp();
|
||||
thread->interrupt_registers() = Processor::get_interrupt_registers();
|
||||
}
|
||||
|
||||
|
@ -155,15 +148,29 @@ namespace Kernel
|
|||
auto state = Processor::get_interrupt_state();
|
||||
Processor::set_interrupt_state(InterruptState::Disabled);
|
||||
|
||||
#if ARCH(x86_64)
|
||||
asm volatile(
|
||||
"movq %%rsp, %[save_sp];"
|
||||
"movq %%rsp, %%rcx;"
|
||||
"movq %[load_sp], %%rsp;"
|
||||
"int %[ipi];"
|
||||
: [save_sp]"=m"(Thread::current().interrupt_sp())
|
||||
: [load_sp]"r"(Processor::current_stack_top()),
|
||||
"movq %%rcx, %%rsp;"
|
||||
:: [load_sp]"r"(Processor::current_stack_top()),
|
||||
[ipi]"i"(IRQ_VECTOR_BASE + IRQ_IPI)
|
||||
: "memory"
|
||||
: "memory", "rcx"
|
||||
);
|
||||
#elif ARCH(i686)
|
||||
asm volatile(
|
||||
"movl %%esp, %%ecx;"
|
||||
"movl %[load_sp], %%esp;"
|
||||
"int %[ipi];"
|
||||
"movl %%ecx, %%esp;"
|
||||
:: [load_sp]"r"(Processor::current_stack_top()),
|
||||
[ipi]"i"(IRQ_VECTOR_BASE + IRQ_IPI)
|
||||
: "memory", "ecx"
|
||||
);
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
|
||||
Processor::set_interrupt_state(state);
|
||||
}
|
||||
|
|
|
@ -12,19 +12,15 @@
|
|||
namespace Kernel
|
||||
{
|
||||
|
||||
extern "C" [[noreturn]] void start_userspace_thread();
|
||||
extern "C" [[noreturn]] void start_kernel_thread();
|
||||
|
||||
extern "C" void signal_trampoline();
|
||||
|
||||
template<typename T>
|
||||
static void write_to_stack(uintptr_t& rsp, const T& value)
|
||||
static void write_to_stack(uintptr_t& rsp, const T& value) requires(sizeof(T) <= sizeof(uintptr_t))
|
||||
{
|
||||
rsp -= sizeof(uintptr_t);
|
||||
if constexpr(sizeof(T) < sizeof(uintptr_t))
|
||||
*(uintptr_t*)rsp = (uintptr_t)value;
|
||||
else
|
||||
memcpy((void*)rsp, (void*)&value, sizeof(uintptr_t));
|
||||
}
|
||||
|
||||
static pid_t s_next_tid = 1;
|
||||
|
@ -50,13 +46,13 @@ namespace Kernel
|
|||
// Initialize stack for returning
|
||||
uintptr_t sp = thread->kernel_stack_top();
|
||||
write_to_stack(sp, thread);
|
||||
write_to_stack(sp, &Thread::on_exit);
|
||||
write_to_stack(sp, &Thread::on_exit_trampoline);
|
||||
write_to_stack(sp, data);
|
||||
write_to_stack(sp, entry);
|
||||
|
||||
thread->m_interrupt_stack.ip = reinterpret_cast<vaddr_t>(start_kernel_thread);
|
||||
thread->m_interrupt_stack.cs = 0x08;
|
||||
thread->m_interrupt_stack.flags = 0x202;
|
||||
thread->m_interrupt_stack.flags = 0x002;
|
||||
thread->m_interrupt_stack.sp = sp;
|
||||
thread->m_interrupt_stack.ss = 0x10;
|
||||
|
||||
|
@ -245,7 +241,7 @@ namespace Kernel
|
|||
PageTable::with_fast_page(process().page_table().physical_address_of(kernel_stack_top() - PAGE_SIZE), [&] {
|
||||
uintptr_t sp = PageTable::fast_page() + PAGE_SIZE;
|
||||
write_to_stack(sp, this);
|
||||
write_to_stack(sp, &Thread::on_exit);
|
||||
write_to_stack(sp, &Thread::on_exit_trampoline);
|
||||
write_to_stack(sp, m_process);
|
||||
write_to_stack(sp, entry);
|
||||
});
|
||||
|
@ -422,6 +418,11 @@ namespace Kernel
|
|||
return {};
|
||||
}
|
||||
|
||||
void Thread::on_exit_trampoline(Thread* thread)
|
||||
{
|
||||
thread->on_exit();
|
||||
}
|
||||
|
||||
void Thread::on_exit()
|
||||
{
|
||||
ASSERT(this == &Thread::current());
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
|
||||
set -e
|
||||
|
||||
if [[ -z $BANAN_ARCH ]]; then
|
||||
echo "You must set the BANAN_ARCH environment variable" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z $BANAN_DISK_IMAGE_PATH ]]; then
|
||||
echo "You must set the BANAN_DISK_IMAGE_PATH environment variable" >&2
|
||||
exit 1
|
||||
|
@ -26,7 +31,7 @@ ROOT_PARTITION_INDEX=2
|
|||
ROOT_PARTITION_INFO=$(fdisk -x $BANAN_DISK_IMAGE_PATH | grep "^$BANAN_DISK_IMAGE_PATH" | head -$ROOT_PARTITION_INDEX | tail -1)
|
||||
ROOT_PARTITION_GUID=$(echo $ROOT_PARTITION_INFO | cut -d' ' -f6)
|
||||
|
||||
INSTALLER_BUILD_DIR=$BANAN_ROOT_DIR/bootloader/installer/build
|
||||
INSTALLER_BUILD_DIR=$BANAN_ROOT_DIR/bootloader/installer/build/$BANAN_ARCH
|
||||
BOOTLOADER_ELF=$BANAN_BUILD_DIR/bootloader/bios/bootloader
|
||||
|
||||
if ! [ -f $BOOTLOADER_ELF ]; then
|
||||
|
@ -37,11 +42,11 @@ fi
|
|||
if ! [ -d $INSTALLER_BUILD_DIR ]; then
|
||||
mkdir -p $INSTALLER_BUILD_DIR
|
||||
cd $INSTALLER_BUILD_DIR
|
||||
$CMAKE_COMMAND ..
|
||||
$CMAKE_COMMAND ../..
|
||||
fi
|
||||
|
||||
cd $INSTALLER_BUILD_DIR
|
||||
make
|
||||
|
||||
echo installing bootloader
|
||||
$INSTALLER_BUILD_DIR/x86_64-banan_os-bootloader-installer $BOOTLOADER_ELF $BANAN_DISK_IMAGE_PATH $ROOT_PARTITION_GUID
|
||||
$INSTALLER_BUILD_DIR/banan_os-bootloader-installer $BOOTLOADER_ELF $BANAN_DISK_IMAGE_PATH $ROOT_PARTITION_GUID
|
||||
|
|
Loading…
Reference in New Issue