Skip to content

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 turns a base MediaTek firmware image into freemkv firmware, and checks whether a file or a live drive is already freemkv.

Terminal window
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 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.

Terminal window
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.

Terminal window
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.

Terminal window
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 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.

Terminal window
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.

Terminal window
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.

Terminal window
# 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.

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 page) before building.

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.

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).

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).

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)

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). 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.

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.

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.

  • 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.

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.

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.

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.

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:

Terminal window
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:

Terminal window
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:

Terminal window
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:

Terminal window
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):

Terminal window
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:

Terminal window
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:

Terminal window
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].

  • Firmware — the public Find / Modify / Flash walkthrough
  • Unlocked drives — which drives freemkv firmware targets