Novatek webcam firmware update

Date: 2014-10-19

This blog post describes Novatek’s firmware update mechanism used by the SoC NT96120 and NT96131 commonly found in USB webcams. I am not aware of any public documentation for both, this update mechanism as well as the chips in general and thus all results presented have been obtained by reverse-engineering firmware update utilities.


The NT96120 powers Microsoft’s Lifecam series, including HD-3000, HD-5000, HD-5001, HD-6000 and Cinema as well as HP’s Webcam 3100 and 3110. Microsoft’s Lifecam Studio uses the chip NT96131.

All webcams listed above support the USB Video Class (UVC) device class, which is essential to the update mechanism.


The webcam’s firmware implements an Extension Unit (XU), a mechanism for vendor-specific, proprietary UVC extensions. Each XU is identified by a unique GUID, which is 29a787c9‑d359-6945‑8467‑ff0849fc19e8 for Novatek’s update XU.

An extension unit exposes controls, each identified by an integer value. They can be used to read (GET_CUR) and write (SET_CUR) a fixed number of bytes (obtained by GET_LEN) from or to the device.

Control 15 and 16 can be used to read data from the device’s flash memory. Writing 01h followed by a 16 bit little endian offset to control 16 modifies the address from which 64 bytes of data can be read with control 15. The first four bytes returned are control information and start with the data previously written to control 16 followed by one byte encoding the length of the following payload (thus returning less than 60 bytes is possible) and the actual data from the flash memory:

struct {
        uint8_t device;
        uint16_t offset;
        uint8_t size;
        char data[];
} payload;

The same payload structure (minus actual data) can be written to control 14, which erases a flash block, whose size seems to be 4096 bytes. Control 9 accepts up to 36 bytes (including control data) and writes the payload’s data to the given offset.

The current firmware version can be retrieved with control 12. It returns four bytes, which encode firmware version and date. For instance 4b070420 is version 2.0, July, 4th 2011:

printf ("%u.%u, %u/%u/%u", data[3] >> 4, data[3] & 0xf, data[1] & 0xf,
                data[2] & 0x1f, data[0] & 0x1f);

The HD-3000 I’m experimenting with provides five additional controls. I don’t know their purpose yet, since they are not mentioned anywhere in Microsoft’s firmware updater. They might be related to factory testing and calibration.

On the other hand Microsoft’s firmware updater mentions controls 21 and 22, control register address and control register data respectively, which do not exist in the HD-3000’s XU. Control 21’s payload format differs from the structure above: It starts with two bytes set to one followed by a 16 bit little endian offset and one byte set to zero. Offset f006h contains the device’s streaming status.


The firmware images for HP and Microsoft cameras extracted from their respective firmware updaters are similar, indicating they share a common codebase with vendor-specific modifications on top.

Microsoft’s firmware updater splits the image into five sections:

Start address End address Checksum address
0000h bfffh 0008h
c000h cfffh cfffh
d000h dfffh dfffh
e000h efffh efffh
f000h ffffh fffbh

The one-byte checksum is literally a sum of all bytes in the region, inverted and one added (two’s complement negation):

uint8_t checksum = 0;
for (size_t i = start; i < end; i++) {
        if (i != checksumAddress) {
                checksum += data[i];
checksum = (~checksum) + 1;

Furthermore two “preserved” regions, cfc0h–cffeh and d800h–d9ffh, are defined. They are copied from the webcam’s flash to a new firmware image before it is written back to the device. It’s possible they are reserved for factory calibration data. However in the firmware image I pulled from a HD-3000 the regions consist of 0’s and ffh’s (respectively) only.

Some of the regions mentioned above overlap with interesting data: Region f000h–ffffh for example contains raw USB and UVC descriptor data. XU and YUX GUID and well as several UTF-16 strings containing vendor and product name are visible. The firmware version returned by XU control 12 is located at b000h.

The first 40 kb of the 64 kb large firmware image seem to be instruction and data section. I have not been able to figure out which processor architecture the SoC uses though.


Novatek’s webcam firmware provides a USB video class extension unit supporting the following controls:

ID Data length Read value Comment
1 5 0000  
2 5 010000  
3 9 000000  
4 9 01000001  
9 36 not supported Firmware download data
11 4 a1000000  
12 4 4b070420 Firmware version
14 5 not supported Erase flash
15 64 data Read flash data
16 5 010000 Read flash address
21 64 unknown Control register address
22 64 unknown Control register data