Firmware tools
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 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
Section titled “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
Section titled “create”freemkv-fw create <input.bin> [output.freemkv.bin] # default output: <input-stem>.freemkv.binfreemkv-fw create <input.bin> --json # machine-readable per-capability reportfreemkv-fw create <input.bin> --audit # verify every applied patch actually landedfreemkv-fw create <input.bin> --in-place # rewrite the input image instead of writing a new filefreemkv-fw create <input.bin> --base # strict base build: all-or-nothing, refuses without a full freemkv baseTakes 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 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 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
Section titled “verify”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.
freemkv-fw info <device> # print the drive's freemkv identityfreemkv-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 imageProbes 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.
freemkv-fw sign <image.bin> [-o <out.bin>] [--in-place] # default output: <stem>.signed.binRecomputes 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
Section titled “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.
freemkv-flash info <device> # identify a live drivefreemkv-flash info <image.bin> # classify a firmware fileinfo 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.
freemkv-flash dump <device> [-o backup.tar] # default output: <product>_<revision>.dump.tarReads the drive’s current firmware to a file. Always dump and keep a backup before flashing anything.
# 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.
How do I tell what drive I have?
Section titled “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 itsINQUIRYdata.- Linux,
lsscsi— lists attached SCSI/ATAPI devices, including the vendor and model string, without touching the drive. - Linux,
sg_inq <device>(fromsg3-utils) — issues a standardINQUIRYdirectly and prints the same vendor/product/revision fieldsfreemkv-flash inforeads. - The label on the drive itself, or on Windows, Device Manager → DVD/CD-ROM drives — the
model string printed there usually matches the
INQUIRYproduct field.
Once you have vendor + model + firmware revision, check it against the base images in the firmware index (see the Firmware → Find page) before building.
Command reference
Section titled “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]
Section titled “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 below).
CDB layout
Section titled “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])
Section titled “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)
Section titled “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 |
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).00andFFboth replay OEM behavior; only01arms the widen. - HRL / Encryption are unlock switches where
00is the unlock direction —00= off (skip revocation / bypass the encryption handshake so content reads back de-bussed),01= on (enforce),FF= OEM.
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
Section titled “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
Section titled “What each verb and feature does”- Identity (
0x01, read-only). Returns the ASCIIfreemkvmagic, 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).SETwritescdb[6](state) into the feature named incdb[5];GETreads that feature’s current state back as a 1-byte data-in. Both act on exactly one feature, andSETtouches RAM only — the change is lost on power-off unless youSAVE. - Reset (
0x04). Reloads the live RAM state without reflashing —--to flash(cdb[6]=00) restores the last saved config andcdb[6]=01restores 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 noSAVEis 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 isRESET --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–FEset 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;00locks the drive (nothing plays);01–08pin the drive to DVD region 1–8;0A/0B/0Cpin it to BD region A / B / C;0Fmakes it region-free (RPC-1, with none of retail’s ~5-change limit). - Unrestricted (
0x03, renamed fromUhdin 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 at0x00136826.FF(STATE_PASSTHROUGH) and00(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_vareads0where it doesn’t apply.) A fresh flash with virgin NV boots with this feature already atSTATE_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/GETstill 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 byUnrestrictednow. New hosts should not arm this feature; useUnrestrictedinstead. - 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 fromAKE+Busin 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, soREAD(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 normalREAD DISC STRUCTURErequest, 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 acrosscdb[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 thefw09_dumphelper script), not a drive-facing capability toggle.
Composing features
Section titled “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 = yesfor a UHD disc) — the drive skips the handshake entirely and returns de-bussed sectors. - Quality-of-life only.
Speed = maxand/orRegion = 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
Section titled “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
Section titled “Response conventions”Responses are not uniform — read each verb’s response by its own rule:
- Identity (
0x01) returns the ASCIIfreemkvmagic, 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);Resetalso echoes its mode byte. After aSETthat turns off the encryption handshake (Encryption = off), read the released Volume ID with a normalREAD DISC STRUCTURErequest — it does not come back in the command’s own response. - DumpAll (
0x09) returns exactly 64 raw bytes from the requested address.
Safety
Section titled “Safety”Examples (sg_raw on Linux)
Section titled “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:
sg_raw -r 96 /dev/sg0 3C 0E C0 DE 01 00 00 00 60 00 # Identity → "freemkv" + version + state tableSpeed — unlock to max, or write OEM (FF) to hand the subsystem back to the stock ramp:
sg_raw -r 1 /dev/sg0 3C 0E C0 DE 02 01 00 00 00 00 # SET Speed → max / uncappedsg_raw -r 1 /dev/sg0 3C 0E C0 DE 02 01 FF 00 00 00 # SET Speed → OEM rampRegion — go region-free, or pin a specific DVD / BD region:
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 2sg_raw -r 1 /dev/sg0 3C 0E C0 DE 02 02 0B 00 00 00 # SET Region → force BD region BUnrestricted — 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:
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):
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:
sg_raw -r 1 /dev/sg0 3C 0E C0 DE 03 01 00 00 01 00 # GET Speed → 1-byte statesg_raw -r 1 /dev/sg0 3C 0E C0 DE 0B 00 00 00 01 00 # SAVE → persist live settings to flashsg_raw -r 1 /dev/sg0 3C 0E C0 DE 04 00 00 00 01 00 # RESET --to flash → reload saved configsg_raw -r 1 /dev/sg0 3C 0E C0 DE 04 00 01 00 01 00 # RESET mode 01 → reload the baked defaultssg_raw -r 1 /dev/sg0 3C 0E C0 DE 04 00 FF 00 01 00 # RESET --to oem → every feature to OEM, saved config blankedDumpAll at an address of your choice (0xAABBCCDD shown as a placeholder) — expect 64 raw bytes:
sg_raw -r 64 /dev/sg0 3C 0E C0 DE 09 AA BB CC DD 00 # dump → 64 bytes at 0xAABBCCDDThe 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
Section titled “See also”- Firmware — the public Find / Modify / Flash walkthrough
- Unlocked drives — which drives freemkv firmware targets