github.com/hugelgupf/u-root@v0.0.0-20191023214958-4807c632154c/pkg/multiboot/description.go (about) 1 // Copyright 2019 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package multiboot 6 7 import ( 8 "bytes" 9 "crypto/sha256" 10 "encoding/json" 11 "fmt" 12 "strconv" 13 "strings" 14 ) 15 16 // DebugPrefix is a prefix that some messages are printed with for tests to parse. 17 const DebugPrefix = "MULTIBOOT_DEBUG_INFO:" 18 19 // Description stores representation of multiboot 20 // information passed to a final kernel used for 21 // for debugging and testing. 22 type Description struct { 23 Status string `json:"status"` 24 25 Flags uint32 `json:"flags"` 26 MemLower uint32 `json:"mem_lower"` 27 MemUpper uint32 `json:"mem_upper"` 28 MmapAddr uint32 `json:"mmap_addr"` 29 MmapLength uint32 `json:"mmap_length"` 30 31 CmdLine string `json:"cmdline"` 32 Bootloader string `json:"bootloader"` 33 34 Mmap []MemoryMap `json:"mmap"` 35 Modules []ModuleDesc `json:"modules"` 36 } 37 38 // Description returns string representation of 39 // multiboot information. 40 func (m multiboot) description() (string, error) { 41 var modules []ModuleDesc 42 for i, mod := range m.loadedModules { 43 name := strings.Fields(m.modules[i])[0] 44 b, err := readFile(name) 45 if err != nil { 46 return "", nil 47 } 48 hash := sha256.Sum256(b) 49 modules = append(modules, ModuleDesc{ 50 Start: mod.Start, 51 End: mod.End, 52 CmdLine: m.modules[i], 53 SHA256: fmt.Sprintf("%x", hash), 54 }) 55 56 } 57 58 b, err := json.Marshal(Description{ 59 Status: "ok", 60 Flags: uint32(m.info.Flags), 61 MemLower: m.info.MemLower, 62 MemUpper: m.info.MemUpper, 63 MmapAddr: m.info.MmapAddr, 64 MmapLength: m.info.MmapLength, 65 66 CmdLine: m.cmdLine, 67 Bootloader: m.bootloader, 68 69 Mmap: m.memoryMap(), 70 Modules: modules, 71 }) 72 if err != nil { 73 return "", err 74 } 75 76 b = bytes.Replace(b, []byte{'\n'}, []byte{' '}, -1) 77 return string(b), nil 78 } 79 80 // ModuleDesc is a debug representation of 81 // loaded module. 82 type ModuleDesc struct { 83 Start uint32 `json:"start"` 84 End uint32 `json:"end"` 85 CmdLine string `json:"cmdline"` 86 SHA256 string `json:"sha256"` 87 } 88 89 type mmap struct { 90 Size uint32 `json:"size"` 91 BaseAddr string `json:"base_addr"` 92 Length string `json:"length"` 93 Type uint32 `json:"type"` 94 } 95 96 // MarshalJSON implements json.Marshaler 97 func (m MemoryMap) MarshalJSON() ([]byte, error) { 98 return json.Marshal(mmap{ 99 Size: m.Size, 100 BaseAddr: fmt.Sprintf("%#x", m.BaseAddr), 101 Length: fmt.Sprintf("%#x", m.Length), 102 Type: m.Type, 103 }) 104 } 105 106 // UnmarshalJSON implements json.Unmarshaler 107 func (m *MemoryMap) UnmarshalJSON(b []byte) error { 108 var desc mmap 109 err := json.Unmarshal(b, &desc) 110 if err != nil { 111 return err 112 } 113 114 m.Size = desc.Size 115 m.Type = desc.Type 116 v, err := strconv.ParseUint(desc.BaseAddr, 0, 64) 117 if err != nil { 118 return err 119 } 120 m.BaseAddr = v 121 122 v, err = strconv.ParseUint(desc.Length, 0, 64) 123 if err != nil { 124 return err 125 } 126 m.Length = v 127 return nil 128 }