From 4e3567f8a1348b5d8e667193d4f68dfb437dc6b9 Mon Sep 17 00:00:00 2001 From: Achilleas Anagnostopoulos Date: Mon, 19 Mar 2018 09:01:34 +0000 Subject: [PATCH 1/6] tools: update offsets tool to work with go versions 1.7 - 1.10 Older go versions (1.7.x) specify a fixed page size (_PageSize const) as part of their runtime whereas newer go versions populate the page size at runtime. The kernel asm bootstrap code was written with go 1.8 in mind. As a result it attempts to populate the page size manually which obviously breaks compilation in go 1.7. The offsets tool has been updated to emit the special def "SKIP_PAGESIZE_SETUP" when running under go 1.7 which allows us to perform conditional compilation of the page setup code inside the bootstrap asm code. fixup --- Makefile | 3 +- src/arch/x86_64/asm/data.s | 0 src/arch/x86_64/asm/rt0_64.s | 132 ++++++++++++++++++----------------- tools/offsets/offsets.go | 54 ++++++++++++-- 4 files changed, 116 insertions(+), 73 deletions(-) delete mode 100644 src/arch/x86_64/asm/data.s diff --git a/Makefile b/Makefile index 1a49ab9..794deed 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,6 @@ FUZZ_PKG_LIST := src/gopheros/device/acpi/aml ifeq ($(OS), Linux) export SHELL := /bin/bash -o pipefail - LD := ld AS := nasm @@ -105,7 +104,7 @@ $(BUILD_DIR)/go_asm_offsets.inc: @mkdir -p $(BUILD_DIR) @echo "[tools:offsets] calculating OS/arch-specific offsets for g, m and stack structs" - @GOPATH=$(GOPATH) $(GO) run tools/offsets/offsets.go -target-os $(GOOS) -target-arch $(GOARCH) -go-binary $(GO) -out $@ + @GOROOT=$(GOROOT) GOPATH=$(GOPATH) $(GO) run tools/offsets/offsets.go -target-os $(GOOS) -target-arch $(GOARCH) -go-binary $(GO) -out $@ $(BUILD_DIR)/arch/$(ARCH)/asm/%.o: src/arch/$(ARCH)/asm/%.s @mkdir -p $(shell dirname $@) diff --git a/src/arch/x86_64/asm/data.s b/src/arch/x86_64/asm/data.s deleted file mode 100644 index e69de29..0000000 diff --git a/src/arch/x86_64/asm/rt0_64.s b/src/arch/x86_64/asm/rt0_64.s index bf1f115..fb42fc9 100644 --- a/src/arch/x86_64/asm/rt0_64.s +++ b/src/arch/x86_64/asm/rt0_64.s @@ -17,17 +17,17 @@ _rt0_idt_desc: resw 1 resq 1 -; Allocates space for the IRQ handlers pointers registered by the IRQ package +; Allocates space for the IRQ handlers pointers registered by the IRQ package _rt0_irq_handlers resq IDT_ENTRIES ; According to the "ELF handling for TLS" document section 3.4.6 ; (https://www.akkadia.org/drepper/tls.pdf) for the GNU variant for x86-64, -; fs:0x00 contains a pointer to the TCB. Variables in the TLS are stored +; fs:0x00 contains a pointer to the TCB. Variables in the TLS are stored ; before the TCB and are accessed using negative offsets from the TCB address. -r0_g_ptr: resq 1 -tcb_ptr: resq 1 +r0_g_ptr: resq 1 +tcb_ptr: resq 1 -section .text +section .text ;------------------------------------------------------------------------------ ; Kernel 64-bit entry point @@ -36,7 +36,7 @@ section .text ; - it has entered long mode and enabled paging ; - it has loaded a 64bit GDT ; - it has set up identity paging for the physical 0-8M region and the -; PAGE_OFFSET to PAGE_OFFSET+8M region. +; PAGE_OFFSET to PAGE_OFFSET+8M region. ;------------------------------------------------------------------------------ global _rt0_64_entry _rt0_64_entry: @@ -50,7 +50,7 @@ _rt0_64_entry: extern _kernel_start extern _kernel_end extern kernel.Kmain - + mov rax, PAGE_OFFSET push rax mov rax, _kernel_end - PAGE_OFFSET @@ -60,7 +60,7 @@ _rt0_64_entry: mov rax, multiboot_data push rax call kernel.Kmain - + ; Main should never return; halt the CPU mov rdi, err_kmain_returned call write_string @@ -75,13 +75,15 @@ _rt0_64_entry: _rt0_64_setup_go_runtime_structs: %include "go_asm_offsets.inc" ; generated by tools/offsets + %ifndef SKIP_PAGESIZE_SETUP ; 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. + ; As the kernel bypasses osinit() this needs to be manually set here. extern runtime.physPageSize mov rax, runtime.physPageSize mov qword [rax], 0x1000 ; 4096 - - ; Setup r0_g stack limits using the reserved stack + %endif + + ; Setup r0_g stack limits using the reserved stack extern stack_top extern stack_bottom extern runtime.g0 @@ -99,21 +101,21 @@ _rt0_64_setup_go_runtime_structs: 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 + ; Store the address of g0 in r0_g_ptr mov rax, r0_g_ptr mov qword [rax], rsi - ; According to the x86-64 ABI requirements fs:0x0 should point to the + ; According to the x86-64 ABI requirements fs:0x0 should point to the ; TCB. mov rax, tcb_ptr mov qword [rax], rax - ; Load 64-bit FS register address - ; eax -> lower 32 bits + ; Load 64-bit FS register address + ; eax -> lower 32 bits ; edx -> upper 32 bits mov ecx, 0xc0000100 ; fs_base mov rsi, tcb_ptr - mov rax, rsi ; lower 32 bits + mov rax, rsi ; lower 32 bits shr rsi, 32 mov rdx, rsi ; high 32 bits wrmsr @@ -122,26 +124,26 @@ _rt0_64_setup_go_runtime_structs: ;------------------------------------------------------------------------------ -; Setup and load IDT. We preload each IDT entry with a pointer to a gate handler -; but set it as inactive. The code in irq_amd64 is responsible for enabling +; Setup and load IDT. We preload each IDT entry with a pointer to a gate handler +; but set it as inactive. The code in irq_amd64 is responsible for enabling ; individual IDT entries when handlers are installed. ;------------------------------------------------------------------------------ _rt0_64_load_idt: mov rax, _rt0_idt_start -%assign gate_num 0 +%assign gate_num 0 %rep IDT_ENTRIES mov rbx, _rt0_64_gate_entry_%+ gate_num mov word [rax], bx ; gate entry bits 0-15 mov word [rax+2], 0x8 ; GDT descriptor - mov byte [rax+5], 0x0 ; Mark the entry as NOT present + mov byte [rax+5], 0x0 ; Mark the entry as NOT present shr rbx, 16 mov word [rax+6], bx ; gate entry bits 16-31 shr rbx, 16 mov dword [rax+8], ebx ; gate entry bits 32-63 add rax, 16 ; size of IDT entry -%assign gate_num gate_num+1 +%assign gate_num gate_num+1 %endrep mov rax, _rt0_idt_desc mov word [rax], _rt0_idt_end - _rt0_idt_start - 1 ; similar to GDT this must be len(IDT) - 1 @@ -152,15 +154,15 @@ ret ;------------------------------------------------------------------------------ -; Generate gate entries. Each gate handler pushes the address of the registered +; Generate gate entries. Each gate handler pushes the address of the registered ; handler to the stack before jumping to a dispatcher function. ; ; Some exceptions push an error code to the stack after the stack frame. This -; code must be popped off the stack before calling iretq. The generated handlers -; are aware whether they need to deal with the code or not and jump to the +; code must be popped off the stack before calling iretq. The generated handlers +; are aware whether they need to deal with the code or not and jump to the ; appropriate get dispatcher. ;------------------------------------------------------------------------------ -%assign gate_num 0 +%assign gate_num 0 %rep IDT_ENTRIES extern _rt0_interrupt_handlers _rt0_64_gate_entry_%+ gate_num: @@ -177,13 +179,13 @@ _rt0_64_gate_entry_%+ gate_num: %else jmp _rt0_64_gate_dispatcher_without_code %endif -%assign gate_num gate_num+1 +%assign gate_num gate_num+1 %endrep %macro save_regs 0 - push r15 + push r15 push r14 - push r13 + push r13 push r12 push r11 push r10 @@ -191,10 +193,10 @@ _rt0_64_gate_entry_%+ gate_num: push r8 push rbp push rdi - push rsi - push rdx - push rcx - push rbx + push rsi + push rdx + push rcx + push rbx push rax %endmacro @@ -203,13 +205,13 @@ _rt0_64_gate_entry_%+ gate_num: pop rbx pop rcx pop rdx - pop rsi + pop rsi pop rdi - pop rbp + pop rbp pop r8 pop r9 pop r10 - pop r11 + pop r11 pop r12 pop r13 pop r14 @@ -217,14 +219,14 @@ _rt0_64_gate_entry_%+ gate_num: %endmacro ;------------------------------------------------------------------------------ -; This dispatcher is invoked by gate entries that expect a code to be pushed +; This dispatcher is invoked by gate entries that expect a code to be pushed ; by the CPU to the stack. It performs the following functions: ; - save registers -; - push pointer to saved regs -; - push pointer to stack frame -; - read and push exception code +; - push pointer to saved regs +; - push pointer to stack frame +; - read and push exception code ; - invoke handler(code, &frame, ®s) -; - restore registers +; - restore registers ; - pop exception code from stack so rsp points to the stack frame ;------------------------------------------------------------------------------ _rt0_64_gate_dispatcher_with_code: @@ -236,7 +238,7 @@ _rt0_64_gate_dispatcher_with_code: ;-----------------| ; Exception code | <- needs to be removed from stack before calling iretq ;-----------------| - ; RIP | <- exception frame + ; RIP | <- exception frame ; CS | ; RFLAGS | ; RSP | @@ -244,12 +246,12 @@ _rt0_64_gate_dispatcher_with_code: ;----------------- cld - ; save regs and push a pointer to them + ; save regs and push a pointer to them save_regs mov rax, rsp ; rax points to saved rax push rax ; push pointer to saved regs - ; push pointer to exception stack frame (we have used 15 qwords for the + ; push pointer to exception stack frame (we have used 15 qwords for the ; saved registers plus one qword for the data pushed by the gate entry ; plus one extra qword to jump over the exception code) add rax, 17*8 @@ -261,7 +263,7 @@ _rt0_64_gate_dispatcher_with_code: call [rsp + 18*8] ; call registered irq handler - add rsp, 3 * 8 ; unshift the pushed arguments so rsp points to the saved regs + add rsp, 3 * 8 ; unshift the pushed arguments so rsp points to the saved regs restore_regs add rsp, 16 ; pop handler address and exception code off the stack before returning @@ -271,10 +273,10 @@ _rt0_64_gate_dispatcher_with_code: ; This dispatcher is invoked by gate entries that do not use exception codes. ; It performs the following functions: ; - save registers -; - push pointer to saved regs -; - push pointer to stack frame +; - push pointer to saved regs +; - push pointer to stack frame ; - invoke handler(&frame, ®s) -; - restore registers +; - restore registers ;------------------------------------------------------------------------------ _rt0_64_gate_dispatcher_without_code: ; This is how the stack looks like when entering this function: @@ -283,7 +285,7 @@ _rt0_64_gate_dispatcher_without_code: ;------------------ ; handler address | <- pushed by gate_entry_xxx (RSP points here) ;-----------------| - ; RIP | <- exception frame + ; RIP | <- exception frame ; CS | ; RFLAGS | ; RSP | @@ -291,21 +293,21 @@ _rt0_64_gate_dispatcher_without_code: ;----------------- cld - ; save regs and push a pointer to them + ; save regs and push a pointer to them save_regs mov rax, rsp ; rax points to saved rax push rax ; push pointer to saved regs - ; push pointer to exception stack frame (we have used 15 qwords for the + ; push pointer to exception stack frame (we have used 15 qwords for the ; saved registers plus one qword for the data pushed by the gate entry) add rax, 16*8 push rax call [rsp + 17*8] ; call registered irq handler - add rsp, 2 * 8 ; unshift the pushed arguments so rsp points to the saved regs + add rsp, 2 * 8 ; unshift the pushed arguments so rsp points to the saved regs restore_regs - + add rsp, 8 ; pop handler address off the stack before returning iretq @@ -340,13 +342,13 @@ write_string: ; runtime functions to the kernel's own implementation without the need to ; export/globalize any symbols. This works by first setting up a redirect table ; (populated by a post-link step) that contains the addresses of the symbol to -; hook and the address where calls to that symbol should be redirected. +; hook and the address where calls to that symbol should be redirected. ; ; This function iterates the redirect table entries and for each entry it ; sets up a trampoline to the dst symbol and overwrites the code in src with -; the 14-byte long _rt0_redirect_trampoline code. +; the 14-byte long _rt0_redirect_trampoline code. ; -; Note: this code modification is only possible because we are currently +; Note: this code modification is only possible because we are currently ; operating in supervisor mode with no memory protection enabled. Under normal ; conditions the .text section should be flagged as read-only. ;------------------------------------------------------------------------------ @@ -355,7 +357,7 @@ _rt0_install_redirect_trampolines: mov rdx, NUM_REDIRECTS _rt0_install_redirect_rampolines.next: - mov rdi, [rax] ; the symbol address to hook + mov rdi, [rax] ; the symbol address to hook mov rbx, [rax+8] ; the symbol to redirect to ; setup trampoline target and copy it to the hooked symbol @@ -364,15 +366,15 @@ _rt0_install_redirect_rampolines.next: mov rcx, 14 rep movsb ; copy rcx bytes from rsi to rdi - add rax, 16 - dec rdx + add rax, 16 + dec rdx jnz _rt0_install_redirect_rampolines.next ret ;------------------------------------------------------------------------------ -; This trampoline exploits rip-relative addressing to allow a jump to a -; 64-bit address without the need to touch any registers. The generated +; This trampoline exploits rip-relative addressing to allow a jump to a +; 64-bit address without the need to touch any registers. The generated ; code is equivalent to: ; ; jmp [rip+0] @@ -380,14 +382,14 @@ _rt0_install_redirect_rampolines.next: ;------------------------------------------------------------------------------ _rt0_redirect_trampoline: db 0xff ; the first 6 bytes encode a "jmp [rip+0]" instruction - db 0x25 - dd 0x00 + db 0x25 + dd 0x00 dq 0x00 ; the absolute address to jump to ;------------------------------------------------------------------------------ -; The redirect table is placed in a dedicated section allowing us to easily +; The redirect table is placed in a dedicated section allowing us to easily ; find its offset in the kernel image file. As the VMA addresses of the src -; and target symbols for the redirect are now known in advance we just reserve +; and target symbols for the redirect are now known in advance we just reserve ; enough space space for the src and dst addresses using the NUM_REDIRECTS ; define which is calculated by the Makefile and passed to nasm. ;------------------------------------------------------------------------------ @@ -395,7 +397,7 @@ section .goredirectstbl _rt0_redirect_table: %rep NUM_REDIRECTS - dq 0 ; src: address of the symbol we want to redirect + dq 0 ; src: address of the symbol we want to redirect dq 0 ; dst: address of the symbol where calls to src are redirected to %endrep diff --git a/tools/offsets/offsets.go b/tools/offsets/offsets.go index c749906..7080e22 100644 --- a/tools/offsets/offsets.go +++ b/tools/offsets/offsets.go @@ -7,6 +7,8 @@ import ( "io/ioutil" "os" "os/exec" + "path/filepath" + "runtime" "strconv" "strings" "time" @@ -30,6 +32,7 @@ func genBuildScript(targetOS, targetArch, goBinary, workDir string) ([]byte, err // rebuild the runtime packages. cmd := exec.Command(goBinary, "build", "-a", "-n") cmd.Dir = workDir + cmd.Env = append(cmd.Env, fmt.Sprintf("GOROOT=%s", os.Getenv("GOROOT"))) cmd.Env = append(cmd.Env, fmt.Sprintf("GOOS=%s", targetOS)) cmd.Env = append(cmd.Env, fmt.Sprintf("GOARCH=%s", targetArch)) out, err := cmd.CombinedOutput() @@ -41,13 +44,18 @@ func genBuildScript(targetOS, targetArch, goBinary, workDir string) ([]byte, err } func patchBuildScript(script []byte, workDir, targetOS, targetArch, goBinary string) ([]byte, error) { - lines := strings.Split(string(script), "\n") + // Replace $WORK with the workDir location. This is required for executing + // build scripts generated by go 1.10 + lines := strings.Split( + strings.Replace(string(script), "$WORK", workDir, -1), + "\n", + ) // Inject os/arch and workdir to the top of the build file header := []string{ + fmt.Sprintf("export GOROOT=%s", os.Getenv("GOROOT")), fmt.Sprintf("export GOOS=%s", targetOS), fmt.Sprintf("export GOARCH=%s", targetArch), - fmt.Sprintf("WORK=%q", workDir), fmt.Sprintf("alias pack='%s tool pack'", goBinary), } lines = append(header, lines...) @@ -58,7 +66,7 @@ func patchBuildScript(script []byte, workDir, targetOS, targetArch, goBinary str var stopOnNextComment bool for lineIndex := 0; lineIndex < len(lines); lineIndex++ { // Ignore empty comments - if lines[lineIndex] == "#" { + if strings.TrimSpace(lines[lineIndex]) == "#" || strings.Contains(lines[lineIndex], "# import") { continue } @@ -97,8 +105,32 @@ func execBuildScript(script []byte, workDir string) error { } func genAsmIncludes(workDir string) ([]byte, error) { - headers, err := ioutil.ReadFile(fmt.Sprintf("%s/runtime/_obj/go_asm.h", workDir)) - if err != nil { + // Find all generated go_asm.h files and concat their conentents + var ( + allHeaders, headers []byte + ) + + if err := filepath.Walk(workDir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + if info.IsDir() { + return nil + } + + if filepath.Base(path) != "go_asm.h" { + return nil + } + + if headers, err = ioutil.ReadFile(path); err != nil { + return err + } + + allHeaders = append(allHeaders, '\n') + allHeaders = append(allHeaders, headers...) + return nil + }); err != nil { return nil, err } @@ -106,7 +138,7 @@ func genAsmIncludes(workDir string) ([]byte, error) { includes = append(includes, "; vim: set ft=nasm :\n") includes = append(includes, fmt.Sprintf("; generated by tools/offsets at %v\n", time.Now())) - for _, line := range strings.Split(string(headers), "\n") { + for _, line := range strings.Split(string(allHeaders), "\n") { line = strings.TrimPrefix(line, "#define ") // We are only interested in the offsets for the g, m and stack structures @@ -131,6 +163,16 @@ func genAsmIncludes(workDir string) ([]byte, error) { } } + // In go 1.7.x, the page size is given by the _PageSize constant whereas in + // newer go versions it is specified at runtime and needs to be manually set + // by our asm bootstrap code. + if strings.Contains(runtime.Version(), "go1.7") { + includes = append(includes, + "; go 1.7 runtime uses a fixed 4k page size for our target arch so our bootstrap code does not need to do any extra work to set it up", + "%define SKIP_PAGESIZE_SETUP 1", + ) + } + return []byte(strings.Join(includes, "\n")), nil } From 8d0c44921bdf00fe84651380bf52f8f6524a1abd Mon Sep 17 00:00:00 2001 From: Achilleas Anagnostopoulos Date: Fri, 23 Mar 2018 07:20:22 +0000 Subject: [PATCH 2/6] goruntime: split bootstrap symbols into conditionally compiled files Due to some changes in the runtime init functions between go 1.7 and later versions (e.g. runtime.modulesInit() defined after go 1.7), the kernel code that bootstraps the go runtime had to be split into separate files which are conditionally compiled using +build flags. --- src/gopheros/kernel/goruntime/bootstrap.go | 23 +------------- .../kernel/goruntime/bootstrap_go17.go | 30 +++++++++++++++++++ .../kernel/goruntime/bootstrap_go18+.go | 28 +++++++++++++++++ 3 files changed, 59 insertions(+), 22 deletions(-) create mode 100644 src/gopheros/kernel/goruntime/bootstrap_go17.go create mode 100644 src/gopheros/kernel/goruntime/bootstrap_go18+.go diff --git a/src/gopheros/kernel/goruntime/bootstrap.go b/src/gopheros/kernel/goruntime/bootstrap.go index e51fedc..4bdd5bd 100644 --- a/src/gopheros/kernel/goruntime/bootstrap.go +++ b/src/gopheros/kernel/goruntime/bootstrap.go @@ -27,27 +27,6 @@ var ( prngSeed = 0xdeadc0de ) -//go:linkname algInit runtime.alginit -func algInit() - -//go:linkname modulesInit runtime.modulesinit -func modulesInit() - -//go:linkname typeLinksInit runtime.typelinksinit -func typeLinksInit() - -//go:linkname itabsInit runtime.itabsinit -func itabsInit() - -//go:linkname mallocInit runtime.mallocinit -func mallocInit() - -//go:linkname mSysStatInc runtime.mSysStatInc -func mSysStatInc(*uint64, uintptr) - -//go:linkname procResize runtime.procresize -func procResize(int32) uintptr - // initGoPackages is an alias to main.init which recursively calls the init() // methods in all imported packages. Unless this function is called, things like // package errors will not be properly initialized causing various problems when @@ -184,7 +163,7 @@ func getRandomData(r []byte) { func Init() *kernel.Error { mallocInitFn() algInitFn() // setup hash implementation for map keys - modulesInitFn() // provides activeModules + modulesInitFn() // provides activeModules (go 1.8+) typeLinksInitFn() // uses maps, activeModules itabsInitFn() // uses activeModules diff --git a/src/gopheros/kernel/goruntime/bootstrap_go17.go b/src/gopheros/kernel/goruntime/bootstrap_go17.go new file mode 100644 index 0000000..6022c01 --- /dev/null +++ b/src/gopheros/kernel/goruntime/bootstrap_go17.go @@ -0,0 +1,30 @@ +// +build go1.7,!go1.8 + +package goruntime + +import ( + _ "unsafe" // required for go:linkname +) + +//go:linkname algInit runtime.alginit +func algInit() + +//go:linkname typeLinksInit runtime.typelinksinit +func typeLinksInit() + +//go:linkname itabsInit runtime.itabsinit +func itabsInit() + +//go:linkname mallocInit runtime.mallocinit +func mallocInit() + +//go:linkname mSysStatInc runtime.mSysStatInc +func mSysStatInc(*uint64, uintptr) + +//go:linkname procResize runtime.procresize +func procResize(int32) uintptr + +// modulesInit is defined on go1.8 so just declare an empty +// stub for go 1.7 to keep the compiler happy. +func modulesInit() { +} diff --git a/src/gopheros/kernel/goruntime/bootstrap_go18+.go b/src/gopheros/kernel/goruntime/bootstrap_go18+.go new file mode 100644 index 0000000..90eaaf2 --- /dev/null +++ b/src/gopheros/kernel/goruntime/bootstrap_go18+.go @@ -0,0 +1,28 @@ +// +build go1.8 + +package goruntime + +import ( + _ "unsafe" // required for go:linkname +) + +//go:linkname algInit runtime.alginit +func algInit() + +//go:linkname modulesInit runtime.modulesinit +func modulesInit() + +//go:linkname typeLinksInit runtime.typelinksinit +func typeLinksInit() + +//go:linkname itabsInit runtime.itabsinit +func itabsInit() + +//go:linkname mallocInit runtime.mallocinit +func mallocInit() + +//go:linkname mSysStatInc runtime.mSysStatInc +func mSysStatInc(*uint64, uintptr) + +//go:linkname procResize runtime.procresize +func procResize(int32) uintptr From ce9a3970089838c4b3670a3232667ab021b5788b Mon Sep 17 00:00:00 2001 From: Achilleas Anagnostopoulos Date: Thu, 22 Mar 2018 08:00:17 +0000 Subject: [PATCH 3/6] bootstrap: add extra cgo stub symbols for go 1.8 --- src/arch/x86_64/asm/cgo_stubs.s | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/arch/x86_64/asm/cgo_stubs.s b/src/arch/x86_64/asm/cgo_stubs.s index 75816dc..6e5241f 100644 --- a/src/arch/x86_64/asm/cgo_stubs.s +++ b/src/arch/x86_64/asm/cgo_stubs.s @@ -6,6 +6,7 @@ bits 64 global x_cgo_callers global x_cgo_init global x_cgo_mmap +global x_cgo_munmap global x_cgo_notify_runtime_init_done global x_cgo_sigaction global x_cgo_thread_start @@ -17,6 +18,7 @@ global _cgo_yield x_cgo_callers: x_cgo_init: x_cgo_mmap: +x_cgo_munmap: x_cgo_notify_runtime_init_done: x_cgo_sigaction: x_cgo_thread_start: From c0f92f445469d0b6d8ae79f644dadc26e6dd8fb7 Mon Sep 17 00:00:00 2001 From: Achilleas Anagnostopoulos Date: Fri, 23 Mar 2018 07:17:12 +0000 Subject: [PATCH 4/6] makefile: tweak build script to compile kernel using go 1.10 --- Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 794deed..07cfefb 100644 --- a/Makefile +++ b/Makefile @@ -61,11 +61,13 @@ go.o: -e "1s|^|export GOOS=$(GOOS)\n|" \ -e "1s|^|export GOARCH=$(GOARCH)\n|" \ -e "1s|^|export GOROOT=$(GOROOT)\n|" \ - -e "1s|^|WORK='$(BUILD_ABS_DIR)'\n|" \ + -e "1s|^|export CGO_ENABLED=0\n|" \ -e "1s|^|alias pack='$(GO) tool pack'\n|" \ -e "/^mv/d" \ + -e "/\/buildid/d" \ -e "s|-extld|-tmpdir='$(BUILD_ABS_DIR)' -linkmode=external -extldflags='-nostartfiles -nodefaultlibs -nostdlib -r' -extld|g" \ - | sh 2>&1 | sed -e "s/^/ | /g" + -e 's|$$WORK|$(BUILD_ABS_DIR)|g' \ + | sh 2>&1 | sed -e "s/^/ | /g" @# build/go.o is a elf32 object file but all go symbols are unexported. Our @# asm entrypoint code needs to know the address to 'main.main' so we use From bb81bb35507d4536829568562a6fde91beb346b9 Mon Sep 17 00:00:00 2001 From: Achilleas Anagnostopoulos Date: Mon, 19 Mar 2018 08:56:19 +0000 Subject: [PATCH 5/6] ci: run matrix build with go 1.7.x - 1.x The .travis.yml file has been updated so that CI will also attempt to build the kernel using the latest go branches from 1.7, 1.8, 1.9, 1.10, 1.x. The tests will only be run once against the latest go version. --- .travis.yml | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3ee48ed..7542fea 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,29 @@ language: go sudo: required +addons: + apt: + packages: + - nasm + - binutils-2.26 +# Compile kernel with various go versions go: + - 1.7.x + - 1.8.x + - 1.9.x + - 1.10.x - 1.x -script: - - make lint - - make collect-coverage -after_success: - - bash <(curl -s https://codecov.io/bash) +stage: build kernel +before_install: + - export PATH=/usr/lib/binutils-2.26/bin:${PATH} +script: make kernel + +# Run the tests against the latest go version +jobs: + include: + - stage: run tests + go: 1.x + script: + - make lint + - make collect-coverage + after_success: + - bash <(curl -s https://codecov.io/bash) From b39cdd5bd48eb15877e0894d3210b3f65dc08d39 Mon Sep 17 00:00:00 2001 From: Achilleas Anagnostopoulos Date: Fri, 23 Mar 2018 08:36:27 +0000 Subject: [PATCH 6/6] docs: add badges for matrix builds and update build instructions --- BUILD.md | 2 +- README.md | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/BUILD.md b/BUILD.md index 6959cdb..694c0ff 100644 --- a/BUILD.md +++ b/BUILD.md @@ -11,7 +11,7 @@ To compile gopher-os wheh running on Linux you need a fairly recent version of: - grub - nasm - gcc (for GNU ld) -- go (1.6+; recommended: 1.8) +- go 1.7+ The above dependencies can be installed using the appropriate package manager for each particular Linux distribution. diff --git a/README.md b/README.md index 0a6d771..6a3822e 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,17 @@ [![Go Report Card](https://goreportcard.com/badge/github.com/achilleasa/gopher-os)](https://goreportcard.com/report/github.com/achilleasa/gopher-os) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) +| Go 1.7.x | Go 1.8.x | Go 1.9.x | Go 1.10.x | Go 1.x | +|---------------------|---------------------|---------------------|----------------------|-------------------| +| [![go 1.7.x][1]][6] | [![go 1.8.x][2]][6] | [![Go 1.9.x][3]][6] | [![go 1.10.x][4]][6] | [![go 1.x][5]][6] | + +[1]: https://travis-matrix-badges.herokuapp.com/repos/achilleasa/gopher-os/branches/master/1 +[2]: https://travis-matrix-badges.herokuapp.com/repos/achilleasa/gopher-os/branches/master/2 +[3]: https://travis-matrix-badges.herokuapp.com/repos/achilleasa/gopher-os/branches/master/3 +[4]: https://travis-matrix-badges.herokuapp.com/repos/achilleasa/gopher-os/branches/master/4 +[5]: https://travis-matrix-badges.herokuapp.com/repos/achilleasa/gopher-os/branches/master/5 +[6]: https://travis-ci.org/achilleasa/gopher-os + The goal of this project is to build a 64-bit POSIX-compliant tick-less kernel with a Linux-compatible syscall implementation using [Go](https://golang.org).