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

294 Commits

Author SHA1 Message Date
Achilleas Anagnostopoulos
52266c9f66 Make %x formatting verb in early.Printf behave like fmt.Printf
The %x verb in fmt.Printf does not add the "0x" prefix automatically so
early.Printf has been changed to match this behavior.
2017-05-15 07:05:07 +01:00
Achilleas Anagnostopoulos
1d8d81095c Merge pull request #11 from achilleasa/use-linter
Use linter and fix linter warnings
2017-05-15 06:59:01 +01:00
Achilleas Anagnostopoulos
cb0975c9c4 Fix linter errors 2017-05-15 06:55:31 +01:00
Achilleas Anagnostopoulos
1c17562f07 Add lint Makefile target 2017-05-15 06:55:14 +01:00
Achilleas Anagnostopoulos
be529349bb Merge pull request #10 from achilleasa/improve-tty-and-fix-fmt-bugs
Improve tty and fix fmt bugs
2017-05-12 08:16:33 +01:00
Achilleas Anagnostopoulos
6d3c463ee8 Prevent early_fmt code from triggering Go's allocator
When converting strings to []byte so that they can be used with the tty
io.Writer interface Go calls a runtime method called
"stringtoslicebyte". If the input length exceeds a particular size then
this method will allocate a new []byte and copy the data into it. This
obviously causes our kernel to crash.

To fix this, all early_fmt functions have been changed to iterate any
string arguments and output them to the active TTY one byte at a time.
2017-05-12 08:00:18 +01:00
Achilleas Anagnostopoulos
d7028cee00 Make TTYs implement io.ByteWriter and add support for TAB/BS chars 2017-05-12 07:54:42 +01:00
Achilleas Anagnostopoulos
0154c132ea Merge pull request #9 from achilleasa/enter-longmode-and-setup-paging
Switch to a 64-bit version of the kernel and rt0 code
2017-05-03 21:39:48 +01:00
Achilleas Anagnostopoulos
2558f79fbf Switch to a 64-bit version of the kernel and rt0 code
The switch to 64-bit mode allows us to use 48-bit addressing and to
relocate the kernel to virtual address 0xffff800000000000 + 1M. The
actual kernel is loaded by the bootloader at physical address 1M.

The rt0 code has been split in two parts. The 32-bit part provides the
entrypoint that the bootloader jumps to after loading the kernel. Its
purpose is to make sure that:
- the kernel was booted by a multiboot-compliant bootloader
- the multiboot info structures are copied to a reserved memory block
  where they can be accessed after enabling paging
- the CPU meets the minimum requirements for the kernel (CPUID, SSE,
  support for long-mode)

Since paging is not enabled when the 32-bit code runs, it needs to
translate all memory addresses it accesses to physical memory addresses
by subtracting PAGE_OFFSET. The 32-bit rt0 code will set up a page table
that identity-maps region: 0 to 8M and region: PAGE_OFFSET to
PAGE_OFFSET+8M. This ensures that when paging gets enabled, we will still
be able to access the kernel using both physical and virtual memory
addresses. After enabling paging, the 32-bit rt0 will jump to a small
64-bit trampoline function that updates the stack pointer to use the
proper virtual address and jumps to the virtual address of the 64-bit
entry point.

The 64-bit entrypoint sets up the minimal g0 structure required by the
go function prologue for stack checks and sets up the FS register to
point to it. The principle is the same as with 32-bit code (a segment
register has the address of a pointer to the active g) with the
difference that in 64-bit mode, the FS register is used instead of GS
and that in order to set its value we need to write to a MSR.
2017-05-03 21:37:53 +01:00
Achilleas Anagnostopoulos
4829115647 Merge pull request #8 from achilleasa/enable-sse-support
Enable SSE support
2017-04-24 08:44:41 +01:00
Achilleas Anagnostopoulos
4b25afd2f5 Request valid EGA console from bootloader 2017-04-24 08:44:33 +01:00
Achilleas Anagnostopoulos
2b77a9270f Enable SSE support
The go compiler uses SSE instructions to optimize some of the generated code. We need to explicitly enable SSE support by manipulating the appropriate CR flags; otherwise the kernel will triple-fault
2017-04-24 08:42:15 +01:00
Achilleas Anagnostopoulos
5db83cd3c6 Merge pull request #6 from achilleasa/implement-early-printf
Implement early printf functionality
2017-04-05 08:39:25 +01:00
Achilleas Anagnostopoulos
b6ad5c933d Implement early printf functionality
The kfmt/early package provides a minimal printf implementation that
does not use memory allocations (everything is allocated on the stack).
This implementation can be used to emit debug messages before the memory
manager is initialized.
2017-04-05 08:35:32 +01:00
Achilleas Anagnostopoulos
d69c945019 Ensure the we pass the correct symbol address to objcopy
If kernel.Kmain defines a nested function then a symbol like `github.com/achilleasa/gopher-os/kernel.Kmain.func1` will be generated. To make sure we always pick the `github.com/achilleasa/gopher-os/kernel.Kmain` symbol address we just need to add a `$` to the grep argument.
2017-04-01 07:09:49 +01:00
Achilleas Anagnostopoulos
46353b198d Merge pull request #5 from achilleasa/wrap-multiboot-under-a-hal
Begin work on a hardware abstraction layer package
2017-04-01 07:06:07 +01:00
Achilleas Anagnostopoulos
66eedf1200 Initialize a minimal terminal attached to a text console device 2017-03-31 08:48:07 +01:00
Achilleas Anagnostopoulos
50da8ab106 Remove all locking code
Since the Go runtime is not yet setup there is no support for
spinlocking if a lock cannot be acquired. This makes the locking code
useless for now.
2017-03-31 08:48:02 +01:00
Achilleas Anagnostopoulos
7dac10a23b Rename Vga console driver to Ega and improve Init() signature 2017-03-30 07:44:09 +01:00
Achilleas Anagnostopoulos
80f7980e74 Move multiboot package under the hal package 2017-03-30 07:34:00 +01:00
Achilleas Anagnostopoulos
04c3987219 Merge pull request #4 from achilleasa/parse-multiboot-info
Add support for parsing multiboot info sections
2017-03-29 08:02:08 +01:00
Achilleas Anagnostopoulos
6dd00b5934 Create a global symbol alias for kernel.Kmain
The go compiler exposes a fully qualified symbol for kernel.Kmain that
also includes the full package name (github.com/.../kernel.Kmain). Since nasm
cannot work with external symbols that include slashes we use objcopy to
create an alias symbol "kernel.Kmain" that points to the symbol
generated by the go compiler.

To use the "--add-symbol" argument we need to use objcopy 2.6+. The
makefile was modified to include an additional pre-compile check for the
installed objcopy version.
2017-03-29 07:54:23 +01:00
Achilleas Anagnostopoulos
c15f27235c Update rt0 code to check for multiboot support and call kernel.Kmain
We still keep the required main func in stub.go to prevent the compiler
from optimizing the code out. We also force the compiler not to inline
the call to kernel.Kmain so we can find the symbol in the generated .o
file.
2017-03-29 07:54:23 +01:00
Achilleas Anagnostopoulos
244c8af752 Provide method for querying framebuffer info 2017-03-29 07:54:23 +01:00
Achilleas Anagnostopoulos
558cbf5f17 Implement visitor for examining reported memory map entries
Since the actual size of each memory entry is not known in advance
(bootloaders may append additional information to it) but needs to be
queried off the memory map tag header we cannot reserve space for it as
no memory allocation is yet available.

Instead, a visitor pattern was implemented to allow the memory
manager initialization block to easily mark the appropriate pages as reserved
2017-03-29 07:54:23 +01:00
Achilleas Anagnostopoulos
d4c0d52372 Implement multiboot info structure tag scanner 2017-03-29 07:54:23 +01:00
Achilleas Anagnostopoulos
8770634fd2 Switch to xenial vagrant box for updated binutils
We need binutils 2.26+ so objcopy supports the "--add-symbol" option
2017-03-29 07:42:38 +01:00
Achilleas Anagnostopoulos
08142d90f6 Merge pull request #3 from achilleasa/implement-simple-terminal
Implement simple terminal
2017-03-27 21:20:28 +01:00
Achilleas Anagnostopoulos
616fc6a412 Implement simple terminal
The terminal uses console.Vga as its output device. A proper terminal
implementation would be using a console.Console interface as its output.
However, at this point we cannot use Go interfaces as the fn pointers in
the itables have not been yet initialized. The Go runtime bits that set
up the itables need access to a memory allocator, a facility which is
not yet provided by the kernel.
2017-03-27 20:12:01 +01:00
Achilleas Anagnostopoulos
95ce4c6057 Define TTY interface 2017-03-26 21:42:27 +01:00
Achilleas Anagnostopoulos
138bc244f9 Add mutex to Vga console to satisfy console.Console 2017-03-26 21:41:53 +01:00
Achilleas Anagnostopoulos
985bc92bf7 Fix typo 2017-03-26 09:51:38 +01:00
Achilleas Anagnostopoulos
38e5afbc76 Merge pull request #2 from achilleasa/setup-ci
Setup CI and coverage tools
2017-03-26 09:50:53 +01:00
Achilleas Anagnostopoulos
cc1f2e6016 Setup CI and coverage tools 2017-03-26 09:48:12 +01:00
Achilleas Anagnostopoulos
8c41bf6404 Merge pull request #1 from achilleasa/implement-text-console
Implement VGA text console driver
2017-03-26 09:42:45 +01:00
Achilleas Anagnostopoulos
f72eacc4fb Define VGA console
The VGA console frame buffer is mapped to the physical address 0xB8000.
2017-03-26 09:37:54 +01:00
Achilleas Anagnostopoulos
b513f2f332 Define console interface 2017-03-26 09:33:17 +01:00
Achilleas Anagnostopoulos
590d4f1363 Set -o pipefail to catch go compilation errors 2017-03-23 08:51:32 +00:00
Achilleas Anagnostopoulos
95569d2982 Implement Makefile for building, running and debugging the kernel
The makefile provides the following targets:
- kernel
- iso
- run
- gdb

It sniffs the OS type and when running on non-linux hosts it uses
vagrant ssh and runs make with the above targets inside the vagrant box.

The kernel build process consists of the following steps:
1) Compile arch-specific (only x86 for now) assembly files.
2) Run go build -n to obtain the build commands for our kernel. The
makefile sets the build target to 386/linux so that our current rt0
implementation does not need to switch to long-mode.
3) The build commands are then patched to:
  - use build/ as the output directory
  - force the go linker to use external link mode and to place its output files
  (--tmpdir) to the build folder. By forcing external link mode, the go
  linker will emit a single go.o file which can be used by ld.
4) We run our own link step and use ld to link the rt0 .o files with the
go.o file and provide a custom linker script to ensure that our
multiboot record is located at the top of the kernel image so that grub
can find it.

The ISO build process sets up a minimal folder structure for building a
bootable ISO (basically the kernel image plus a grub configuration) and
runs grub-mkrescue to produce the ISO file.

Both the run and the gdb targets assume that qemu is installed. The gdb
target starts qemu, attaches the debugger and sets a breakpoint to the
rt0 entrypoint.
2017-03-23 07:24:49 +00:00
Achilleas Anagnostopoulos
865f46c467 Define kernel entry-points in Go 2017-03-23 07:10:01 +00:00
Achilleas Anagnostopoulos
5b47048397 Implement rt0 assembly boot code for x86 arch 2017-03-23 06:50:41 +00:00
Achilleas Anagnostopoulos
1a094f511e Define Vagrantfile for building gopher-os on non-linux hosts 2017-03-23 06:50:38 +00:00
Achilleas Anagnostopoulos
3a1a8b4185 Update .gitignore 2017-03-23 06:50:13 +00:00
Achilleas Anagnostopoulos
1630e9562c Initial commit 2017-03-23 06:50:13 +00:00