mirror of
https://github.com/taigrr/gopher-os
synced 2025-01-18 04:43:13 -08:00
Use runtime.g0, runtime.m0 and replace hardcoded offsets
The rt0 code implements a dedicated function for initializing the Go runtime structures. Instead of reserving space for a dummy g struct, the rt0 code now uses the g0 and m0 symbols defined by the runtime package. In addition to setting up g0, the rt0 also sets up the m0 struct and links it to g0. Setting up m0 is a requirement for properly bootstapping the malloc-related code in the following commits
This commit is contained in:
parent
6820ffef2b
commit
b733915536
@ -20,12 +20,9 @@ _rt0_idt_desc:
|
||||
; Allocates space for the IRQ handlers pointers registered by the IRQ package
|
||||
_rt0_irq_handlers resq IDT_ENTRIES
|
||||
|
||||
r0_g_ptr: resq 1 ; fs:0x00 is a pointer to the current g struct
|
||||
r0_g:
|
||||
r0_g_stack_lo: resq 1
|
||||
r0_g_stack_hi: resq 1
|
||||
r0_g_stackguard0: resq 1 ; rsp compared to this value in go stack growth prologue
|
||||
r0_g_stackguard1: resq 1 ; rsp compared to this value in C stack growth prologue
|
||||
; The FS register is loaded with the address of r0_g_ptr. fs:0x00 should contain
|
||||
; a pointer to the currently active g struct (in this case runtime.g0)
|
||||
r0_g_ptr: resq 1
|
||||
|
||||
section .text
|
||||
|
||||
@ -42,34 +39,7 @@ global _rt0_64_entry
|
||||
_rt0_64_entry:
|
||||
call _rt0_install_redirect_trampolines
|
||||
call _rt0_64_load_idt
|
||||
|
||||
; According to the x86_64 ABI, the fs:0 should point to the address of
|
||||
; the user-space thread structure. The actual TLS structure is located
|
||||
; just before that (aligned). Go code tries to fetch the address to the
|
||||
; active go-routine's g struct by accessing fs:-8. What we need to do
|
||||
; is to setup a mock g0 struct, populate its stack_lo/hi/guard fields
|
||||
; and then use wrmsr to update the FS register
|
||||
extern stack_top
|
||||
extern stack_bottom
|
||||
|
||||
; Setup r0_g
|
||||
mov rax, stack_bottom
|
||||
mov rbx, stack_top
|
||||
mov rsi, r0_g
|
||||
mov qword [rsi+0], rax ; stack_lo
|
||||
mov qword [rsi+8], rbx ; stack_hi
|
||||
mov qword [rsi+16], rax ; stackguard0
|
||||
mov rax, r0_g_ptr
|
||||
mov qword [rax], rsi
|
||||
|
||||
; Load 64-bit FS register address
|
||||
; rax -> lower 32 bits
|
||||
; rdx -> upper 32 bits
|
||||
mov ecx, 0xc0000100 ; fs_base
|
||||
mov rax, rsi ; lower 32 bits
|
||||
shr rsi, 32
|
||||
mov rdx, rsi ; high 32 bits
|
||||
wrmsr
|
||||
call _rt0_64_setup_go_runtime_structs
|
||||
|
||||
; Call the kernel entry point passing a pointer to the multiboot data
|
||||
; copied by the 32-bit entry code
|
||||
@ -93,6 +63,58 @@ _rt0_64_entry:
|
||||
cli
|
||||
hlt
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Setup m0, g0 and other symbols required for bootstrapping the Go runtime.
|
||||
; For the definitions of g and m see the Go runtime src: src/runtime/runtime2.go
|
||||
;------------------------------------------------------------------------------
|
||||
_rt0_64_setup_go_runtime_structs:
|
||||
%include "go_asm_offsets.inc" ; generated by tools/offsets
|
||||
|
||||
; The Go allocator expects this symbol to be set to the system page size
|
||||
; As the kernel bypass osinit() this needs to be set here.
|
||||
extern runtime.physPageSize
|
||||
mov rax, runtime.physPageSize
|
||||
mov qword [rax], 0x1000 ; 4096
|
||||
|
||||
; Setup r0_g stack limits using the reserved stack
|
||||
extern stack_top
|
||||
extern stack_bottom
|
||||
extern runtime.g0
|
||||
mov rax, stack_bottom
|
||||
mov rbx, stack_top
|
||||
mov rsi, runtime.g0
|
||||
mov qword [rsi+GO_G_STACK+GO_STACK_LO], rax ; g.stack.lo
|
||||
mov qword [rsi+GO_G_STACK+GO_STACK_HI], rbx ; g.stack.hi
|
||||
mov qword [rsi+GO_G_STACKGUARD0], rax ; g.stackguard0
|
||||
|
||||
; Link m0 to the g0
|
||||
extern runtime.m0
|
||||
mov rbx, runtime.m0
|
||||
mov qword [rbx+GO_M_G0], rsi ; m.g0 = g0
|
||||
mov qword [rsi+GO_G_M], rbx ; g.m = m
|
||||
|
||||
; Store the address of g0 in r0_g_ptr
|
||||
mov rax, r0_g_ptr
|
||||
mov qword [rax], rsi
|
||||
|
||||
; According to the x86_64 ABI, the fs register should contain the
|
||||
; address after the pointer to the pointer to the user-space thread
|
||||
; structure. This allows the Go runtime to retrieve the address of
|
||||
; the currently active g structure by accessing fs:-0x8.
|
||||
;
|
||||
; Load 64-bit FS register address
|
||||
; eax -> lower 32 bits
|
||||
; edx -> upper 32 bits
|
||||
mov ecx, 0xc0000100 ; fs_base
|
||||
mov rsi, r0_g_ptr
|
||||
add rsi, 8 ; fs -> r0_g_ptr + 0x8
|
||||
mov rax, rsi ; lower 32 bits
|
||||
shr rsi, 32
|
||||
mov rdx, rsi ; high 32 bits
|
||||
wrmsr
|
||||
|
||||
ret
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Setup and load IDT. We preload each IDT entry with a pointer to a gate handler
|
||||
|
Loading…
x
Reference in New Issue
Block a user