1
0
mirror of https://github.com/taigrr/gopher-os synced 2025-01-18 04:43:13 -08:00

137 Commits

Author SHA1 Message Date
Achilleas Anagnostopoulos
0bbaa1dbff Use correct FP offset for fetching the values passed to cpu.PortWriteXXX 2017-07-05 17:09:19 +01:00
Achilleas Anagnostopoulos
40521f8626 Ensure that the memory returned by sysAlloc is always zeroed 2017-07-05 16:50:59 +01:00
Achilleas Anagnostopoulos
dd63b23246 Merge pull request #37 from achilleasa/support-cpuid-and-implement-port-rw-helpers
Support CPUID and implement port R/W asm helpers
2017-07-02 19:27:30 +01:00
Achilleas Anagnostopoulos
4f3312b85d Implement functions for reading/writing from/to IO ports 2017-07-02 19:21:09 +01:00
Achilleas Anagnostopoulos
e4879b9f8a Support the CPUID instruction 2017-07-02 19:21:04 +01:00
Achilleas Anagnostopoulos
e580dea9d1 Merge pull request #36 from achilleasa/use-project-specific-go-workspace
Use project-specific go workspace and rewrite import paths
2017-07-02 06:58:36 +01:00
Achilleas Anagnostopoulos
5f8f42a0c5 Override GOPATH when collecting coverage 2017-07-02 06:39:19 +01:00
Achilleas Anagnostopoulos
f961270904 Use the new Go workspace paths when building qualified symbol names 2017-07-02 06:39:19 +01:00
Achilleas Anagnostopoulos
00fdf79888 Append pwd to GOPATH when compiling the kernel
The Makefile changes create a standalone Go workspace routed at pwd
2017-07-02 06:39:13 +01:00
Achilleas Anagnostopoulos
8dfc5d4e92 Use pwd as a workspace; move sources to src/gopheros and rewrite imports
By setting up pwd as a Go workspace, we can trim import paths from
something like "github.com/achilleasa/gopher-os/kernel" to just
"kernel".

These changes make forking easier and also allows us to move the code to
a different git hosting provider without having to rewrite the imports.
2017-07-01 20:37:09 +01:00
Achilleas Anagnostopoulos
7b93d01c6e Merge pull request #35 from achilleasa/bootstrap-interfaces-and-map-primitive
Enable support for interfaces and the map primitive
2017-06-30 18:35:10 +01:00
Achilleas Anagnostopoulos
cd7e7ed15a Enable support for interfaces and the map primitive 2017-06-30 18:17:03 +01:00
Achilleas Anagnostopoulos
264ea09b9a Merge pull request #33 from achilleasa/bootstrap-go-allocator
Bootstrap Go allocator
2017-06-30 09:30:44 +01:00
Achilleas Anagnostopoulos
effc6710d9 Initialize Go memory allocator 2017-06-30 09:21:05 +01:00
Achilleas Anagnostopoulos
b4f4a9a738 Provide replacement for runtime.sysAlloc 2017-06-30 09:21:05 +01:00
Achilleas Anagnostopoulos
636220ab1d Unexport bitmap allocator instance and export AllocFrame helper
This allows us to mock calls to the frame allocator from other packages
while testing.
2017-06-30 09:21:05 +01:00
Achilleas Anagnostopoulos
6ee95b439e Provide replacement for runtime.sysReserve 2017-06-30 09:21:05 +01:00
Achilleas Anagnostopoulos
5e5e9f1c0b Redirect runtime.throw to kernel.Panic via kernel.panicString 2017-06-30 09:21:05 +01:00
Achilleas Anagnostopoulos
ce34763e23 Redirects tool should only consider comments attached to functions 2017-06-30 09:21:05 +01:00
Achilleas Anagnostopoulos
336cbb415d Fix lint warning 2017-06-30 09:20:24 +01:00
Achilleas Anagnostopoulos
df6e4314ca Merge pull request #34 from achilleasa/remove-hardcoded-g-offsets-from-rt0-code
Remove hardcoded g offsets from rt0 code and use runtime.g0/m0
2017-06-30 09:18:17 +01:00
Achilleas Anagnostopoulos
b733915536 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
2017-06-30 09:08:32 +01:00
Achilleas Anagnostopoulos
6820ffef2b Generate offset definitions as part of the build process
The Makefile contains rules for invoking the offsets tool to generate
the offset definitions for members of the g, m and stack structs. The
definitions are stored in BUILD_DIR and BUILD_DIR is passed as an
include target to nasm.
2017-06-30 09:01:41 +01:00
Achilleas Anagnostopoulos
62aca2f2de Implement tool for calculating offsets into g, m and stack structs
The offsets tool is essentially a wrapper around "go build -a -n". It
creates a temporary folder with a dummy go file and runs the above
command using the target OS/ARCH for the kernel and captures the output.
The use of the "-a" flag forces go build to generate a build script for
rebuilding all packages including the runtime ones. As a by-product of
building the runtime package, the compiler emits the "go_asm.h" file
that contains (among other things) the offsets for each element of the
g, m and stack structures (see src/runtime/runtime2.go).

These offsets are used in Go assembly files instead of hardcoded
offsets. For example the following snippet accesses the pointer to m in
the g struct address stored at register CX:

MOVQ TLS, CX
MOVQ g_m(CX), BX

The offsets tool modifies the captured output from the go build command
so it only includes the steps up to building the runtime package,
executes the build script and post-processes the generated go_asm.h file
to retain the entries relevant to g, m and stack and then formats them
so they are compatible with nasm definitions (name equ value).

Depending on the value of the "-out" option, the tool outputs the
generated definitions either to STDOUT (default value for -out) or to a
file.
2017-06-30 09:01:41 +01:00
Achilleas Anagnostopoulos
0c79af3f90 Substitute source paths when running GDB on OSX
The generated DWARF information contains absolute file paths for the
source files which causes issues when debugging on OSX as GDB cannot
lookup the source files.
2017-06-28 18:18:00 +01:00
Achilleas Anagnostopoulos
c9ca6e31eb Merge pull request #32 from achilleasa/improve-debugging
Use latest Go in Vagrantfile and improve debugging
2017-06-28 08:08:27 +01:00
Achilleas Anagnostopoulos
b286c4c0d4 Remove gccgo from Vagrantfile provision section and replace it with make
gccgo was used in early gopher-os experiments as is not required for
building gopher-os
2017-06-28 08:05:12 +01:00
Achilleas Anagnostopoulos
d65c29ce63 Imrpove debug process
Summary of changes:
- when building the gdb target, the source is built with optimizations
  and inlining disabled (-N -l)
- source Go gdb helpers when running the gdb target
- set split layout (asm + code)
2017-06-28 07:53:28 +01:00
Achilleas Anagnostopoulos
cbf36d46ee Install Go 1.8.3 2017-06-28 07:29:04 +01:00
Achilleas Anagnostopoulos
2ea1f43d0e Merge pull request #31 from achilleasa/trampoline-based-runtime-call-redirects
Trampoline-based runtime call redirects
2017-06-26 05:43:20 +01:00
Achilleas Anagnostopoulos
5fc6ce188e Use go:redirect-from directive to map panic to kernel.Panic
All calls (but one) to kernel.Panic have been replaced by calls to
panic. A call to kernel.Panic is still required to prevent the compiler
from treating kernel.Panic as dead code and eliminating it.
2017-06-25 21:39:56 +01:00
Achilleas Anagnostopoulos
b238442ccc Use redirects tool with nasm and as a post-link step 2017-06-25 21:39:20 +01:00
Achilleas Anagnostopoulos
d17f582c0b Reserve space for redirect table and install trampolines
The rt0_64 code reserves space for _rt0_redirect_table using the output
from the redirect tool's "count" command as a hint to the size of the
table. The table itself is located in the .goredirectstbl section which
the linker moves to a dedicated section in the final ELF image.

When the kernel boots, the _rt0_install_redirect_trampolines function
iterates the _rt0_redirect_table entries (populated as a post-link step)
and overwrite the original function code with a trampoline that
redirects control to the destination function.

The trampoline is implemented as a 14-byte instruction that exploits
rip-relative addressing to ensure that no registers are made dirty. The
actual trampoline code looks like this:

jmp [rip+0]                 ; 6-bytes
dq abs_address_to_jump_to   ; 8-bytes

The _rt0_install_redirect_trampolines function sets up the abs_address
to "dst" for each (src, dst) tuple and then copies the trampoline to
"src". After the trampoline is installed, any calls to "src" will be
transparently redirected to "dst". This hack (modifying code in the
.text section) is only possible because the code runs in supervisor mode
before memory protection is enabled.
2017-06-25 21:39:20 +01:00
Achilleas Anagnostopoulos
275664219e Implement tool to detect redirects and to populate the redirect table
The tool scans all go sources (excluding tests) in the "kernel" package
and its subpackages looking for functions with a "go:redirect-from
symbol_name" comment. The go:redirect-from directive implies that a
function serves as a redirect target for s symbol name.  For example,
the following block:

//go:redirect-from runtime.gopanic
func foo(_ interface{}){
	...
}

specifies that calls to "runtime.gopanic" should be redirected to "foo".

The tool provides two commands:
- count: prints the count of redirections
- populate-table: resolve redirect symbols and populate the
  _rt0_rediret_table entries in the kernel image.

As the final virtual addresses for the symbols are only known after
linking, populating this table is a 2-step process. At first, the
"count" command is used to allocate enough space for 2 x NUM_REDIRECTS
pointers. The table itself is placed with the help of the linker script
in a separate section making it easy to find its offset in the ELF
image.

After the kernel is linked, the "populate-table" command use the
debug/elf package to scan the image file and resolve the addresses for
the src and dst redirection symbols. The tool will then open the image
file in RW mode, seek to the location of the table and write the symbol
addresses for each (src, dst) tuple.
2017-06-25 21:39:16 +01:00
Achilleas Anagnostopoulos
39c0a96fa2 Merge pull request #30 from achilleasa/implement-copy-on-write-pages
Implement copy on write pages
2017-06-22 20:30:46 +01:00
Achilleas Anagnostopoulos
1fc9d20ed2 Reserve and protect zereod frame when initializing vmm
This vmm package exports ReservedZeroedFrame which can be used to setup
a lazy physical page allocation scheme. This is implemented by mapping
ReservedZeroedFrame to each page in a virtual memory region using the
following flag combination: FlagPresent | FlagCopyOnWrite.

This has the effect that all reads from the virtual address region
target the contents of ReservedZeroedFrame (always returning zero). On
the other hand, writes to the virtual address region trigger a page
fault which is resolved as follows:
- a new physical frame is allocated and the contents of ReservedZeroedFrame
  are copied to it (effectively clearing the new frame).
- the page entry for the virtual address that caused the fault is
  updated to point to the new frame and its flags are changed to:
  FlagPresent | FlagRW
- execution control is returned back to the code that caused the fault
2017-06-22 19:17:19 +01:00
Achilleas Anagnostopoulos
32a10601ac Add support for copy-on-write to the page fault handler
Page faults occurring on RO pages with the CopyOnWrite flag set will be
handled by the page handler as follows:
- allocate new frame
- establish temporary mapping for new frame
- copy original page to new frame
- update entry for the page where the fault occurred:
  - set physical frame address to the allocated frame
  - clear CoW flag and set Present, RW flags
- return from the fault handler to resume execution at the instruction
  that caused the fault

Any other page faults will still cause a kernel panic
2017-06-22 07:44:55 +01:00
Achilleas Anagnostopoulos
56d23f50ae Enable page write protection for both kernel and user space
If the WP bit in CR0 is not set then write protection for pages is only
enforced for user-land code.
2017-06-22 06:24:30 +01:00
Achilleas Anagnostopoulos
42ee2d1325 Implement memcopy 2017-06-22 06:06:05 +01:00
Achilleas Anagnostopoulos
71dfc9ae70 FlagPresent must be explicitly specified in calls to Map 2017-06-22 05:41:32 +01:00
Achilleas Anagnostopoulos
37ba897ca4 Merge pull request #29 from achilleasa/install-exception-handlers
Install exception handlers for page fault and GPF exceptions
2017-06-22 05:34:07 +01:00
Achilleas Anagnostopoulos
56d031621d Make qemu log exceptions and prevent reboots in case of triple faults 2017-06-21 21:41:31 +01:00
Achilleas Anagnostopoulos
6e8d504ae8 Install exception handlers for page faults/GPFs and provide kernel.Panic 2017-06-21 21:41:24 +01:00
Achilleas Anagnostopoulos
c5aa5fe05f Add method for reading the CR2 register value
This will allow us to figure out the virtual address that caused a page-
or general protection fault.
2017-06-21 21:36:59 +01:00
Achilleas Anagnostopoulos
9adde8f5c1 Define and implement API for registering exception handlers 2017-06-21 21:36:55 +01:00
Achilleas Anagnostopoulos
5a2efb2bd3 Load IDT and define gate error-code-aware handlers (rt0/x86_64)
The rt0_64 code will load a blank IDT with 256 entries (the max number
of supported interrupts in the x86_64 architecture). Each IDT entry is
set as *not present* but its handler is set to a dedicated gate entrypoint
defined in the rt0 code.

A gate entrypoint is defined for each interrupt number using a nasm
macro. Each entrypoint will then use the interrupt number to index a
list of pointers (defined and managed by the Go assembly code in
the irq pkg) to the registered interrupt handlers and push its address
on the stack before jumping to one of the two available gate dispatching
functions (some interrupts also push an error code to the stack which
must be popped before returning from the interrupt handler):
- _rt0_64_gate_dispatcher_with_code
- _rt0_64_gate_dispatcher_without_code

Both dispatchers operate in the same way:
- they save the original registers
- they invoke the interrupt handler
- they restore the original registers
- ensure that the stack pointer (rsp) points to the exception frame
  pushed by the CPU

The difference between the dispatchers is that the "with_code" variant
will invoke a handler with signature `func(code, &frame, &regs)` and
ensure that the code is popped off the stack before returning from the
interrupt while the "without_code" variant will invoke a handler with
signature `func(&frame, &regs)`
2017-06-21 17:46:41 +01:00
Achilleas Anagnostopoulos
827f1a171f Load SS register value to DS_SEG when setting up GDT
If not set then the CPU wil generate a GPF exception when returning from
an interrupt handler
2017-06-21 17:29:29 +01:00
Achilleas Anagnostopoulos
cd3199199b Add assemnly code for enabling/disabling insterrupts and halting the CPU 2017-06-21 07:59:48 +01:00
Achilleas Anagnostopoulos
d793300279 Move TLB-handling code to the cpu pkg 2017-06-21 07:57:05 +01:00
Achilleas Anagnostopoulos
3923e09aac Merge pull request #27 from achilleasa/implement-bitmap-allocator
Implement bitmap-based physical page allocator
2017-06-19 06:18:18 +01:00