github.com/shaardie/u-root@v4.0.1-0.20190127173353-f24a1c26aa2e+incompatible/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 const DebugPrefix = "MULTIBOOT_DEBUG_INFO:" 17 18 // Description stores representation of multiboot 19 // information passed to a final kernel used for 20 // for debugging and testing. 21 type Description struct { 22 Status string `json:"status"` 23 24 Flags uint32 `json:"flags"` 25 MemLower uint32 `json:"mem_lower"` 26 MemUpper uint32 `json:"mem_upper"` 27 MmapAddr uint32 `json:"mmap_addr"` 28 MmapLength uint32 `json:"mmap_length"` 29 30 CmdLine string `json:"cmdline"` 31 Bootloader string `json:"bootloader"` 32 33 Mmap []MemoryMap `json:"mmap"` 34 Modules []ModuleDesc `json:"modules"` 35 } 36 37 // Description returns string representation of 38 // multiboot information. 39 func (m Multiboot) Description() (string, error) { 40 var modules []ModuleDesc 41 for i, mod := range m.loadedModules { 42 name := strings.Fields(m.modules[i])[0] 43 b, err := readFile(name) 44 if err != nil { 45 return "", nil 46 } 47 hash := sha256.Sum256(b) 48 modules = append(modules, ModuleDesc{ 49 Start: mod.Start, 50 End: mod.End, 51 CmdLine: m.modules[i], 52 SHA256: fmt.Sprintf("%x", hash), 53 }) 54 55 } 56 57 b, err := json.Marshal(Description{ 58 Status: "ok", 59 Flags: uint32(m.info.Flags), 60 MemLower: m.info.MemLower, 61 MemUpper: m.info.MemUpper, 62 MmapAddr: m.info.MmapAddr, 63 MmapLength: m.info.MmapLength, 64 65 CmdLine: m.cmdLine, 66 Bootloader: m.bootloader, 67 68 Mmap: m.memoryMap(), 69 Modules: modules, 70 }) 71 if err != nil { 72 return "", err 73 } 74 75 b = bytes.Replace(b, []byte{'\n'}, []byte{' '}, -1) 76 return string(b), nil 77 } 78 79 // ModuleDesc is a debug representation of 80 // loaded module. 81 type ModuleDesc struct { 82 Start uint32 `json:"start"` 83 End uint32 `json:"end"` 84 CmdLine string `json:"cmdline"` 85 SHA256 string `json:"sha256"` 86 } 87 88 type mmap struct { 89 Size uint32 `json:"size"` 90 BaseAddr string `json:"base_addr"` 91 Length string `json:"length"` 92 Type uint32 `json:"type"` 93 } 94 95 // MarshalJSON implements json.Marshaler 96 func (m MemoryMap) MarshalJSON() ([]byte, error) { 97 return json.Marshal(mmap{ 98 Size: m.Size, 99 BaseAddr: fmt.Sprintf("%#x", m.BaseAddr), 100 Length: fmt.Sprintf("%#x", m.Length), 101 Type: m.Type, 102 }) 103 } 104 105 // UnmarshalJSON implements json.Unmarshaler 106 func (m *MemoryMap) UnmarshalJSON(b []byte) error { 107 var desc mmap 108 err := json.Unmarshal(b, &desc) 109 if err != nil { 110 return err 111 } 112 113 m.Size = desc.Size 114 m.Type = desc.Type 115 v, err := strconv.ParseUint(desc.BaseAddr, 0, 64) 116 if err != nil { 117 return err 118 } 119 m.BaseAddr = v 120 121 v, err = strconv.ParseUint(desc.Length, 0, 64) 122 if err != nil { 123 return err 124 } 125 m.Length = v 126 return nil 127 }