Skip to content

Commit

Permalink
Add support for extracting an image. (#568)
Browse files Browse the repository at this point in the history
  • Loading branch information
floitsch authored Nov 8, 2024
1 parent 61e770a commit d51a750
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 16 deletions.
2 changes: 1 addition & 1 deletion cmd/jag/commands/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ func crashDecode(ctx context.Context, envelope string, backtrace string) error {
}
}

firmwareElf, err := ExtractFirmware(ctx, sdk, envelopePath, "elf")
firmwareElf, err := ExtractFirmware(ctx, sdk, envelopePath, "elf", nil)
if err != nil {
return err
}
Expand Down
57 changes: 57 additions & 0 deletions cmd/jag/commands/firmware.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func FirmwareCmd() *cobra.Command {
},
}
cmd.AddCommand(FirmwareUpdateCmd())
cmd.AddCommand(FirmwareExtractCmd())
cmd.Flags().StringP("device", "d", "", "use device with a given name, id, or address")
return cmd
}
Expand Down Expand Up @@ -111,3 +112,59 @@ func FirmwareUpdateCmd() *cobra.Command {
addFirmwareFlashFlags(cmd, "", "new name of the device, if given")
return cmd
}

func FirmwareExtractCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "extract [envelope]",
Short: "Build the firmware image of a Jaguar device",
Long: "Build the firmware image of a Jaguar device, for flashing, Wokwi, or QEMU." +
"\n" +
"Wokwi\n" +
"-----\n" +
"Remember to use the WiFi SSID \"Wokwi-GUEST\" without a password.\n" +
"You need a Club subscription to be able to connect to your device, but\n" +
"the device is able to reach the Internet without a subscription.\n" +
"\n" +
"To run the image go to https://wokwi.com/projects/new/esp32, then\n" +
"press F1 and run the command \"Upload Firmware and Start Simulation\".\n",
Args: cobra.MaximumNArgs(1),
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()

output, err := cmd.Flags().GetString("output")
if err != nil {
return err
}
if output == "" {
return fmt.Errorf("missing output file")
}

return withFirmware(cmd, args, nil, func(newID string, envelopeFile *os.File, config map[string]interface{}) error {

sdk, err := GetSDK(ctx)
if err != nil {
return err
}

imageFile, err := ExtractFirmware(ctx, sdk, envelopeFile.Name(), "image", config)
if err != nil {
return err
}
defer os.Remove(imageFile.Name())

imageBin, err := os.ReadFile(imageFile.Name())
if err != nil {
return err
}

return os.WriteFile(output, imageBin, 0644)
})
},
}

cmd.Flags().StringP("device", "d", "", "use device with a given name, id, or address")
addFirmwareFlashFlags(cmd, "esp32", "name of the device")
cmd.Flags().StringP("output", "o", "", "write the firmware image to a file")
return cmd
}
32 changes: 17 additions & 15 deletions cmd/jag/commands/firmware_flash.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,12 +246,12 @@ func ExtractFirmwareBin(ctx context.Context, sdk *SDK, envelopePath string, conf
return binaryFile, nil
}

func ExtractFirmware(ctx context.Context, sdk *SDK, envelopePath string, format string) (*os.File, error) {
func ExtractFirmware(ctx context.Context, sdk *SDK, envelopePath string, format string, config map[string]interface{}) (*os.File, error) {
outputFile, err := os.CreateTemp("", "firmware-"+format+".*")
if err != nil {
return nil, err
}
if err := runFirmwareTool(ctx, sdk, envelopePath, "extract", "--format", format, "-o", outputFile.Name()); err != nil {
if err := runFirmwareToolWithConfig(ctx, sdk, envelopePath, config, "extract", "--format", format, "-o", outputFile.Name()); err != nil {
outputFile.Close()
return nil, err
}
Expand All @@ -263,22 +263,24 @@ func setFirmwareProperty(ctx context.Context, sdk *SDK, envelope *os.File, key s
}

func runFirmwareToolWithConfig(ctx context.Context, sdk *SDK, envelopePath string, config map[string]interface{}, args ...string) error {
configFile, err := os.CreateTemp("", "*.json.config")
if err != nil {
return err
}
defer os.Remove(configFile.Name())
if config != nil {
configFile, err := os.CreateTemp("", "*.json.config")
if err != nil {
return err
}
defer os.Remove(configFile.Name())

configBytes, err := json.Marshal(config)
if err != nil {
return err
}
configBytes, err := json.Marshal(config)
if err != nil {
return err
}

if err := os.WriteFile(configFile.Name(), configBytes, 0666); err != nil {
return err
}
if err := os.WriteFile(configFile.Name(), configBytes, 0666); err != nil {
return err
}

args = append(args, "--config", configFile.Name())
args = append(args, "--config", configFile.Name())
}
return runFirmwareTool(ctx, sdk, envelopePath, args...)
}

Expand Down

0 comments on commit d51a750

Please sign in to comment.