github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/pkg/vpd/flashromvpd.go (about) 1 // Copyright 2021 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 vpd 6 7 import ( 8 "log" 9 "os" 10 "os/exec" 11 "os/signal" 12 "syscall" 13 ) 14 15 func handler(c <-chan os.Signal) { 16 for range c { 17 log.Printf("ignoring SIGINT during flash write to prevent corruption") 18 } 19 } 20 21 // Set RW_VPD key-value via flashrom and vpd executables, delete set to false would set or add the key, 22 // delete set to true would delete an existing key. 23 func FlashromRWVpdSet(key string, value []byte, delete bool) error { 24 file, err := os.CreateTemp("/tmp", "rwvpd*.bin") 25 if err != nil { 26 return err 27 } 28 defer os.Remove(file.Name()) 29 30 c := make(chan os.Signal, 1) 31 go handler(c) 32 defer close(c) 33 34 cmd := exec.Command("flashrom", "-p", "internal:ich_spi_mode=hwseq", "-c", "Opaque flash chip", "--fmap", "-i", "RW_VPD", "-r", file.Name()) 35 cmd.Stdin, cmd.Stdout = os.Stdin, os.Stdout 36 if err = cmd.Run(); err != nil { 37 log.Printf("flashrom failed to read RW_VPD: %v", err) 38 return err 39 } 40 41 if delete { 42 cmd = exec.Command("vpd", "-f", file.Name(), "-d", key) 43 if err = cmd.Run(); err != nil { 44 log.Printf("vpd failed to delete key: %v, err: %v", key, err) 45 return err 46 } 47 } else { 48 cmd = exec.Command("vpd", "-f", file.Name(), "-s", key+"="+string(value[:])) 49 if err = cmd.Run(); err != nil { 50 log.Printf("vpd failed to set key: %v value: %v, err: %v", key, string(value[:]), err) 51 return err 52 } 53 } 54 55 cmd = exec.Command("flashrom", "-p", "internal:ich_spi_mode=hwseq", "-c", "Opaque flash chip", "--fmap", "-i", "RW_VPD", "--noverify-all", "-w", file.Name()) 56 cmd.SysProcAttr = &syscall.SysProcAttr{ 57 Setpgid: true, 58 } 59 signal.Notify(c, syscall.SIGINT) 60 defer signal.Reset(syscall.SIGINT) 61 if err = cmd.Run(); err != nil { 62 log.Printf("flashrom failed to write RW_VPD: %v", err) 63 return err 64 } 65 return nil 66 } 67 68 // ClearRwVpd re-format RW_VPD via flashrom and vpd executables 69 func ClearRwVpd() error { 70 file, err := os.CreateTemp("/tmp", "rwvpd*.bin") 71 if err != nil { 72 return err 73 } 74 defer os.Remove(file.Name()) 75 76 c := make(chan os.Signal, 1) 77 go handler(c) 78 defer close(c) 79 80 log.Printf("Reading RW_VPD...") 81 cmd := exec.Command("flashrom", "-p", "internal:ich_spi_mode=hwseq", "-c", "Opaque flash chip", "--fmap", "-i", "RW_VPD", "-r", file.Name()) 82 cmd.Stdin, cmd.Stdout = os.Stdin, os.Stdout 83 if err = cmd.Run(); err != nil { 84 log.Printf("flashrom failed to read RW_VPD: %v", err) 85 return err 86 } 87 cmd = exec.Command("vpd", "-f", file.Name(), "-O") 88 if err = cmd.Run(); err != nil { 89 log.Printf("vpd failed to re-format RW_VPD: %v", err) 90 return err 91 } 92 cmd = exec.Command("flashrom", "-p", "internal:ich_spi_mode=hwseq", "-c", "Opaque flash chip", "--fmap", "-i", "RW_VPD", "--noverify-all", "-w", file.Name()) 93 cmd.SysProcAttr = &syscall.SysProcAttr{ 94 Setpgid: true, 95 } 96 signal.Notify(c, syscall.SIGINT) 97 defer signal.Reset(syscall.SIGINT) 98 if err = cmd.Run(); err != nil { 99 log.Printf("flashrom failed to write RW_VPD: %v", err) 100 return err 101 } 102 return nil 103 } 104 105 // FlashromVpdDump read and dump all VPD values from RO and RW VPD flash regions directly 106 func FlashromVpdDump() error { 107 file, err := os.CreateTemp("/tmp", "rovpd*.bin") 108 if err != nil { 109 return err 110 } 111 defer os.Remove(file.Name()) 112 113 log.Printf("RO_VPD values:") 114 cmd := exec.Command("flashrom", "-p", "internal:ich_spi_mode=hwseq", "-c", "Opaque flash chip", "--fmap", "-i", "RO_VPD", "-r", file.Name()) 115 if err = cmd.Run(); err != nil { 116 log.Printf("flashrom failed to read RO_VPD: %v", err) 117 return err 118 } 119 cmd = exec.Command("vpd", "-f", file.Name(), "-l") 120 cmd.Stdin, cmd.Stdout = os.Stdin, os.Stdout 121 if err = cmd.Run(); err != nil { 122 log.Printf("vpd failed to print RO_VPD: %v", err) 123 return err 124 } 125 126 os.Remove(file.Name()) 127 file, err = os.CreateTemp("/tmp", "rwvpd*.bin") 128 if err != nil { 129 return err 130 } 131 defer os.Remove(file.Name()) 132 133 log.Printf("RW_VPD values:") 134 cmd = exec.Command("flashrom", "-p", "internal:ich_spi_mode=hwseq", "-c", "Opaque flash chip", "--fmap", "-i", "RW_VPD", "-r", file.Name()) 135 if err = cmd.Run(); err != nil { 136 log.Printf("flashrom failed to read RW_VPD: %v", err) 137 return err 138 } 139 cmd = exec.Command("vpd", "-f", file.Name(), "-l") 140 cmd.Stdin, cmd.Stdout = os.Stdin, os.Stdout 141 if err = cmd.Run(); err != nil { 142 log.Printf("vpd failed to print RW_VPD: %v", err) 143 return err 144 } 145 146 return nil 147 }