mirror of
https://github.com/taigrr/gopher-os
synced 2025-01-18 04:43:13 -08:00
Support extraction of boot cmdline off the multiboot data
This commit is contained in:
parent
5ef344010b
commit
af9613e336
@ -1,6 +1,10 @@
|
||||
package multiboot
|
||||
|
||||
import "unsafe"
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type tagType uint32
|
||||
|
||||
@ -137,7 +141,8 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
infoData uintptr
|
||||
infoData uintptr
|
||||
cmdLineKV map[string]string
|
||||
)
|
||||
|
||||
// MemRegionVisitor defies a visitor function that gets invoked by VisitMemRegions
|
||||
@ -224,6 +229,39 @@ func GetFramebufferInfo() *FramebufferInfo {
|
||||
return info
|
||||
}
|
||||
|
||||
// GetBootCmdLine returns the command line key-value pairs passed to the
|
||||
// kernel. This function must only be invoked after bootstrapping the memory
|
||||
// allocator.
|
||||
func GetBootCmdLine() map[string]string {
|
||||
if cmdLineKV != nil {
|
||||
return cmdLineKV
|
||||
}
|
||||
|
||||
cmdLineKV = make(map[string]string)
|
||||
|
||||
curPtr, size := findTagByType(tagBootCmdLine)
|
||||
if size != 0 {
|
||||
// The command line is a C-style NULL-terminated string
|
||||
cmdLine := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
|
||||
Len: int(size - 1),
|
||||
Cap: int(size - 1),
|
||||
Data: curPtr,
|
||||
}))
|
||||
pairs := strings.Fields(string(cmdLine))
|
||||
for _, pair := range pairs {
|
||||
kv := strings.Split(pair, "=")
|
||||
switch len(kv) {
|
||||
case 2: // foo=bar
|
||||
cmdLineKV[kv[0]] = kv[1]
|
||||
case 1: // nofoo
|
||||
cmdLineKV[kv[0]] = kv[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cmdLineKV
|
||||
}
|
||||
|
||||
// findTagByType scans the multiboot info data looking for the start of of the
|
||||
// specified type. It returns a pointer to the tag contents start offset and
|
||||
// the content length exluding the tag header.
|
||||
|
@ -1,6 +1,7 @@
|
||||
package multiboot
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
"unsafe"
|
||||
)
|
||||
@ -170,6 +171,26 @@ func TestGetFramebufferInfo(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetBootCmdLine(t *testing.T) {
|
||||
SetInfoPtr(uintptr(unsafe.Pointer(&multibootInfoTestData[0])))
|
||||
|
||||
expKV := map[string]string{
|
||||
"param1": "param1", // "param1" (no value)
|
||||
"param2": "value2", // "param2=value2"
|
||||
}
|
||||
|
||||
kv := GetBootCmdLine()
|
||||
if !reflect.DeepEqual(kv, expKV) {
|
||||
t.Errorf("expected to get: %v; got %v", expKV, kv)
|
||||
}
|
||||
|
||||
// Second call should return the memoized data
|
||||
cmdLineKV["foo"] = "bar"
|
||||
if kv2 := GetBootCmdLine(); !reflect.DeepEqual(kv2, kv) {
|
||||
t.Error("expected second call to GetBootCmdLine() to return the memoized KV pairs")
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
emptyInfoData = []byte{
|
||||
0, 0, 0, 0, // size
|
||||
@ -181,7 +202,7 @@ var (
|
||||
// A dump of multiboot data when running under qemu.
|
||||
multibootInfoTestData = []byte{
|
||||
0xb8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
|
||||
0x70, 0x61, 0x72, 0x61, 0x6d, 0x31, 0x3d, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x20, 0x70, 0x61,
|
||||
0x70, 0x61, 0x72, 0x61, 0x6d, 0x31, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61,
|
||||
0x72, 0x61, 0x6d, 0x32, 0x3d, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x47, 0x52, 0x55, 0x42, 0x20, 0x32, 0x2e, 0x30,
|
||||
0x32, 0x7e, 0x62, 0x65, 0x74, 0x61, 0x32, 0x2d, 0x33, 0x36, 0x75, 0x62, 0x75, 0x6e, 0x74, 0x75,
|
||||
|
Loading…
x
Reference in New Issue
Block a user