-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The display command uses the plan9ports devdraw device, and the 9fans devdraw Go support, to allow a display of the state of the buffer. Currently, a user can do something like this: Set up so devdraw command is in $PATH PLAN9=/Users/rminnich/Documents/plan9 export PLAN9 PATH=$PATH:$PLAN9/bin export PATH Now run utk utk ~/Downloads/SBIOS_P5043_PG535_SKU_893_02.02.03_rel_prod.rom \ display start \ remove_dxes_except list \ display end The result will be two windows, one showing before, and one after. The plan is that this can get fancier: utk ~/Downloads/SBIOS_P5043_PG535_SKU_893_02.02.03_rel_prod.rom \ display start \ remove Http.* \ display nohttp \ remove_dxes_except list \ display end Also, note, although we only set up one pixel for each point, devdraw is nice to you: if you grow the window it grows the display of ROM. Also, the border is necessery for OSX with its rounded edges. Signed-off-by: Ronald G. Minnich <[email protected]>
- Loading branch information
Showing
3 changed files
with
153 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
// Copyright 2018 the LinuxBoot Authors. All rights reserved | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package visitors | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"io" | ||
"os" | ||
"time" | ||
|
||
"9fans.net/go/draw" | ||
"github.com/linuxboot/fiano/pkg/uefi" | ||
) | ||
|
||
// Display the memory map with used areas in red. | ||
// This can be called multiple times. | ||
// The argument is the display name. | ||
type Display struct { | ||
// Input | ||
Predicate func(f uefi.Firmware) bool | ||
Name string | ||
// logs are written to this writer. | ||
W io.Writer | ||
} | ||
|
||
func (v *Display) printf(format string, a ...interface{}) { | ||
if v.W != nil { | ||
fmt.Fprintf(v.W, format, a...) | ||
} | ||
} | ||
|
||
// Run wraps Visit and performs some setup and teardown tasks. | ||
func (v *Display) Run(f uefi.Firmware) error { | ||
return f.Apply(v) | ||
} | ||
|
||
// Visit applies the Display visitor to any Firmware type. | ||
// The name "end" has meaning. It will force an assemble of the image, | ||
// which should cleanup f.Buf(), and it will not return. | ||
// If it returns, utk will exit and you will see no images. | ||
// Using "end" this way lets us hold off on using goroutines and | ||
// waitgroups for now. | ||
func (v *Display) Visit(f uefi.Firmware) error { | ||
switch f := f.(type) { | ||
case *uefi.BIOSRegion: | ||
if v.Name == "end" { | ||
a := &Assemble{} | ||
// Assemble the binary to make sure the top level buffer is correct | ||
if err := f.Apply(a); err != nil { | ||
return err | ||
} | ||
} | ||
b := bytes.NewBuffer(f.Buf()) | ||
// The display is 256KiB x however many rows we need. | ||
// So that's len(buf) / (256x1024) | ||
squareSize := 1 | ||
wid := 100 + 256*squareSize | ||
ht := 100 + squareSize*b.Len()/(wid*1024) | ||
// Initialize the draw context with a dynamically-sized window | ||
d, err := draw.Init(nil, "", v.Name, fmt.Sprintf("256x%d", ht)) | ||
if err != nil { | ||
return fmt.Errorf("failed to initialize draw: %w", err) | ||
} | ||
|
||
// Initialize mouse control using drawfcall | ||
// mousectl, err := drawfcall.InitMouse("", d.ScreenImage) | ||
//if err != nil { | ||
//log.Fatalf("failed to initialize mouse: %v", err) | ||
//} | ||
|
||
// Determine the window size from the screen image | ||
winWidth := wid | ||
winHeight := ht | ||
|
||
// Get color images for red and green | ||
grn := d.AllocImageMix(draw.Green, draw.Opaque) | ||
red := d.AllocImageMix(draw.Red, draw.Opaque) | ||
|
||
var buf [uefi.RegionBlockSize]byte | ||
for y := 0; y < winHeight; y++ { | ||
for x := 0; x < winWidth; x++ { | ||
// Calculate the top-left corner of the square | ||
pt := draw.Pt(50+x*squareSize, 50+y*squareSize) | ||
rect := draw.Rect(pt.X, pt.Y, pt.X+squareSize, pt.Y+squareSize) | ||
n, err := b.Read(buf[:]) | ||
if err != nil && err != io.EOF { | ||
return fmt.Errorf("reading buffer with non-eof error:%w", err) | ||
} | ||
|
||
// Alternate colors between red and yellow | ||
if uefi.IsErased(buf[:n], 0) { | ||
d.ScreenImage.Draw(rect, grn, nil, draw.ZP) | ||
} else { | ||
d.ScreenImage.Draw(rect, red, nil, draw.ZP) | ||
} | ||
} | ||
} | ||
|
||
d.Flush() | ||
|
||
// What a hack. But it will let us test the idea, | ||
// until we're sure it is right. | ||
for v.Name == "end" { | ||
time.Sleep(40 * time.Second) | ||
} | ||
|
||
} | ||
|
||
return nil | ||
} | ||
|
||
func init() { | ||
RegisterCLI("display", "display the memory map", 1, func(args []string) (uefi.Visitor, error) { | ||
if len(args) != 1 { | ||
return nil, fmt.Errorf("usage: display <name>:%w", os.ErrInvalid) | ||
} | ||
return &Display{ | ||
Name: args[0], | ||
W: os.Stdout, | ||
}, nil | ||
}) | ||
} |