# Firmware tools

> freemkv-fw and freemkv-flash — the two CLI tools for building and installing freemkv firmware — plus the full command ABI the resulting firmware answers to on the wire.

Source: https://freemkv.org/docs/firmware-tools/

> **Note**
>
> Accurate as of freemkv firmware **0.9.2+**.

freemkv firmware turns a supported optical drive into a faster, unlocked drive. Two small
command-line tools do the work: **freemkv-fw** builds and checks firmware images, and
**freemkv-flash** writes them to a drive. Both are also documented on the public
[Firmware](https://freemkv.org/firmware/) pages, which cover finding a base image, building it, and flashing it
step by step; this page is the detailed reference — for the tools themselves, for identifying
your drive, and for the command ABI the firmware they build actually implements.

## freemkv-fw

`freemkv-fw` turns a base MediaTek firmware image into freemkv firmware, and checks whether a
file or a live drive is already freemkv.

### create

```bash
freemkv-fw create <input.bin> [output.freemkv.bin]     # default output: <input-stem>.freemkv.bin
freemkv-fw create <input.bin> --json                   # machine-readable per-capability report
freemkv-fw create <input.bin> --audit                  # verify every applied patch actually landed
freemkv-fw create <input.bin> --in-place               # rewrite the input image instead of writing a new file
freemkv-fw create <input.bin> --base                   # strict base build: all-or-nothing, refuses without a full freemkv base
```

Takes one stock (OEM) image and produces one freemkv image. It **auto-detects the chipset**
(MediaTek MT1959 or MT1939) from the image, then applies **every capability that drive supports
and reports each one individually** — by default it is never all-or-nothing (`--base` is the
strict exception, used by the publish pipeline). A capability whose signature
isn't found on that particular image is reported and skipped; the rest still apply. Each
capability comes back as one of four states:

| Report | Meaning |
|---|---|
| **applied** | the patch was added on this run |
| **already set** | the feature is already present (e.g. re-running on freemkv firmware) — a safe no-op |
| **n/a** | out of scope for this drive (e.g. UHD on a DVD-only drive) |
| **skipped** | in scope, but the signature wasn't found on this image (nothing is written) |

Running `create` on freemkv firmware again is **idempotent**: every capability reports *already
set* and the output is byte-identical to the input. `--audit` (also `create --audit`) re-derives
the exact expected patch bytes and confirms each applied capability actually landed at its hook
site — an automated correctness check, no drive required. The drive stays completely stock until
the freemkv command is sent — see [Command reference](#command-reference) below.

| Capability | What it does | Status |
|---|---|---|
| Speed | Sets the read-speed / riplock ceiling — a settable cap, not just on/off | ready |
| Region | Region-free (RPC-1, no ~5-change cap), or force a specific DVD region (1–8) or Blu-ray region (A/B/C) | ready |
| Unrestricted (was UHD) | Opens the drive to read every disc type, including Blu-ray and Ultra HD Blu-ray (AACS 1.0/2.0). Same wire discriminant as the old `Uhd` name | ready |
| Revocation (HRL) | Skip the host-certificate revocation check, so a revoked-but-genuine certificate still works (non-destructive) | ready |
| Encryption | Removes the drive's disc-encryption handshake so content reads back decrypted; the host applies the title keys | ready |
| Downgrade versions | Enables you to flash any firmware version over any existing one | ready |
| Diagnostic Dump | Reads 64-byte windows of firmware RAM | ready (diagnostic use) |

These map to the **features** in the [command reference](#command-reference) below, each an
independent setting. Which capabilities apply to a given image depends on the chipset and
generation, so `create` reports them per image rather than assuming — a DVD-only drive has no Unrestricted
gate, for example. Every feature except `Unrestricted` (armed by default) ships at OEM, and
the rest stay stock until deliberately armed; settings live in RAM and revert on power-off unless **saved** to
flash. Every build is **statically verified** (integrity re-signs, structural audit passes); the
levers are structurally verified across the corpus.

### verify

```bash
freemkv-fw verify <file-or-device>
```

Answers one question two ways. Point it at a **file** to check the firmware image's own
internal integrity. Point it at a **live drive** (e.g. `/dev/sg0`) to send the Identity command
over SCSI and report what the drive itself says back. For a file, `--family <mt1959|mt1939>`
forces the chipset instead of auto-detecting it.

### info

```bash
freemkv-fw info <device>                                        # print the drive's freemkv identity
freemkv-fw info <device> --dump <addr> --len <len> --out <file>  # read an explicit memory range (hex)
freemkv-fw info <device> --full --out <prefix>                  # capture the whole decrypted image
```

Probes a live freemkv drive. With no flags it prints the drive's freemkv identity; `--dump`
reads a memory range, and `--full` captures every readable flash and RAM region, one
`<prefix>-<address>.bin` file per region. Read-only.

### sign

```bash
freemkv-fw sign <image.bin> [-o <out.bin>] [--in-place]    # default output: <stem>.signed.bin
```

Recomputes and writes back the digest of every active integrity region in an image, after
you have edited it by hand. `--family` forces the chipset, as for `verify`.

## freemkv-flash

`freemkv-flash` is a generic MediaTek (MT19xx) optical-drive flasher and dumper. It isn't
specific to freemkv — it can read and write any compatible firmware image. It always backs up
before writing, and reads back every write to confirm it took. `dump` also works on Pioneer and
Renesas drives, as a backup only: `flash` never writes to those.

### info

```bash
freemkv-flash info <device>        # identify a live drive
freemkv-flash info <image.bin>     # classify a firmware file
```

`info` works on **either a live drive or a firmware file** — it auto-detects which. On a
**device** it reports the drive's **vendor**, **product**, and **firmware revision** (from the
drive's own SCSI `INQUIRY` data). On a **file** it classifies the image: chipset (MT1959 /
MT1939), vendor/model/revision, media capability (BD / UHD / DVD), whether the tool can flash it,
and whether its integrity tables are valid. Both use the **same detection**, which is exactly
what the flasher's file↔drive safety check compares. Read-only and safe.

### dump

```bash
freemkv-flash dump <device> [-o backup.tar]     # default output: <product>_<revision>.dump.tar
```

Reads the drive's current firmware to a file. Always dump and keep a backup before flashing
anything.

### flash

```bash
# dry-run (default — plans the write, changes nothing):
freemkv-flash flash --input <image.bin> <device>

# actually write it:
freemkv-flash flash --input <image.bin> <device> \
    --execute --i-understand-risk --backup <backup.tar>
```

Writes an image to the drive. **It is dry-run by default** — without `--execute` it only prints
the plan and writes nothing. A real write requires `--execute` and `--i-understand-risk`, and
takes a **mandatory pre-flash backup** first (`--backup`), then reads the image back to verify.
The only way around the backup is `--rescue-no-dump`, for rescuing a drive that can no longer be
read. (`--mode main|full` is accepted but has no effect on MT1959: the full image is always
written.)
Before flashing it runs the same file↔drive check as `info`, refusing an image whose chipset
family doesn't match the connected drive.

Executable writes are supported today for **MediaTek MT1959**; other families are catalogued and
can be planned (dry-run) but are gated off real writes until validated on hardware. `flash` is
newer and less battle-tested than `info`/`dump` — always keep your own separate dump as well.

> **Caution: Crossflash is experimental**
>
> `--allow-crossflash` waives the drive-*model* match (but **never** the chipset-family match, and
> never the backup/risk gates) to flash one MT1959 drive's firmware onto a different MT1959 drive.
> It is **experimental and not hardware-validated**, warns on capability mismatches (e.g. UHD vs
> non-UHD), and can brick an incompatible drive. Same-chipset only; different chipsets are always
> refused.

## How do I tell what drive I have?

Before building or flashing anything, confirm what you're working with — vendor, model, and
firmware revision:

- **`freemkv-flash info <device>`** — the quickest path; prints the drive's vendor, product,
  and firmware revision straight from its `INQUIRY` data.
- **Linux, `lsscsi`** — lists attached SCSI/ATAPI devices, including the vendor and model
  string, without touching the drive.
- **Linux, `sg_inq <device>`** (from `sg3-utils`) — issues a standard `INQUIRY` directly and
  prints the same vendor/product/revision fields `freemkv-flash info` reads.
- **The label on the drive itself**, or on Windows, **Device Manager → DVD/CD-ROM drives** — the
  model string printed there usually matches the `INQUIRY` product field.

Once you have vendor + model + firmware revision, check it against the base images in the
firmware index (see the [Firmware → Find](https://freemkv.org/firmware/) page) before building.

## Command reference

Every `freemkv-fw` command is a **hijack of the standard SCSI `READ BUFFER` (`0x3C`)** command,
discriminated by an OEM-unused mode byte plus a 2-byte knock. `READ BUFFER` is used because it's
a standard opcode that USB/UAS bridges pass through unmodified (a bare vendor opcode gets
rejected by the bridge), and it returns data through an existing transfer path. freemkv claims
an OEM-unused mode byte and hands every other mode straight back to the stock handler, so normal
`READ BUFFER` behavior stays byte-identical until the knock arrives.

The full discriminator is the 4-byte prefix **`3C 0E C0 DE`**: standard opcode + OEM-unused mode
+ knock. There is no separate vendor opcode and no persistent mode — control rides one command
every optical drive already answers, and the drive stays **100% OEM** until that exact prefix
shows up.

`freemkv-fw create` wires these features into the firmware image it builds, and
`freemkv-fw verify /dev/…` sends the **Identity** command to test a live drive.

### Grammar: `verb [feature] [state]`

The command surface is a small set of **verbs** operating on a flat namespace of **features**,
each holding a **state**. A verb (`SET`, `GET`, `RESET`, `SAVE`, `IDENTITY`, `DUMPALL`) says what
to do; a feature (Speed, Region, Unrestricted, …) says which subsystem; a state says how to set it. Every
feature has an **OEM** state — the firmware does not touch that subsystem, so a drive left at OEM
is byte-behaviour-identical to stock. Settings live in **RAM** and are lost on power-off unless
you **SAVE** them to flash; on boot the firmware restores the saved config, or falls back to the
baked defaults (`Unrestricted` armed, everything else OEM) if nothing was saved. **RESET** reloads
that state — back to the last saved config (`--to flash`), to the baked defaults (mode `01`), or all
the way to OEM (`--to oem`, which also blanks the saved config). Features are **orthogonal**: the familiar
"modes" are just combinations (see [Composing features](#composing-features) below).

### CDB layout

```
byte:  0     1     2  3     4      5          6        7   8       9
       0x3C  0x0E  C0 DE    <verb> <feature>  <state>  <alloc_len 16-bit BE>  <ctrl>
```

| Field | Bytes | Offset | Meaning |
|---|---|---|---|
| Opcode | 1 | `cdb[0]` | `0x3C` — `READ BUFFER`, the command freemkv hijacks |
| Knock mode | 1 | `cdb[1]` | `0x0E` — an OEM-unused `READ BUFFER` mode |
| Knock | 2 | `cdb[2..4]` | `C0 DE`; a defence-in-depth signature behind the mode byte |
| Verb | 1 | `cdb[4]` | selects the operation — `SET` / `GET` / `RESET` / `SAVE` / `IDENTITY` / `DUMPALL` (see verb table) |
| Feature | 1 | `cdb[5]` | which feature to act on, for `SET` / `GET` (else `00`; see feature table) |
| State | 1 | `cdb[6]` | the state to write, for `SET`; for `RESET` the mode byte (`00` = to saved flash, `01` = to baked defaults, `FF` = to OEM); else `00` |
| Alloc length | 2 | `cdb[7..9]` | 16-bit big-endian allocation length — sizes the data-in transfer for data-returning verbs |
| Control | 1 | `cdb[9]` | `0x00` |

`build_cdb()` (the host-side helper) assembles exactly this 10-byte frame. Without the `3C 0E
C0 DE` prefix, every byte is interpreted by the OEM's normal `READ BUFFER` handler — nothing
about a bare `READ BUFFER` command changes. **DUMPALL** is the one exception to the field layout:
it carries a 32-bit RAM address big-endian in `cdb[5..9]` (no feature / state / alloc-length).

### Verb table (`cdb[4]`)

| CDB prefix | Verb | Value | Meaning | Status |
|---|---|---|---|---|
| `3C 0E C0 DE 01` | Identity | `0x01` | Status / ping — returns the `freemkv` magic, version, and current feature-state table | ready |
| `3C 0E C0 DE 02 <feat> <state>` | Set | `0x02` | Set one feature to a state (RAM only) | ready |
| `3C 0E C0 DE 03 <feat>` | Get | `0x03` | Read one feature's current state back in the data-in | ready |
| `3C 0E C0 DE 04 00 <mode>` | Reset | `0x04` | Reload the live state — `cdb[6]` mode `00` = to saved flash config (RAM only), `01` = to the baked defaults a never-saved drive boots to (RAM only), `FF` = to true OEM (RAM **and** blanks the saved flash config) | ready |
| `3C 0E C0 DE 0B` | Save | `0x0B` | Persist the current (live) feature-state table to flash | ready |
| `3C 0E C0 DE 09 <addr32>` | DumpAll | `0x09` | Diagnostic 64-byte RAM peek at a 32-bit address | ready (diagnostic use) |

### Feature table (`cdb[5]`, for `SET` / `GET`)

Each feature is an independent state byte in the firmware's flag table. Every feature reserves
one universal code — `FF` = **OEM** (do exactly what the stock drive does) — and defines its own
values on top. Two shapes result: **toggles** (`FF` OEM / `00` / `01`) and **valued** features
(Speed and Region, which take a range).

| Feature | Value | States | Status |
|---|---|---|---|
| Speed | `0x01` | `FF` = OEM ramp · `00` = off = max / uncapped · `01`–`FE` = explicit speed cap | ready |
| Region | `0x02` | `FF` = OEM region logic · `00` = locked (nothing plays) · `01`–`08` = force DVD region 1–8 · `0A`/`0B`/`0C` = force BD region A/B/C · `0F` = region-free | ready |
| Unrestricted | `0x03` | `FF` (`STATE_PASSTHROUGH`) = replay OEM · `00` (`STATE_OFF`) = replay OEM, drive refuses non-`0xC*` states · `01` (`STATE_ON`) = widen, accept BD + UHD + the extended auth-cell nibble set | ready |
| BD | `0x04` | **Deprecated (0.9.2).** `FF` = OEM · `00`/`01` still round-trip via SET/GET but have no runtime effect — use Unrestricted | deprecated |
| HRL | `0x05` | `FF` = OEM enforce · `00` = off, skip the revocation lookup (accept revoked, non-destructive) · `01` = on, enforce | ready |
| Encryption | `0x06` | `FF` = OEM real handshake · `00` = off, null/bypass (drive acts pre-authenticated, no handshake, content reads back de-bussed) · `01` = on, require the real handshake | ready |

> **Note: Feature::Uhd renamed to Feature::Unrestricted (0.9.2)**
>
> `0x03` kept its **numeric discriminant** — the wire byte is unchanged, and existing hosts built
> against the old `Uhd` name keep interoperating without any change. Only the name changed, to
> document what the flag actually controls as of 0.9.2: one lever for all AACS media acceptance
> (BD, UHD, *and* the auth-cell state-band gate below) rather than just the UHD arm. `Feature::Bd`
> (`0x04`) is preserved for backward compatibility — `SET`/`GET` still round-trip through its own NV
> slot — but is marked deprecated and has no runtime effect; new hosts should drive `Unrestricted`
> instead.

> **Note: AKE and Bus consolidated into Encryption (0.9.0)**
>
> The pre-0.9.0 model exposed two separate levers — `AKE` (`0x06`) and `Bus` (`0x07`). Since 0.9.0
> they are **one feature, `Encryption` (`0x06`)**: hardware on the BU40N/MT1959 proved that toggling
> the handshake alone de-busses content reads, so the two were never independent datapath levers.
> `FF` = OEM real handshake; `00` = off (null/bypass — the drive acts pre-authenticated, performs no
> handshake, and content reads back de-bussed); `01` = require the real handshake. Wire id `0x07` is
> **retired** (it was `Bus`, proved inert).

**State conventions.** Every feature reserves **OEM** (`0xFF`) — the firmware jumps to the stock
drive code, so that subsystem behaves exactly as shipped. Beyond that each feature has its own
value domain. For the **toggle** features the two poles differ in meaning:

- **Unrestricted** (and, historically, **BD**, now deprecated) answers "does this drive accept
  this disc type?" — `00` (`STATE_OFF`) = **No** (refuse — replays OEM), `01` (`STATE_ON`) =
  **Yes** (widen — accept), `FF` (`STATE_PASSTHROUGH`) = **OEM** (replay OEM, byte-identical to an
  unmodified drive). `00` and `FF` both replay OEM behavior; only `01` arms the widen.
- **HRL / Encryption** are unlock switches where `00` is the **unlock** direction — `00` = **off**
  (skip revocation / bypass the encryption handshake so content reads back de-bussed), `01` = **on**
  (enforce), `FF` = **OEM**.

> **Note: Auth-cell state-band widen (new in 0.9.2)**
>
> On BU40N 1.00, arming `Unrestricted` also hooks the OEM auth-cell gate at `0x00136826`
> (`cmp (state>>4),#0xC; bne <6F/02>`) and widens the accepted top-nibble set, so discs whose
> classifier lands the state byte outside the usual `0xC*` band (observed: `0xE8` on a triple-layer
> UHD) are no longer silently refused with `0x30/0x02 Incompatible medium installed`. It shares the
> same lever and the same tri-state semantics as the BD/UHD acceptance gate — there's no separate
> CDB feature code for it. `CreateReport` exposes `auth_cell_site` / `auth_cell_stub_va`, which read
> zero on hardware where the anchor shape doesn't exist (e.g. MT1939 classic). A freshly flashed
> drive with virgin NV boots with `Unrestricted = STATE_ON` — the widen is armed out of the box,
> unlike every other feature, which boots at OEM until explicitly saved.

The **valued** features carry a range: **Speed** (`00` = max/uncapped, `01`–`FE` = a specific
speed cap) and **Region** (`00` = locked, `01`–`08` = DVD 1–8, `0A`–`0C` = BD A/B/C, `0F` =
region-free). A freshly flashed, never-saved drive boots with every feature at **OEM** except
`Unrestricted` (see above); boot otherwise restores whatever config was last **saved**. That
OEM-compatibility guarantee is the point of the design.

#### Default unlock profile

The `freemkv-unlock` host tool applies this profile for a normal rip — the common "just unlock
everything" combination. The firmware supports **any** mix of feature values; this is simply the
default the tool arms:

| Feature | Setting | State |
|---|---|---|
| Speed | max (uncapped) | `0x00` |
| Region | region-free | `0x0F` |
| Unrestricted | yes (widen — accept BD + UHD) | `0x01` |
| HRL | off (skip revocation) | `0x00` |
| Encryption | off (bypass handshake, de-bussed) | `0x00` |

`BD` (`0x04`) is deprecated as of 0.9.2 and no longer part of this profile — `Unrestricted` covers
both BD and UHD acceptance.

#### What each verb and feature does

- **Identity (`0x01`, read-only).** Returns the ASCII `freemkv` magic, a firmware version byte,
  and the current feature-state table. Send it first, and only treat a drive as freemkv-flashed
  if it answers with the magic. Changes nothing.
- **Set (`0x02`) / Get (`0x03`).** `SET` writes `cdb[6]` (state) into the feature named in
  `cdb[5]`; `GET` reads that feature's current state back as a 1-byte data-in. Both act on exactly
  one feature, and `SET` touches **RAM only** — the change is lost on power-off unless you `SAVE`.
- **Reset (`0x04`).** Reloads the live RAM state without reflashing — `--to flash` (`cdb[6]` =
  `00`) restores the last **saved** config and `cdb[6]` = `01` restores the baked defaults; both
  are RAM only. `--to oem` (`cdb[6]` = `FF`) returns every feature to OEM **and** blanks the saved
  flash config in one step, so no `SAVE` is needed — the drive is left exactly like a never-saved
  one.
- **Save (`0x0B`).** Persists the current live feature-state table to flash (the only other
  command that writes flash is `RESET --to oem`). Saved settings survive a power-cycle and are
  restored on the next boot; a drive that has never saved boots to the baked defaults.
- **Speed.** Read-speed / riplock ceiling. `FF` (OEM) = the OEM speed ramp; `00` (off) = speed
  control off, so the drive reads at max / uncapped; `01`–`FE` set an explicit speed cap. Use max
  to lift the playback-speed riplock so discs read back at the drive's full rate for ripping.
- **Region.** RPC control across DVD **and** Blu-ray. `FF` (OEM) keeps the drive's own region
  logic; `00` locks the drive (nothing plays); `01`–`08` pin the drive to DVD region 1–8;
  `0A` / `0B` / `0C` pin it to BD region A / B / C; `0F` makes it region-free (RPC-1, with none of
  retail's ~5-change limit).
- **Unrestricted** (`0x03`, renamed from `Uhd` in 0.9.2 — same wire byte). One AACS media-acceptance
  gate for BD (AACS 1.0), UHD (AACS 2.0), and, on hardware where the anchor exists, the auth-cell
  state-band gate at `0x00136826`. `FF` (`STATE_PASSTHROUGH`) and `00` (`STATE_OFF`) both replay
  OEM behavior (refuse non-`0xC*` states); `01` (`STATE_ON`, "widen") accepts BD, UHD, and the
  extended top-nibble set. (In scope only on UHD/BD-capable hardware; the auth-cell hook is
  additionally gated on BU40N 1.00's anchor shape — `auth_cell_stub_va` reads `0` where it doesn't
  apply.) A fresh flash with virgin NV boots with this feature **already at `STATE_ON`** — widen
  is the baked-in default.
- **BD** (`0x04`, **deprecated since 0.9.2**). The old Blu-ray-only (AACS 1.0) capability gate.
  `SET`/`GET` still round-trip through its own NV slot for legacy hosts, but the value has **no
  runtime effect** — the drive's BD acceptance is driven entirely by `Unrestricted` now. New hosts
  should not arm this feature; use `Unrestricted` instead.
- **HRL.** Host-certificate revocation handling on the cert path. `FF` (OEM) = enforce; `00` (off)
  is the unlock direction — it skips the revocation lookup so a revoked-but-genuine certificate is
  accepted (non-destructive, reversible); `01` (on) enforces the check.
- **Encryption** (`0x06`, consolidated from `AKE` + `Bus` in 0.9.0). Content encryption / the
  drive↔host AKE handshake, now a single feature — hardware proved that toggling the handshake
  alone de-busses content reads, so the two are one lever. `FF` (OEM) = the real handshake;
  `00` (off) is the unlock direction — the drive acts pre-authenticated, performs no handshake, and
  content reads back de-bussed, so `READ(10)` comes back exactly as it sits on the disc (still
  AACS-encrypted at rest, so the host applies the title keys); `01` (on) requires the real
  handshake. Turning the handshake off also releases the Volume ID (and the other AACS-gated
  values) to a normal `READ DISC STRUCTURE` request, since the gate no longer refuses to emit them.
- **DumpAll (`0x09`, read-only).** Returns a fixed 64-byte window read from the 32-bit address
  packed big-endian across `cdb[5..9]` (`cdb[5]` = address bits 31:24 … `cdb[8]` = address bits
  7:0). The host iterates in 64-byte steps to dump any RAM region. This is a read-only diagnostic
  tool (used by the `fw09_dump` helper script), not a drive-facing capability toggle.

#### Composing features

Features are orthogonal, so the familiar "modes" are just combinations of independent settings:

- **OEM-style rip (real authentication).** `Unrestricted = yes` + `HRL = off (skip)` +
  `Encryption = OEM` — the drive still runs the genuine handshake, but a revoked host certificate is
  accepted.
- **Full bypass.** `Encryption = off (bypass)` (+ `Unrestricted = yes` for a UHD disc) — the drive
  skips the handshake entirely and returns de-bussed sectors.
- **Quality-of-life only.** `Speed = max` and/or `Region = region-free`, with every AACS-path
  feature left at OEM — a faster, region-free drive that is otherwise 100% stock.

### How the firmware is built

freemkv firmware is **not tied to any one OEM image**. Every firmware address a patch needs is
located by **signature at build time** — nothing is hardcoded — so the same builder works across
MediaTek **MT1959** and **MT1939** OEM images, auto-detecting the chipset and applying the
capabilities that drive supports (reported per image). Once the patches are applied, the image's
integrity table is **re-signed with CMAC using the known key** so the drive accepts it, and the
**DE (downgrade-enable) byte is always set** on every build.

**Downgrade-enable — flash over any existing version.** By default a drive refuses to accept an
older firmware than the one it's running (anti-rollback). freemkv sets the DE byte
(`0x1EC056 = 0xDE`) in every image it builds, which flips that gate off — so a freemkv image
installs cleanly **over any existing firmware version**. This is proven on hardware: with the DE
byte set the drive accepts a lower version;
with it cleared the same downgrade is rejected (`ILLEGAL REQUEST / INVALID FIELD IN CDB`) and
nothing is written.

### Response conventions

Responses are **not** uniform — read each verb's response by its own rule:

- **Identity (`0x01`)** returns the ASCII `freemkv` magic, a 1-byte version, and the current
  feature-state table. This is the command to use to confirm you're talking to freemkv-flashed
  firmware.
- **Get (`0x03`)** returns the named feature's current state as a single byte.
- **Set (`0x02`) / Reset (`0x04`) / Save (`0x0B`)** return a 1-byte status (`01` = ok, `00` =
  fail); `Reset` also echoes its mode byte. After a `SET` that turns off the encryption handshake
  (**Encryption** = off), read the released Volume ID with a normal `READ DISC STRUCTURE`
  request — it does not come back in the command's own response.
- **DumpAll (`0x09`)** returns exactly **64 raw bytes** from the requested address.

### Safety

> **Note: Reversible by design**
>
> **Identity (`0x01`), Get (`0x03`) and DumpAll (`0x09`) are read-only and safe** — they report
> a value and change no drive state. Start with `0x01` to confirm the drive is freemkv-flashed.
>
> `SET` is **reversible**: write `OEM` (`FF`) back to a feature, or send `RESET --to oem` to return
> every feature to OEM at once, and the drive is byte-identical to stock again — no reflash
> required. `SET` and `RESET` touch RAM only, except `RESET --to oem`, which also blanks the saved
> config; otherwise nothing is written to flash until you `SAVE`, so a power-cycle reverts to the
> last saved config (the baked defaults, `Unrestricted` armed and everything else OEM, if you never
> saved). Every feature change is
> non-destructive.

### Examples (`sg_raw` on Linux)

The `sg3-utils` package provides `sg_raw`, which sends a raw CDB and prints the bytes read
back. Pass the 10-byte `READ BUFFER` CDB and use `-r <n>` to request enough bytes for the
response; keep the `cdb[7..9]` allocation length consistent with `-r`. The `SET` frame is
`… 02 <feature> <state>`; `GET` is `… 03 <feature>`. Replace `/dev/sg0` with your drive.

Identity probe — expect the response to lead with `freemkv`:

```bash
sg_raw -r 96 /dev/sg0 3C 0E C0 DE 01 00 00 00 60 00   # Identity → "freemkv" + version + state table
```

Speed — unlock to max, or write OEM (`FF`) to hand the subsystem back to the stock ramp:

```bash
sg_raw -r 1 /dev/sg0 3C 0E C0 DE 02 01 00 00 00 00    # SET Speed → max / uncapped
sg_raw -r 1 /dev/sg0 3C 0E C0 DE 02 01 FF 00 00 00    # SET Speed → OEM ramp
```

Region — go region-free, or pin a specific DVD / BD region:

```bash
sg_raw -r 1 /dev/sg0 3C 0E C0 DE 02 02 0F 00 00 00    # SET Region → region-free (RPC-1)
sg_raw -r 1 /dev/sg0 3C 0E C0 DE 02 02 02 00 00 00    # SET Region → force DVD region 2
sg_raw -r 1 /dev/sg0 3C 0E C0 DE 02 02 0B 00 00 00    # SET Region → force BD region B
```

Unrestricted — widen: accept Blu-ray and Ultra HD Blu-ray (AACS 1.0 / 2.0) discs, plus the
extended auth-cell state-band on hardware where that hook exists:

```bash
sg_raw -r 1 /dev/sg0 3C 0E C0 DE 02 03 01 00 00 00    # SET Unrestricted → widen (STATE_ON)
```

An OEM-style rip keeps the real handshake but skips revocation; a full bypass turns the encryption
handshake off entirely so sectors read back de-bussed. For HRL / Encryption, `00` is the unlock
direction (wire id `0x07` is retired):

```bash
sg_raw -r 1 /dev/sg0 3C 0E C0 DE 02 05 00 00 00 00    # SET HRL → off (skip revocation check)
sg_raw -r 1 /dev/sg0 3C 0E C0 DE 02 06 00 00 00 00    # SET Encryption → off (bypass handshake, sectors de-bussed)
```

Read a feature's current state back, persist the live settings, or reload the state:

```bash
sg_raw -r 1 /dev/sg0 3C 0E C0 DE 03 01 00 00 01 00    # GET Speed → 1-byte state
sg_raw -r 1 /dev/sg0 3C 0E C0 DE 0B 00 00 00 01 00    # SAVE → persist live settings to flash
sg_raw -r 1 /dev/sg0 3C 0E C0 DE 04 00 00 00 01 00    # RESET --to flash → reload saved config
sg_raw -r 1 /dev/sg0 3C 0E C0 DE 04 00 01 00 01 00    # RESET mode 01 → reload the baked defaults
sg_raw -r 1 /dev/sg0 3C 0E C0 DE 04 00 FF 00 01 00    # RESET --to oem → every feature to OEM, saved config blanked
```

DumpAll at an address of your choice (`0xAABBCCDD` shown as a placeholder) — expect 64 raw bytes:

```bash
sg_raw -r 64 /dev/sg0 3C 0E C0 DE 09 AA BB CC DD 00   # dump → 64 bytes at 0xAABBCCDD
```

The allocation length lives in `cdb[7..9]` big-endian (two bytes, e.g. `00 60` = 96 bytes for
Identity), with `cdb[9]` the control byte. For `DumpAll` the 32-bit address instead occupies
`cdb[5..9]`.

## See also

- [Firmware](https://freemkv.org/firmware/) — the public Find / Modify / Flash walkthrough
- [Unlocked drives](https://freemkv.org/docs/drives-unlocked/) — which drives freemkv firmware targets
