1
0
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:
Achilleas Anagnostopoulos 2017-07-10 06:30:58 +01:00
parent 5ef344010b
commit af9613e336
2 changed files with 62 additions and 3 deletions

View File

@ -1,6 +1,10 @@
package multiboot
import "unsafe"
import (
"reflect"
"strings"
"unsafe"
)
type tagType uint32
@ -138,6 +142,7 @@ const (
var (
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.

View File

@ -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,