-
Notifications
You must be signed in to change notification settings - Fork 4
/
linux_file_load.go
70 lines (62 loc) · 1.83 KB
/
linux_file_load.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
// package kexec contains the kexec-related syscalls
// +build linux
package kexec
import (
"fmt"
"github.com/platinasystems/fdt"
"github.com/platinasystems/goes/internal/memmap"
"io/ioutil"
"os"
"syscall"
)
func LoadSlices(kdat, idat []byte, cmdline string, flags uintptr) (err error) {
m, err := memmap.FileToMap("/proc/iomem")
if err != nil {
return err
}
kCode, ok := m["Kernel code"]
if !ok {
return fmt.Errorf("Can't find kernel code in /proc/iomem")
}
kBase := kCode.Ranges[0].Start
segments := make([]KexecSegment, 0, 3)
segments = SliceAddSegment(segments, &kdat, kBase)
segments = SliceAddSegment(segments, &idat, kBase+0x2000000)
t := fdt.DefaultTree()
if t != nil {
chosen := t.RootNode.Children["chosen"]
if chosen == nil {
chosen = &fdt.Node{Name: "chosen", Depth: 1}
t.RootNode.Children["chosen"] = chosen
}
//need 64 bit support - parsing for #address-cells
if idat != nil {
chosen.Properties["linux,initrd-start"] = t.PropUint32ToSlice(uint32(segments[1].Mem))
chosen.Properties["linux,initrd-end"] = t.PropUint32ToSlice(uint32(segments[1].Mem) + uint32(segments[1].Bufsz) + 1)
}
chosen.Properties["bootargs"] = []byte(cmdline + "\x00")
fdt := t.FlattenTreeToSlice()
segments = SliceAddSegment(segments, &fdt, kBase+0x1000000)
}
err = SegmentLoad(uint64(kBase), &segments, 0)
return err
}
func FileLoad(k *os.File, i *os.File, cmdline string, flags uintptr) (err error) {
err = fileLoadSyscall(k, i, cmdline, flags)
if err == syscall.ENOSYS {
kdat, err := ioutil.ReadAll(k)
if err != nil {
return fmt.Errorf("Opening kernel %s: %w", k.Name(), err)
}
idat := []byte{}
if i != nil {
idat, err = ioutil.ReadAll(i)
if err != nil {
return fmt.Errorf("Opening initramfs %s: %w",
i.Name(), err)
}
}
return LoadSlices(kdat, idat, cmdline, flags)
}
return err
}