mirror of
https://github.com/taigrr/gopher-os
synced 2025-01-18 04:43:13 -08:00
Merge pull request #5 from achilleasa/wrap-multiboot-under-a-hal
Begin work on a hardware abstraction layer package
This commit is contained in:
commit
46353b198d
@ -12,7 +12,7 @@ const (
|
|||||||
type Vt struct {
|
type Vt struct {
|
||||||
// Go interfaces will not work before we can get memory allocation working.
|
// Go interfaces will not work before we can get memory allocation working.
|
||||||
// Till then we need to use concrete types instead.
|
// Till then we need to use concrete types instead.
|
||||||
cons *console.Vga
|
cons *console.Ega
|
||||||
|
|
||||||
width uint16
|
width uint16
|
||||||
height uint16
|
height uint16
|
||||||
@ -22,7 +22,9 @@ type Vt struct {
|
|||||||
curAttr console.Attr
|
curAttr console.Attr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Vt) Init(cons *console.Vga) {
|
// AttachTo links the terminal with the specified console device and updates
|
||||||
|
// the terminal's dimensions to match the ones reported by the attached device.
|
||||||
|
func (t *Vt) AttachTo(cons *console.Ega) {
|
||||||
t.cons = cons
|
t.cons = cons
|
||||||
t.width, t.height = cons.Dimensions()
|
t.width, t.height = cons.Dimensions()
|
||||||
t.curX = 0
|
t.curX = 0
|
||||||
@ -30,30 +32,20 @@ func (t *Vt) Init(cons *console.Vga) {
|
|||||||
|
|
||||||
// Default to lightgrey on black text.
|
// Default to lightgrey on black text.
|
||||||
t.curAttr = makeAttr(defaultFg, defaultBg)
|
t.curAttr = makeAttr(defaultFg, defaultBg)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear clears the terminal.
|
// Clear clears the terminal.
|
||||||
func (t *Vt) Clear() {
|
func (t *Vt) Clear() {
|
||||||
t.cons.Lock()
|
|
||||||
defer t.cons.Unlock()
|
|
||||||
|
|
||||||
t.clear()
|
t.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Position returns the current cursor position (x, y).
|
// Position returns the current cursor position (x, y).
|
||||||
func (t *Vt) Position() (uint16, uint16) {
|
func (t *Vt) Position() (uint16, uint16) {
|
||||||
t.cons.Lock()
|
|
||||||
defer t.cons.Unlock()
|
|
||||||
|
|
||||||
return t.curX, t.curY
|
return t.curX, t.curY
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetPosition sets the current cursor position to (x,y).
|
// SetPosition sets the current cursor position to (x,y).
|
||||||
func (t *Vt) SetPosition(x, y uint16) {
|
func (t *Vt) SetPosition(x, y uint16) {
|
||||||
t.cons.Lock()
|
|
||||||
defer t.cons.Unlock()
|
|
||||||
|
|
||||||
if x >= t.width {
|
if x >= t.width {
|
||||||
x = t.width - 1
|
x = t.width - 1
|
||||||
}
|
}
|
||||||
@ -67,9 +59,6 @@ func (t *Vt) SetPosition(x, y uint16) {
|
|||||||
|
|
||||||
// Write implements io.Writer.
|
// Write implements io.Writer.
|
||||||
func (t *Vt) Write(data []byte) (int, error) {
|
func (t *Vt) Write(data []byte) (int, error) {
|
||||||
t.cons.Lock()
|
|
||||||
defer t.cons.Unlock()
|
|
||||||
|
|
||||||
attr := t.curAttr
|
attr := t.curAttr
|
||||||
for _, b := range data {
|
for _, b := range data {
|
||||||
switch b {
|
switch b {
|
||||||
|
@ -2,6 +2,7 @@ package tty
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"github.com/achilleasa/gopher-os/kernel/driver/video/console"
|
"github.com/achilleasa/gopher-os/kernel/driver/video/console"
|
||||||
)
|
)
|
||||||
@ -18,11 +19,12 @@ func TestVtPosition(t *testing.T) {
|
|||||||
{100, 100, 79, 24},
|
{100, 100, 79, 24},
|
||||||
}
|
}
|
||||||
|
|
||||||
var cons console.Vga
|
fb := make([]uint16, 80*25)
|
||||||
cons.Init()
|
var cons console.Ega
|
||||||
|
cons.Init(80, 25, uintptr(unsafe.Pointer(&fb[0])))
|
||||||
|
|
||||||
var vt Vt
|
var vt Vt
|
||||||
vt.Init(&cons)
|
vt.AttachTo(&cons)
|
||||||
|
|
||||||
for specIndex, spec := range specs {
|
for specIndex, spec := range specs {
|
||||||
vt.SetPosition(spec.inX, spec.inY)
|
vt.SetPosition(spec.inX, spec.inY)
|
||||||
@ -34,12 +36,11 @@ func TestVtPosition(t *testing.T) {
|
|||||||
|
|
||||||
func TestWrite(t *testing.T) {
|
func TestWrite(t *testing.T) {
|
||||||
fb := make([]uint16, 80*25)
|
fb := make([]uint16, 80*25)
|
||||||
cons := &console.Vga{}
|
var cons console.Ega
|
||||||
cons.OverrideFb(fb)
|
cons.Init(80, 25, uintptr(unsafe.Pointer(&fb[0])))
|
||||||
cons.Init()
|
|
||||||
|
|
||||||
var vt Vt
|
var vt Vt
|
||||||
vt.Init(cons)
|
vt.AttachTo(&cons)
|
||||||
|
|
||||||
vt.Clear()
|
vt.Clear()
|
||||||
vt.SetPosition(0, 1)
|
vt.SetPosition(0, 1)
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package console
|
package console
|
||||||
|
|
||||||
import "sync"
|
|
||||||
|
|
||||||
// Attr defines a color attribute.
|
// Attr defines a color attribute.
|
||||||
type Attr uint16
|
type Attr uint16
|
||||||
|
|
||||||
@ -36,8 +34,6 @@ const (
|
|||||||
|
|
||||||
// The Console interface is implemented by objects that can function as physical consoles.
|
// The Console interface is implemented by objects that can function as physical consoles.
|
||||||
type Console interface {
|
type Console interface {
|
||||||
sync.Locker
|
|
||||||
|
|
||||||
// Dimensions returns the width and height of the console in characters.
|
// Dimensions returns the width and height of the console in characters.
|
||||||
Dimensions() (uint16, uint16)
|
Dimensions() (uint16, uint16)
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ package console
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"sync"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -11,13 +10,11 @@ const (
|
|||||||
clearChar = byte(' ')
|
clearChar = byte(' ')
|
||||||
)
|
)
|
||||||
|
|
||||||
// Vga implements an EGA-compatible text console. At the moment, it uses the
|
// Ega implements an EGA-compatible text console. At the moment, it uses the
|
||||||
// ega console physical address as its outpucons. After implementing a memory
|
// ega console physical address as its outpucons. After implementing a memory
|
||||||
// allocator, each console will use its own framebuffer while the active console
|
// allocator, each console will use its own framebuffer while the active console
|
||||||
// will periodically sync its internal buffer with the physical screen buffer.
|
// will periodically sync its internal buffer with the physical screen buffer.
|
||||||
type Vga struct {
|
type Ega struct {
|
||||||
sync.Mutex
|
|
||||||
|
|
||||||
width uint16
|
width uint16
|
||||||
height uint16
|
height uint16
|
||||||
|
|
||||||
@ -25,32 +22,19 @@ type Vga struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Init sets up the console.
|
// Init sets up the console.
|
||||||
func (cons *Vga) Init() {
|
func (cons *Ega) Init(width, height uint16, fbPhysAddr uintptr) {
|
||||||
cons.width = 80
|
cons.width = width
|
||||||
cons.height = 25
|
cons.height = height
|
||||||
|
|
||||||
// Set up our frame buffer object by creating a fake slice object pointing
|
|
||||||
// to the physical address of the screen buffer.
|
|
||||||
if cons.fb != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
cons.fb = *(*[]uint16)(unsafe.Pointer(&reflect.SliceHeader{
|
cons.fb = *(*[]uint16)(unsafe.Pointer(&reflect.SliceHeader{
|
||||||
Len: int(cons.width * cons.height),
|
Len: int(cons.width * cons.height),
|
||||||
Cap: int(cons.width * cons.height),
|
Cap: int(cons.width * cons.height),
|
||||||
Data: uintptr(0xB8000),
|
Data: fbPhysAddr,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// OverrideFb overrides the console framebuffer slice with the supplied slice.
|
|
||||||
// This is a temporary function used by tests that will be removed once we can work
|
|
||||||
// with interfaces.
|
|
||||||
func (cons *Vga) OverrideFb(fb []uint16) {
|
|
||||||
cons.fb = fb
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear clears the specified rectangular region
|
// Clear clears the specified rectangular region
|
||||||
func (cons *Vga) Clear(x, y, width, height uint16) {
|
func (cons *Ega) Clear(x, y, width, height uint16) {
|
||||||
var (
|
var (
|
||||||
attr = uint16((clearColor << 4) | clearColor)
|
attr = uint16((clearColor << 4) | clearColor)
|
||||||
clr = attr | uint16(clearChar)
|
clr = attr | uint16(clearChar)
|
||||||
@ -81,12 +65,12 @@ func (cons *Vga) Clear(x, y, width, height uint16) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dimensions returns the console width and height in characters.
|
// Dimensions returns the console width and height in characters.
|
||||||
func (cons *Vga) Dimensions() (uint16, uint16) {
|
func (cons *Ega) Dimensions() (uint16, uint16) {
|
||||||
return cons.width, cons.height
|
return cons.width, cons.height
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scroll a particular number of lines to the specified direction.
|
// Scroll a particular number of lines to the specified direction.
|
||||||
func (cons *Vga) Scroll(dir ScrollDir, lines uint16) {
|
func (cons *Ega) Scroll(dir ScrollDir, lines uint16) {
|
||||||
if lines == 0 || lines > cons.height {
|
if lines == 0 || lines > cons.height {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -107,7 +91,7 @@ func (cons *Vga) Scroll(dir ScrollDir, lines uint16) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Write a char to the specified location.
|
// Write a char to the specified location.
|
||||||
func (cons *Vga) Write(ch byte, attr Attr, x, y uint16) {
|
func (cons *Ega) Write(ch byte, attr Attr, x, y uint16) {
|
||||||
if x >= cons.width || y >= cons.height {
|
if x >= cons.width || y >= cons.height {
|
||||||
return
|
return
|
||||||
}
|
}
|
@ -1,10 +1,13 @@
|
|||||||
package console
|
package console
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"testing"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
func TestVgaInit(t *testing.T) {
|
func TestEgaInit(t *testing.T) {
|
||||||
var cons Vga
|
var cons Ega
|
||||||
cons.Init()
|
cons.Init(80, 25, 0xB8000)
|
||||||
|
|
||||||
var expWidth uint16 = 80
|
var expWidth uint16 = 80
|
||||||
var expHeight uint16 = 25
|
var expHeight uint16 = 25
|
||||||
@ -14,7 +17,7 @@ func TestVgaInit(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVgaClear(t *testing.T) {
|
func TestEgaClear(t *testing.T) {
|
||||||
specs := []struct {
|
specs := []struct {
|
||||||
// Input rect
|
// Input rect
|
||||||
x, y, w, h uint16
|
x, y, w, h uint16
|
||||||
@ -48,8 +51,9 @@ func TestVgaClear(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var cons = Vga{fb: make([]uint16, 80*25)}
|
fb := make([]uint16, 80*25)
|
||||||
cons.Init()
|
var cons Ega
|
||||||
|
cons.Init(80, 25, uintptr(unsafe.Pointer(&fb[0])))
|
||||||
|
|
||||||
testPat := uint16(0xDEAD)
|
testPat := uint16(0xDEAD)
|
||||||
clearPat := (uint16(clearColor) << 8) | uint16(clearChar)
|
clearPat := (uint16(clearColor) << 8) | uint16(clearChar)
|
||||||
@ -58,7 +62,7 @@ nextSpec:
|
|||||||
for specIndex, spec := range specs {
|
for specIndex, spec := range specs {
|
||||||
// Fill FB with test pattern
|
// Fill FB with test pattern
|
||||||
for i := 0; i < len(cons.fb); i++ {
|
for i := 0; i < len(cons.fb); i++ {
|
||||||
cons.fb[i] = testPat
|
fb[i] = testPat
|
||||||
}
|
}
|
||||||
|
|
||||||
cons.Clear(spec.x, spec.y, spec.w, spec.h)
|
cons.Clear(spec.x, spec.y, spec.w, spec.h)
|
||||||
@ -66,7 +70,7 @@ nextSpec:
|
|||||||
var x, y uint16
|
var x, y uint16
|
||||||
for y = 0; y < cons.height; y++ {
|
for y = 0; y < cons.height; y++ {
|
||||||
for x = 0; x < cons.width; x++ {
|
for x = 0; x < cons.width; x++ {
|
||||||
fbVal := cons.fb[(y*cons.width)+x]
|
fbVal := fb[(y*cons.width)+x]
|
||||||
|
|
||||||
if x < spec.expX || y < spec.expY || x >= spec.expX+spec.expW || y >= spec.expY+spec.expH {
|
if x < spec.expX || y < spec.expY || x >= spec.expX+spec.expW || y >= spec.expY+spec.expH {
|
||||||
if fbVal != testPat {
|
if fbVal != testPat {
|
||||||
@ -84,15 +88,16 @@ nextSpec:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVgaScrollUp(t *testing.T) {
|
func TestEgaScrollUp(t *testing.T) {
|
||||||
specs := []uint16{
|
specs := []uint16{
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
2,
|
2,
|
||||||
}
|
}
|
||||||
|
|
||||||
var cons = Vga{fb: make([]uint16, 80*25)}
|
fb := make([]uint16, 80*25)
|
||||||
cons.Init()
|
var cons Ega
|
||||||
|
cons.Init(80, 25, uintptr(unsafe.Pointer(&fb[0])))
|
||||||
|
|
||||||
nextSpec:
|
nextSpec:
|
||||||
for specIndex, lines := range specs {
|
for specIndex, lines := range specs {
|
||||||
@ -100,7 +105,7 @@ nextSpec:
|
|||||||
var x, y, index uint16
|
var x, y, index uint16
|
||||||
for y = 0; y < cons.height; y++ {
|
for y = 0; y < cons.height; y++ {
|
||||||
for x = 0; x < cons.width; x++ {
|
for x = 0; x < cons.width; x++ {
|
||||||
cons.fb[index] = (y << 8) | x
|
fb[index] = (y << 8) | x
|
||||||
index++
|
index++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -112,7 +117,7 @@ nextSpec:
|
|||||||
for y = 0; y < cons.height-lines; y++ {
|
for y = 0; y < cons.height-lines; y++ {
|
||||||
for x = 0; x < cons.width; x++ {
|
for x = 0; x < cons.width; x++ {
|
||||||
expVal := ((y + lines) << 8) | x
|
expVal := ((y + lines) << 8) | x
|
||||||
if cons.fb[index] != expVal {
|
if fb[index] != expVal {
|
||||||
t.Errorf("[spec %d] expected value at (%d, %d) to be %d; got %d", specIndex, x, y, expVal, cons.fb[index])
|
t.Errorf("[spec %d] expected value at (%d, %d) to be %d; got %d", specIndex, x, y, expVal, cons.fb[index])
|
||||||
continue nextSpec
|
continue nextSpec
|
||||||
}
|
}
|
||||||
@ -122,15 +127,16 @@ nextSpec:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVgaScrollDown(t *testing.T) {
|
func TestEgaScrollDown(t *testing.T) {
|
||||||
specs := []uint16{
|
specs := []uint16{
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
2,
|
2,
|
||||||
}
|
}
|
||||||
|
|
||||||
var cons = Vga{fb: make([]uint16, 80*25)}
|
fb := make([]uint16, 80*25)
|
||||||
cons.Init()
|
var cons Ega
|
||||||
|
cons.Init(80, 25, uintptr(unsafe.Pointer(&fb[0])))
|
||||||
|
|
||||||
nextSpec:
|
nextSpec:
|
||||||
for specIndex, lines := range specs {
|
for specIndex, lines := range specs {
|
||||||
@ -138,7 +144,7 @@ nextSpec:
|
|||||||
var x, y, index uint16
|
var x, y, index uint16
|
||||||
for y = 0; y < cons.height; y++ {
|
for y = 0; y < cons.height; y++ {
|
||||||
for x = 0; x < cons.width; x++ {
|
for x = 0; x < cons.width; x++ {
|
||||||
cons.fb[index] = (y << 8) | x
|
fb[index] = (y << 8) | x
|
||||||
index++
|
index++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -150,7 +156,7 @@ nextSpec:
|
|||||||
for y = lines; y < cons.height-lines; y++ {
|
for y = lines; y < cons.height-lines; y++ {
|
||||||
for x = 0; x < cons.width; x++ {
|
for x = 0; x < cons.width; x++ {
|
||||||
expVal := ((y - lines) << 8) | x
|
expVal := ((y - lines) << 8) | x
|
||||||
if cons.fb[index] != expVal {
|
if fb[index] != expVal {
|
||||||
t.Errorf("[spec %d] expected value at (%d, %d) to be %d; got %d", specIndex, x, y, expVal, cons.fb[index])
|
t.Errorf("[spec %d] expected value at (%d, %d) to be %d; got %d", specIndex, x, y, expVal, cons.fb[index])
|
||||||
continue nextSpec
|
continue nextSpec
|
||||||
}
|
}
|
||||||
@ -160,9 +166,10 @@ nextSpec:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVgaWriteWithOffScreenCoords(t *testing.T) {
|
func TestEgaWriteWithOffScreenCoords(t *testing.T) {
|
||||||
var cons = Vga{fb: make([]uint16, 80*25)}
|
fb := make([]uint16, 80*25)
|
||||||
cons.Init()
|
var cons Ega
|
||||||
|
cons.Init(80, 25, uintptr(unsafe.Pointer(&fb[0])))
|
||||||
|
|
||||||
specs := []struct {
|
specs := []struct {
|
||||||
x, y uint16
|
x, y uint16
|
||||||
@ -176,13 +183,13 @@ func TestVgaWriteWithOffScreenCoords(t *testing.T) {
|
|||||||
nextSpec:
|
nextSpec:
|
||||||
for specIndex, spec := range specs {
|
for specIndex, spec := range specs {
|
||||||
for i := 0; i < len(cons.fb); i++ {
|
for i := 0; i < len(cons.fb); i++ {
|
||||||
cons.fb[i] = 0
|
fb[i] = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
cons.Write('!', Red, spec.x, spec.y)
|
cons.Write('!', Red, spec.x, spec.y)
|
||||||
|
|
||||||
for i := 0; i < len(cons.fb); i++ {
|
for i := 0; i < len(cons.fb); i++ {
|
||||||
if got := cons.fb[i]; got != 0 {
|
if got := fb[i]; got != 0 {
|
||||||
t.Errorf("[spec %d] expected Write() with off-screen coords to be a no-op", specIndex)
|
t.Errorf("[spec %d] expected Write() with off-screen coords to be a no-op", specIndex)
|
||||||
continue nextSpec
|
continue nextSpec
|
||||||
}
|
}
|
||||||
@ -190,27 +197,16 @@ nextSpec:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVgaWrite(t *testing.T) {
|
func TestEgaWrite(t *testing.T) {
|
||||||
var cons = Vga{fb: make([]uint16, 80*25)}
|
fb := make([]uint16, 80*25)
|
||||||
cons.Init()
|
var cons Ega
|
||||||
|
cons.Init(80, 25, uintptr(unsafe.Pointer(&fb[0])))
|
||||||
|
|
||||||
attr := (Black << 4) | Red
|
attr := (Black << 4) | Red
|
||||||
cons.Write('!', attr, 0, 0)
|
cons.Write('!', attr, 0, 0)
|
||||||
|
|
||||||
expVal := uint16(attr<<8) | uint16('!')
|
expVal := uint16(attr<<8) | uint16('!')
|
||||||
if got := cons.fb[0]; got != expVal {
|
if got := fb[0]; got != expVal {
|
||||||
t.Errorf("expected call to Write() to set fb[0] to %d; got %d", expVal, got)
|
t.Errorf("expected call to Write() to set fb[0] to %d; got %d", expVal, got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVgaOverrideFb(t *testing.T) {
|
|
||||||
var cons = Vga{}
|
|
||||||
cons.Init()
|
|
||||||
|
|
||||||
fb := []uint16{}
|
|
||||||
cons.OverrideFb(fb)
|
|
||||||
|
|
||||||
if len(cons.fb) != len(fb) {
|
|
||||||
t.Fatalf("expected calling OverrideFb to change the framebuffer for the console")
|
|
||||||
}
|
|
||||||
}
|
|
21
kernel/hal/hal.go
Normal file
21
kernel/hal/hal.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package hal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/achilleasa/gopher-os/kernel/driver/tty"
|
||||||
|
"github.com/achilleasa/gopher-os/kernel/driver/video/console"
|
||||||
|
"github.com/achilleasa/gopher-os/kernel/hal/multiboot"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
egaConsole = &console.Ega{}
|
||||||
|
ActiveTerminal = &tty.Vt{}
|
||||||
|
)
|
||||||
|
|
||||||
|
// InitTerminal provides a basic terminal to allow the kernel to emit some output
|
||||||
|
// till everything is properly setup
|
||||||
|
func InitTerminal() {
|
||||||
|
fbInfo := multiboot.GetFramebufferInfo()
|
||||||
|
|
||||||
|
egaConsole.Init(uint16(fbInfo.Width), uint16(fbInfo.Height), uintptr(fbInfo.PhysAddr))
|
||||||
|
ActiveTerminal.AttachTo(egaConsole)
|
||||||
|
}
|
@ -3,7 +3,8 @@ package kernel
|
|||||||
import (
|
import (
|
||||||
_ "unsafe" // required for go:linkname
|
_ "unsafe" // required for go:linkname
|
||||||
|
|
||||||
"github.com/achilleasa/gopher-os/kernel/multiboot"
|
"github.com/achilleasa/gopher-os/kernel/hal"
|
||||||
|
"github.com/achilleasa/gopher-os/kernel/hal/multiboot"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Kmain is the only Go symbol that is visible (exported) from the rt0 initialization
|
// Kmain is the only Go symbol that is visible (exported) from the rt0 initialization
|
||||||
@ -19,4 +20,8 @@ import (
|
|||||||
//go:noinline
|
//go:noinline
|
||||||
func Kmain(multibootInfoPtr uint32) {
|
func Kmain(multibootInfoPtr uint32) {
|
||||||
multiboot.SetInfoPtr(uintptr(multibootInfoPtr))
|
multiboot.SetInfoPtr(uintptr(multibootInfoPtr))
|
||||||
|
|
||||||
|
// Initialize and clear the terminal
|
||||||
|
hal.InitTerminal()
|
||||||
|
hal.ActiveTerminal.Clear()
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user