forked from SanseroGames/LetsGo-OS
-
Notifications
You must be signed in to change notification settings - Fork 0
/
multiboot.go
122 lines (100 loc) · 2.74 KB
/
multiboot.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package main
import (
"unsafe"
)
const (
MEM_MAP_AVAILABLE = 1
)
var (
multibootInfo *MultibootInfo
loadedModules [20]MultibootModule
memoryMaps [6]MemoryMap
)
type MultibootInfo struct {
TotalSize uint32
reserved uint32
}
type multibootType uint32
type MultibootTag struct {
Type uint32
Size uint32
}
type MultibootMemoryMap struct {
MultibootTag // Type is 6
EntrySize uint32
EntryVersion uint32
Entries MemoryMap // Take pointer of it and use it as slice with
}
// A module represents a module to be loaded along with the kernel.
type MultibootModule struct {
MultibootTag
// Start is the inclusive start of the Module memory location
Start uint32
// End is the exclusive end of the Module memory location.
End uint32
// Cmdline is a pointer to a null-terminated ASCII string.
cmdline [100]byte
}
func (m *MultibootModule) Cmdline() string {
if m.Size <= 17 {
return ""
}
return unsafe.String(&m.cmdline[0], max(m.Size-16-1, 1))
}
type Module struct {
Start uint32
End uint32
Cmdline string
}
type MemoryMap struct {
BaseAddr uint64
Length uint64
Type uint32
reserved uint32
}
func InitMultiboot(info *MultibootInfo) {
multibootInfo = info
mbI := unsafe.Slice((*byte)(unsafe.Add(unsafe.Pointer(info), unsafe.Sizeof(*info))), info.TotalSize-uint32(unsafe.Sizeof(*info)))
foundModules := 0
for i := uint32(0); i < info.TotalSize; {
mbTag := (*MultibootTag)(unsafe.Pointer(&mbI[i]))
kdebugln("Type ", mbTag.Type, " size ", mbTag.Size, " i ", i, " next ", (i+mbTag.Size+7)&0xfffffff8)
if mbTag.Type == 0 && mbTag.Size == 8 {
break
}
if mbTag.Type == 3 {
if foundModules < len(loadedModules) {
mbMod := (*MultibootModule)(unsafe.Pointer(mbTag))
loadedModules[foundModules] = *mbMod
kdebugln(mbMod.Cmdline())
kdebugln(loadedModules[foundModules].Cmdline())
kdebugln(uintptr(loadedModules[foundModules].Start), " ", uintptr(loadedModules[foundModules].End), " ", loadedModules[foundModules].Size, " ", loadedModules[foundModules].cmdline[0])
foundModules++
} else {
kerrorln("[WARNING] Not enough space to load all modules")
}
}
if mbTag.Type == 6 {
memTag := (*MultibootMemoryMap)(unsafe.Pointer(mbTag))
nrentries := (memTag.Size - 16) / memTag.EntrySize
maps := unsafe.Slice(&(memTag.Entries), nrentries)
for i, v := range maps {
if i > len(memoryMaps) {
kerrorln("[WARNING] More memory maps than space in memorymap list")
break
}
// kdebugln(uintptr(v.BaseAddr), " ", uintptr(v.Length), " ", v.Type)
memoryMaps[i] = v
}
}
oldi := i
size := max(mbTag.Size, 8)
i = (i + size + 7) & 0xfffffff8
if oldi == i {
kerrorln("[WARNING] Loading multiboot modules behaved weird")
break
}
}
kdebugln("Done")
//printMemMaps()
}