mirror of
https://github.com/taigrr/gopher-os
synced 2025-01-18 04:43:13 -08:00
Implement multiboot info structure tag scanner
This commit is contained in:
parent
8770634fd2
commit
d4c0d52372
115
kernel/multiboot/multiboot.go
Normal file
115
kernel/multiboot/multiboot.go
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
package multiboot
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
type tagType uint32
|
||||||
|
|
||||||
|
const (
|
||||||
|
tagMbSectionEnd tagType = iota
|
||||||
|
tagBootCmdLine
|
||||||
|
tagBootLoaderName
|
||||||
|
tagModules
|
||||||
|
tagBasicMemoryInfo
|
||||||
|
tagBiosBootDevice
|
||||||
|
tagMemoryMap
|
||||||
|
tagVbeInfo
|
||||||
|
tagFramebufferInfo
|
||||||
|
tagElfSymbols
|
||||||
|
tagApmTable
|
||||||
|
)
|
||||||
|
|
||||||
|
// info describes the multiboot info section header.
|
||||||
|
type info struct {
|
||||||
|
// Total size of multiboot info section.
|
||||||
|
totalSize uint32
|
||||||
|
|
||||||
|
// Always set to zero; reserved for future use
|
||||||
|
reserved uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// tagHeader describes the header the preceedes each tag.
|
||||||
|
type tagHeader struct {
|
||||||
|
// The type of the tag
|
||||||
|
tagType tagType
|
||||||
|
|
||||||
|
// The size of the tag including the header but *not* including any
|
||||||
|
// padding. According to the spec, each tag starts at a 8-byte aligned
|
||||||
|
// address.
|
||||||
|
size uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// mmapHeader describes the header for a memory map specification.
|
||||||
|
type mmapHeader struct {
|
||||||
|
// The size of each entry.
|
||||||
|
entrySize uint32
|
||||||
|
|
||||||
|
// The version of the entries that follow.
|
||||||
|
entryVersion uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// MemoryEntryType defines the type of a MemoryMapEntry.
|
||||||
|
type MemoryEntryType uint32
|
||||||
|
|
||||||
|
const (
|
||||||
|
// MemAvailable indicates that the memory region is available for use.
|
||||||
|
MemAvailable MemoryEntryType = iota + 1
|
||||||
|
|
||||||
|
// MemReserved indicates that the memory region is not available for use.
|
||||||
|
MemReserved
|
||||||
|
|
||||||
|
// MemAcpiReclaimable indicates a memory region that holds ACPI info that
|
||||||
|
// can be reused by the OS.
|
||||||
|
MemAcpiReclaimable
|
||||||
|
|
||||||
|
// MemNvs indicates memory that must be preserved when hibernating.
|
||||||
|
MemNvs
|
||||||
|
|
||||||
|
// Any value >= memUnknown will be mapped to MemReserved.
|
||||||
|
memUnknown
|
||||||
|
)
|
||||||
|
|
||||||
|
/// MemoryMapEntry describes a memory region entry, namely its physical address,
|
||||||
|
// its length and its type.
|
||||||
|
type MemoryMapEntry struct {
|
||||||
|
// The physical address for this memory region.
|
||||||
|
PhysAddress uint64
|
||||||
|
|
||||||
|
// The length of the memory region.
|
||||||
|
Length uint64
|
||||||
|
|
||||||
|
// The type of this entry.
|
||||||
|
Type MemoryEntryType
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
infoData uintptr
|
||||||
|
)
|
||||||
|
|
||||||
|
// SetInfoPtr updates the internal multiboot information pointer to the given
|
||||||
|
// value. This function must be invoked before invoking any other function
|
||||||
|
// exported by this package.
|
||||||
|
func SetInfoPtr(ptr uintptr) {
|
||||||
|
infoData = ptr
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// If the tag is not present in the multiboot info, findTagSection will return
|
||||||
|
// back (0,0).
|
||||||
|
func findTagByType(tagType tagType) (uintptr, uint32) {
|
||||||
|
var ptrTagHeader *tagHeader
|
||||||
|
|
||||||
|
curPtr := infoData + 8
|
||||||
|
for ptrTagHeader = (*tagHeader)(unsafe.Pointer(curPtr)); ptrTagHeader.tagType != tagMbSectionEnd; ptrTagHeader = (*tagHeader)(unsafe.Pointer(curPtr)) {
|
||||||
|
if ptrTagHeader.tagType == tagType {
|
||||||
|
return curPtr + 8, ptrTagHeader.size - 8
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tags are aligned at 8-byte aligned addresses
|
||||||
|
curPtr += uintptr(int32(ptrTagHeader.size+7) & ^7)
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, 0
|
||||||
|
}
|
132
kernel/multiboot/multiboot_test.go
Normal file
132
kernel/multiboot/multiboot_test.go
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
package multiboot
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFindTagByType(t *testing.T) {
|
||||||
|
specs := []struct {
|
||||||
|
tagType tagType
|
||||||
|
expSize uint32
|
||||||
|
}{
|
||||||
|
{tagBootCmdLine, 1},
|
||||||
|
{tagBootLoaderName, 27},
|
||||||
|
{tagBasicMemoryInfo, 8},
|
||||||
|
{tagBiosBootDevice, 12},
|
||||||
|
{tagMemoryMap, 152},
|
||||||
|
{tagFramebufferInfo, 24},
|
||||||
|
{tagElfSymbols, 972},
|
||||||
|
{tagApmTable, 20},
|
||||||
|
}
|
||||||
|
|
||||||
|
SetInfoPtr(uintptr(unsafe.Pointer(&multibootInfoTestData[0])))
|
||||||
|
|
||||||
|
for specIndex, spec := range specs {
|
||||||
|
_, size := findTagByType(spec.tagType)
|
||||||
|
|
||||||
|
if size != spec.expSize {
|
||||||
|
t.Errorf("[spec %d] expected tag size for tag type %d to be %d; got %d", specIndex, spec.tagType, spec.expSize, size)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFindTagByTypeWithMissingTag(t *testing.T) {
|
||||||
|
SetInfoPtr(uintptr(unsafe.Pointer(&multibootInfoTestData[0])))
|
||||||
|
|
||||||
|
if offset, size := findTagByType(tagModules); offset != 0 || size != 0 {
|
||||||
|
t.Fatalf("expected findTagByType to return (0,0) for missing tag; got (%d, %d)", offset, size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
// A dump of multiboot data when running under qemu.
|
||||||
|
multibootInfoTestData = []byte{
|
||||||
|
72, 5, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 9, 0, 0, 0,
|
||||||
|
0, 171, 253, 7, 118, 119, 123, 0, 2, 0, 0, 0, 35, 0, 0, 0,
|
||||||
|
71, 82, 85, 66, 32, 50, 46, 48, 50, 126, 98, 101, 116, 97, 50, 45,
|
||||||
|
57, 117, 98, 117, 110, 116, 117, 49, 46, 54, 0, 0, 0, 0, 0, 0,
|
||||||
|
10, 0, 0, 0, 28, 0, 0, 0, 2, 1, 0, 240, 4, 213, 0, 0,
|
||||||
|
0, 240, 0, 240, 3, 0, 240, 255, 240, 255, 240, 255, 0, 0, 0, 0,
|
||||||
|
6, 0, 0, 0, 160, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 9, 0, 0, 0, 0, 0,
|
||||||
|
1, 0, 0, 0, 0, 0, 0, 0, 0, 252, 9, 0, 0, 0, 0, 0,
|
||||||
|
0, 4, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
|
||||||
|
2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 238, 7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 254, 7, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0,
|
||||||
|
2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 255, 0, 0, 0, 0,
|
||||||
|
0, 0, 4, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
9, 0, 0, 0, 212, 3, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0,
|
||||||
|
21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0,
|
||||||
|
1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 16, 0, 0, 16, 0, 0,
|
||||||
|
24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 38, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0,
|
||||||
|
0, 16, 16, 0, 0, 32, 0, 0, 135, 26, 4, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0,
|
||||||
|
1, 0, 0, 0, 2, 0, 0, 0, 0, 48, 20, 0, 0, 64, 4, 0,
|
||||||
|
194, 167, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0,
|
||||||
|
0, 0, 0, 0, 52, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0,
|
||||||
|
224, 215, 21, 0, 224, 231, 5, 0, 176, 6, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0,
|
||||||
|
1, 0, 0, 0, 2, 0, 0, 0, 144, 222, 21, 0, 144, 238, 5, 0,
|
||||||
|
4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 72, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0,
|
||||||
|
160, 222, 21, 0, 160, 238, 5, 0, 119, 23, 2, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0,
|
||||||
|
7, 0, 0, 0, 2, 0, 0, 0, 32, 246, 23, 0, 32, 6, 8, 0,
|
||||||
|
56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 100, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0,
|
||||||
|
0, 0, 24, 0, 0, 16, 8, 0, 204, 5, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 106, 0, 0, 0,
|
||||||
|
1, 0, 0, 0, 3, 0, 0, 0, 224, 5, 24, 0, 224, 21, 8, 0,
|
||||||
|
178, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 117, 0, 0, 0, 8, 0, 0, 0, 3, 4, 0, 0,
|
||||||
|
148, 15, 24, 0, 146, 31, 8, 0, 4, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 123, 0, 0, 0,
|
||||||
|
8, 0, 0, 0, 3, 0, 0, 0, 0, 16, 24, 0, 146, 31, 8, 0,
|
||||||
|
176, 61, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0,
|
||||||
|
0, 0, 0, 0, 128, 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 0,
|
||||||
|
192, 77, 25, 0, 146, 31, 8, 0, 32, 56, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 0,
|
||||||
|
1, 0, 0, 0, 0, 0, 0, 0, 224, 133, 25, 0, 146, 31, 8, 0,
|
||||||
|
64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 153, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
32, 134, 25, 0, 210, 31, 8, 0, 129, 26, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 169, 0, 0, 0,
|
||||||
|
1, 0, 0, 0, 0, 0, 0, 0, 161, 160, 25, 0, 83, 58, 8, 0,
|
||||||
|
2, 201, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 181, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
163, 105, 27, 0, 85, 3, 10, 0, 25, 1, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0,
|
||||||
|
1, 0, 0, 0, 0, 0, 0, 0, 188, 106, 27, 0, 110, 4, 10, 0,
|
||||||
|
67, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 207, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 4, 28, 0, 184, 157, 10, 0, 252, 112, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0,
|
||||||
|
1, 0, 0, 0, 0, 0, 0, 0, 252, 116, 28, 0, 180, 14, 11, 0,
|
||||||
|
16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 231, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
12, 117, 28, 0, 196, 14, 11, 0, 239, 79, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0,
|
||||||
|
3, 0, 0, 0, 0, 0, 0, 0, 251, 196, 28, 0, 179, 94, 11, 0,
|
||||||
|
247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
244, 197, 28, 0, 108, 99, 11, 0, 80, 77, 0, 0, 23, 0, 0, 0,
|
||||||
|
210, 4, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 9, 0, 0, 0,
|
||||||
|
3, 0, 0, 0, 0, 0, 0, 0, 68, 19, 29, 0, 188, 176, 11, 0,
|
||||||
|
107, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0,
|
||||||
|
127, 2, 0, 0, 128, 251, 1, 0, 5, 0, 0, 0, 20, 0, 0, 0,
|
||||||
|
224, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0,
|
||||||
|
8, 0, 0, 0, 32, 0, 0, 0, 0, 128, 11, 0, 0, 0, 0, 0,
|
||||||
|
160, 0, 0, 0, 80, 0, 0, 0, 25, 0, 0, 0, 16, 2, 0, 0,
|
||||||
|
14, 0, 0, 0, 28, 0, 0, 0, 82, 83, 68, 32, 80, 84, 82, 32,
|
||||||
|
89, 66, 79, 67, 72, 83, 32, 0, 220, 24, 254, 7, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 8, 0, 0, 0,
|
||||||
|
}
|
||||||
|
)
|
Loading…
x
Reference in New Issue
Block a user