forked from u-root/u-root
-
Notifications
You must be signed in to change notification settings - Fork 0
/
info.go
120 lines (94 loc) · 2.41 KB
/
info.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
// Copyright 2018 the u-root Authors. All rights reserved
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package multiboot
import (
"bytes"
"encoding/binary"
"github.com/u-root/u-root/pkg/ubinary"
)
var sizeofInfo = uint32(binary.Size(info{}))
type flag uint32
const (
flagInfoMemory flag = 1 << iota
flagInfoBootDev
flagInfoCmdline
flagInfoMods
flagInfoAoutSyms
flagInfoElfSHDR
flagInfoMemMap
flagInfoDriveInfo
flagInfoConfigTable
flagInfoBootLoaderName
flagInfoAPMTable
flagInfoVideoInfo
flagInfoFrameBuffer
)
// info represents the Multiboot v1 info passed to the loaded kernel.
type info struct {
Flags flag
MemLower uint32
MemUpper uint32
// BootDevice is not supported, always zero.
BootDevice uint32
Cmdline uint32
ModsCount uint32
ModsAddr uint32
// Syms is not supported, always zero array.
Syms [4]uint32
MmapLength uint32
MmapAddr uint32
// Following fields except BootLoaderName are not suppoted yet,
// the values are always set to zeros.
DriversLength uint32
DrivesrAddr uint32
ConfigTable uint32
BootLoaderName uint32
APMTable uint32
VBEControlInfo uint32
VBEModeInfo uint32
VBEMode uint16
VBEInterfaceSeg uint16
VBEInterfaceOff uint16
VBEInterfaceLen uint16
FramebufferAddr uint16
FramebufferPitch uint16
FramebufferWidth uint32
FramebufferHeight uint32
FramebufferBPP byte
FramebufferType byte
ColorInfo [6]byte
}
type infoWrapper struct {
info
Cmdline string
BootLoaderName string
}
// marshal writes out the exact bytes of multiboot info
// expected by the kernel being loaded.
func (iw *infoWrapper) marshal(base uintptr) ([]byte, error) {
offset := sizeofInfo + uint32(base)
iw.info.Cmdline = offset
offset += uint32(len(iw.Cmdline)) + 1
iw.info.BootLoaderName = offset
iw.info.Flags |= flagInfoCmdline | flagInfoBootLoaderName
buf := bytes.Buffer{}
if err := binary.Write(&buf, ubinary.NativeEndian, iw.info); err != nil {
return nil, err
}
for _, s := range []string{iw.Cmdline, iw.BootLoaderName} {
if _, err := buf.WriteString(s); err != nil {
return nil, err
}
if err := buf.WriteByte(0); err != nil {
return nil, err
}
}
size := (buf.Len() + 3) &^ 3
_, err := buf.Write(bytes.Repeat([]byte{0}, size-buf.Len()))
return buf.Bytes(), err
}
func (iw infoWrapper) size() (uint, error) {
b, err := iw.marshal(0)
return uint(len(b)), err
}