This document is aimed at defining the standard way to update the HWID database.
The role of a hardware ID (HWID) configuration file is to verify that every hardware component used in a Chrome device is qualified. The config file mainly lists the phase of the device image_id
, the pattern of the encoded string pattern
, the mapping of bit value to the component encoded_field
, and the probe result of each component component
. For convenience, we call the HWID config file HWID database.
The HWID database has two tasks: (1) verifies the probe result and generates the HWID string when building new devices at the factory, and (2) decodes the HWID string generated by every previous version of the database. To ensure the new database can successfully decode the old HWID string, there are some rules while updating the database.
The first common rule is: do not remove anything. Because we not only need to decode current HWID, but also need to decode EVERY previous valid HWID. Only these items can be modified:
It's obvious that we are not allowed to remove the field in the pattern. Adding a field whose component class is new seems not break the previous HWID, but it actually causes ambiguity. After adding the component in the pattern, we would decode old HWID as index = 0. But actually we have no information about this component in old HWID. There are 3 possible situations:
Most of the case is 1, the old device doesn‘t have the component. But we don’t enforce index 0, which means there is no probed result (or no component) currently. So it is weird to allow this happen. The reasonable way is: the component set in each pattern cannot be modified. It can prevent this ambiguity from happening.
However, we might lean to relax this rule in the early build. The case (2) has a high chance of happening: every old device has the component, but it cannot be probed. Creating a new pattern for adding an extra component seems overkill. In this case we allow appending the pattern directly.
In summary, if we confirm that all the old device has the same kind of the component, then it is allowed to append to the current pattern. Otherwise, please create a new pattern when we need to modify the set of component class.
Because encoded_field
is shared with all patterns, the existed items in the encoded_field
cannot be modified. Otherwise the old HWID cannot lookup the correct mapping. Therefore, if we need to change the mapping of a component, we can only add new field into encoded_fields
.
Because the components items should be encoded in encoded_field
in normal case, we cannot remove them. When we don‘t allow a component in the new unit, use deprecated status. If you don’t even allow to match it, use unsupported status. Please refer Status of a Component Item for more details.
Originally it was tedious to convert the probe result to HWID database. Most of the time we copy and paste it from an existing project and modify the probe value. In addition, there are many implict rules and relations between each section. For example, the number of bits in the field of the pattern should be large enough to contain all items in the encoded field.
Now we have a tool called database builder to generate or update the HWID database. This tool is aimed at covering most of the common and tedious HWID database change, like adding or removing components. But the HWID database still needs to be manually updated in the following scenarios:
Multiple image_ids are active
In the database builder, we assume that only the latest (maximum) image_id
is active. So we recommend not to use the tool if the assumption is not true.
Modify the rules
The rule section gives us much flexibility in assigning and verifying the value of the component. On the other hand, there is no universal diagram for the rule section. We still leave it to user update the rules manually.
Change the status of component items
Because changing the status is quite easy. Just change it :)
# Build the HWID database $ hwid build-database \ --project <project name> \ --output-database-path <output folder> \ --probed-results-file <probed result file> \ [--image-id <IMAGE_ID>] \ # Name of the image_id, default is 'EVT' [--add-default-component COMP [COMP ...]] \ # Add the default item [--add-null-component COMP [COMP ...]] \ # Add the null item [--region REGION [REGION ...]] \ # Add supported regions [--chassis ID1 [ID2 ...]] \ # Add supported chassis # Update the HWID database $ hwid update-database \ --project <project name> \ --output-database-path <output folder> \ [--probed-results-file <probed result file>] \ [--output-database <output file>] \ # Write into different file [--image-id <IMAGE_ID>] \ # Name of the image_id [--add-default-component COMP [COMP ...]] \ # Add the default item [--add-null-component COMP [COMP ...]] \ # Add the null item [--region REGION [REGION ...]] \ # Add supported regions [--chassis ID1 [ID2 ...]] \ # Add supported chassis
Though the database builder handle most of the work, there is still some manual post-processing.
Check the name of component items
The builder will decide a name by the probe result, but it might be meaningless. Please change the name in encoded_fields and components if you don't like it.
Confirm the status of the component items
All component items generated by the database builder are unqualified. After the SIE or TAM confirms the component is qualified at AVL, please change the status to supported.
Below, we will list some common use cases of HWID database change, and provide the recommendation way to do it.
At the beginning of the project, we need to create a new HWID database. The easiest way is using the database builder with a valid probe result. The steps of generating HWID database are:
Here is an example to create a product named GOOGLE
with the phase EVT
, add a default item for battery
component, and add a null item for cellular
component.
# Get the probe result. $ hwid probe --output-file /tmp/probe.json # Create the database at /usr/local/factory/hwid/GOOGLE $ hwid build-database \ --probed-results-file /tmp/probe.json \ --output-database-path /usr/local/factory/hwid \ --project GOOGLE \ --image-id EVT \ --add-default-component battery \ --add-null-component cellular
This is the most common update in HWID database. When we introduce second source or update firmware version, we need to add new supported component item into HWID database. Just append the new item in the component field and check if the encoding bit is enough or not. If we update the firmware version, we should mark the old one as “deprecated” to ensure all DUTs in the factory use the latest firmware.
The command for this scenario is:
# Get the probe result. $ hwid probe --output-file /tmp/probe.json # Update the database at /usr/local/factory/hwid/GOOGLE $ hwid update-database \ --probed-results-file /tmp/probe.json \ --output-database-path /usr/local/factory/hwid \ --project GOOGLE
When we bring up a device, the probing code for some hardware components might not be ready. For example, a device cannot probe cellular in EVT build, and can probe it later. Before the probing code is ready, please add a default item. After the probing code is ready, add the component item and deprecate the default item.
image_id: 0: EVT pattern: - image_ids: [0] encoding_scheme: base8192 fields: - cellular_field: 3 encoded_fields: cellular_field: 0: {cellular: cellular_default} components: cellular: items: cellular_default: status: unqualified value: NULL
image_id: 0: EVT pattern: - image_ids: [0] encoding_scheme: base8192 fields: - cellular_field: 3 encoded_fields: cellular_field: 0: {cellular: cellular_default} 1: {cellular: aa} components: cellular: items: cellular_default: status: unsupported value: NULL aa: value: {compact_str: aa}
The command for this scenario is:
# Add a default item with "--add-default-component" argument $ hwid build-database \ --output-database-path /usr/local/factory/hwid \ --project GOOGLE \ --probed-results-file /tmp/probe.json \ # the probe result without cellular --add-default-component cellular # Update the database by the probed result $ hwid update-database \ --output-database-path /usr/local/factory/hwid \ --project GOOGLE \ --probed-results-file /tmp/probe.json # the probe result with cellular "aa"
When we have a special SKU that does not have a component, please add a null item. For example, we have a SKU with cellular component and another SKU without the cellular component. Then the HWID database should be like:
The command for this scenario is:
# Add a default item with "--add-null-component" argument. $ hwid update-database \ --output-database-path /usr/local/factory/hwid \ --project GOOGLE \ --add-null-component cellular
Deprecating the component item is quite easy. Please manually add “status: deprecated” in the target component item. Then the new unit may not use this component item.
The example below is to deprecate the cellular component item aa
.
When we add new components during the build, we need to create a new pattern
and new image_id
. Please refer Update Rule 2 for more details.
For example, we don‘t have cellular in EVT build, but add cellular in DVT build. To complicate the situation even more, in DVT build we might have one SKU that has cellular and another SKU that doesn’t. In this case, we need to distinguish:
The difference between 1 and 2 is: in EVT build we don‘t check the probed result of the cellular component. The actual meaning should be "we don’t have information about cellular" instead of “this device doesn't have cellular”. To distinguish the case 1 and 2, we need to create a new pattern that adds the new component, while retaining the old pattern which lacks the component.
The HWID database for this example:
image_id: 0: EVT pattern: - image_ids: [0] encoding_scheme: base8192 fields: - cpu_field: 3 encoded_fields: cpu_field: 0: {cpu: cpu_aa} components: cpu: items: cpu_aa: value: {compact_str: cpu_aa}
image_id: 0: EVT 1: DVT pattern: - image_ids: [0] encoding_scheme: base8192 fields: - cpu_field: 3 - image_ids: [1] encoding_scheme: base8192 fields: - cpu_field: 3 - cellular_field: 3 encoded_fields: cpu_field: 0: {cpu: cpu_aa} cellular_field: 0: {cellular: NULL} 1: {cellular: aa} components: cpu: items: cpu_aa: value: {compact_str: cpu_aa} cellular: items: aa: value: {compact_str: aa}
The command for this scenario is:
# Create the database at EVT build $ hwid build-database \ --output-database-path /usr/local/factory/hwid \ --project GOOGLE \ --image-id EVT \ --probed-results-file /tmp/probe.json # the probe result without cellular # Update the database at DVT build. $ hwid update-database \ --output-database-path /usr/local/factory/hwid \ --project GOOGLE \ --image-id DVT \ --add-null-component cellular \ --probed-results-file /tmp/probe.json # the probe result with cellular "aa"
image_id: 0: EVT pattern: - image_ids: [0] encoding_scheme: base8192 fields: - cpu_field: 3 encoded_fields: cpu_field: 0: {cpu: cpu_aa} components: cpu: items: cpu_aa: value: {compact_str: cpu_aa}
image_id: 0: EVT pattern: - image_ids: [0] encoding_scheme: base8192 fields: - cpu_field: 3 - cellular_field: 3 encoded_fields: cpu_field: 0: {cpu: cpu_aa} cellular_field: 0: {cellular: aa} components: cpu: items: cpu_aa: value: {compact_str: cpu_aa} cellular: items: aa: value: {compact_str: aa}
The command for this scenario is:
# Update the database without assigning the image_id. $ hwid update-database \ --output-database-path /usr/local/factory/hwid \ --project GOOGLE \ --probed-results-file /tmp/probe.json # the probe result with cellular "aa" WARNING: Extra fields [cellular_field] without assigning a new image_id. If the fields are added into the current pattern, the index of these fields will be encoded to index 0 for all old HWID string. Enter "y" if you are sure all old devices with old HWID string have the component with index 0. [y/N] y
Please choose “Y” for the question, then the database builder will append the component into the current pattern.
We use magic tag "!region_field"
to generate the region encoded field. There are two styles: legacy and list style. In legacy style, each region has its own index mapping. For example, “us” maps to 29 and “gb” maps to 16. However, in list style, only the listed regions are encoded. In the example below, “us” maps to 1 and “gb” maps to 2.
encoded_fields: # Legacy style old_region_field: !region_field # List style new_region_field: !region_field ['us', 'gb']
Because the update rule, we cannot just replace the legacy style because the encoding mapping is different. If we want to convert legacy style to list style, we should create another encoded_field
and remove the old one from the pattern
. For example:
image_id: 0: EVT pattern: - image_ids: [0] encoding_scheme: base8192 fields: - region_field: 8 encoded_fields: region_field: !region_field components: region: !region_component
image_id: 0: EVT 1: DVT pattern: - image_ids: [0] encoding_scheme: base8192 fields: - region_field: 8 - image_ids: [1] encoding_scheme: base8192 fields: - new_region_field: 5 encoded_fields: region_field: !region_field new_region_field: !region_field ['us'] components: region: !region_component
The database builder will automatically convert the style if the old database uses the legacy style.
image_id
is required when converting.When a component with the attribute probeable: False
, it means one of these:
If a component item has the attribute default: True
, it is a default component item. The feature of the default component item is:
supported
Default status. The component is currently used to build new units.
unqualified
The component is now allowed to be used after PVT phase. The components added by the auto-generator should be unqualified. Then SIE or TAM should remove it after the component is confirmed.
deprecated
The component is no longer being used to build new units, but is supported in RMA process.
unsupported
The component is not allowed to be used to build new units, and is not supported in RMA process. The component cannot be matched. It is used for the wrong component or the equivalent component but with different probed result.