tool: Add error for write locked

Add a new error for the case of trying to flash when security is enabled
and it is still locked and update the related docs.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
This commit is contained in:
Tim Crawford
2024-03-22 14:48:56 -06:00
committed by Tim Crawford
parent 54d795480c
commit 70c8678a5f
6 changed files with 26 additions and 12 deletions

View File

@ -1,15 +1,27 @@
# Flashing firmware # Flashing firmware
## UEFI application
The `flash.sh` script from the top-level firmware-open project will use
firmware-update, the UEFI application which is used for normal system updates.
This will flash both the SBIOS and the EC after building the firmware. To
flash just the EC, delete the built `firmware.rom` before running `flash.sh`.
## Internal programmer ## Internal programmer
Use this method for flashing a system already running System76 EC. Use this method for flashing a system already running System76 EC.
This method will only work if the running firmware is not locked. Firmware is This method will only work if the running firmware is not locked. Firmware is
write locked if it was built with `CONFIG_SECURITY=y`. firmware-update must be write locked if it was built with `CONFIG_SECURITY=y`. The firmware can be
used to flash from UEFI in this state (see `flash.sh` in firmware-open). unlocked using ectool for a single boot:
This will trigger a watchdog reset causing the system to **immediately power ```
off**. OS data may be lost or corrupted as a result. Save and close all ./scripts/ectool.sh security unlock
```
This method will trigger a watchdog reset causing the system to **immediately
power off**. OS data may be lost or corrupted as a result. Save and close all
applications before flashing. applications before flashing.
``` ```

View File

@ -104,10 +104,6 @@ make
See [flashing firmware](./flashing.md) for details. See [flashing firmware](./flashing.md) for details.
```sh
make flash_internal
```
Do not use the keyboard or touchpad while it is flashing. Do not use the keyboard or touchpad while it is flashing.
The system will power off as part of the flash process. Turn it back on after The system will power off as part of the flash process. Turn it back on after

View File

@ -2,5 +2,5 @@
# SPDX-License-Identifier: GPL-3.0-only # SPDX-License-Identifier: GPL-3.0-only
set -e set -e
cargo build --release --manifest-path tool/Cargo.toml cargo build --release --quiet --manifest-path tool/Cargo.toml
sudo tool/target/release/system76_ectool "$@" sudo tool/target/release/system76_ectool "$@"

View File

@ -11,7 +11,7 @@ enum SecurityState security_get(void) {
bool security_set(enum SecurityState state) { bool security_set(enum SecurityState state) {
switch (state) { switch (state) {
// Allow perpare states to be set // Allow prepare states to be set
case SECURITY_STATE_PREPARE_LOCK: case SECURITY_STATE_PREPARE_LOCK:
case SECURITY_STATE_PREPARE_UNLOCK: case SECURITY_STATE_PREPARE_UNLOCK:
security_state = state; security_state = state;

View File

@ -29,6 +29,8 @@ pub enum Error {
/// Encountered a hidapi::Error /// Encountered a hidapi::Error
#[cfg(feature = "hidapi")] #[cfg(feature = "hidapi")]
Hid(hidapi::HidError), Hid(hidapi::HidError),
/// Writing to flash is disabled
WriteLocked,
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]

View File

@ -170,6 +170,12 @@ unsafe fn flash(ec: &mut Ec<Box<dyn Access>>, path: &str, target: SpiTarget) ->
println!("ec version: {:?}", str::from_utf8(ec_version)); println!("ec version: {:?}", str::from_utf8(ec_version));
} }
if let Ok(security) = ec.security_get() {
if security != SecurityState::Unlock {
return Err(Error::WriteLocked);
}
}
if scratch { if scratch {
// Wait for any key releases // Wait for any key releases
eprintln!("Waiting 5 seconds for all keys to be released"); eprintln!("Waiting 5 seconds for all keys to be released");
@ -378,8 +384,6 @@ struct Args {
} }
fn main() { fn main() {
//.subcommand(Command::new("security").arg(Arg::new("state").value_parser(["lock", "unlock"])))
let args = Args::parse(); let args = Args::parse();
let get_ec = || -> Result<_, Error> { let get_ec = || -> Result<_, Error> {