github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/pkg/boot/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 14 "github.com/u-root/u-root/pkg/uio" 15 ) 16 17 // DebugPrefix is a prefix that some messages are printed with for tests to parse. 18 const DebugPrefix = "MULTIBOOT_DEBUG_INFO:" 19 20 // Description stores representation of multiboot 21 // information passed to a final kernel used for 22 // for debugging and testing. 23 type Description struct { 24 Status string `json:"status"` 25 26 Flags uint32 `json:"flags"` 27 MemLower uint32 `json:"mem_lower"` 28 MemUpper uint32 `json:"mem_upper"` 29 MmapAddr uint32 `json:"mmap_addr"` 30 MmapLength uint32 `json:"mmap_length"` 31 32 Cmdline string `json:"cmdline"` 33 Bootloader string `json:"bootloader"` 34 35 Mmap []MemoryMap `json:"mmap"` 36 Modules []ModuleDesc `json:"modules"` 37 } 38 39 // Description returns string representation of 40 // multiboot information. 41 func (m multiboot) description() (string, error) { 42 var modules []ModuleDesc 43 for i, mod := range m.loadedModules { 44 b, err := uio.ReadAll(m.modules[i].Module) 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].Cmdline, 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 }