Newer fork of nvmutils, rewritten as a single C file. This program can modify Intel PHY NVM images for gigabit NICs, e.g. change MAC address, set checksums, etc.
Leah Rowe e52025638e nvmutil 20220731 | 1 year ago | |
---|---|---|
.gitignore | 1 year ago | |
AUTHORS | 1 year ago | |
COPYING | 1 year ago | |
ChangeLog.md | 1 year ago | |
Makefile | 1 year ago | |
README.md | 1 year ago | |
nvmutil.c | 1 year ago |
This is the manual for nvmutil
, version 20220731,
released on 31 July 2022. This program lets you modify
the MAC address, correct/verify/invalidate checksums,
swap/copy and dump regions on Intel PHY NVM images,
which are small binary configuration files that go
in flash, for Gigabit (ethernet) Intel NICs.
To understand the differences between each version
of nvmutil
, please review the ChangeLog.md
file
included in each release.
This software is largely targeted at coreboot users, but it can be used on most modern Intel systems, or most systems from about 2008/2009 onwards.
NOTE: Libreboot X200/X200T/X200S/T400/T400S/T500/W500/R400
users should know that this software does not
replace ich9gen
, because that program generates entire
ICH9M IFD+GbE regions, in addition to letting you set the
MAC address. This program, nvmutil
, can also set
the MAC address on those machines, but it operates on a
single GbE dump that is already created.
This program is operated on dumps of the GbE NVM image,
which normally goes in the boot flash (alongside BIOS/UEFI
or coreboot, IFD and other regions in the flash). The first
half of this README is dedicated to precisely this, telling
you how to dump or otherwise acquire that file; the second
half of this README then tells you how to operate on it,
using nvmutil
.
You can find newer versions of nvmutil
by downloading it
from the official Git repository, like so:
git clone https://notabug.org/osboot/nvmutil
The older nvmutils
is still available, for reference. See:
The nvmutil
software is a clean re-write of nvmutils
,
which is compiled to a single binary instead of multiple
binaries. It contains many fixes and enhancements that
are absent in the original nvmutils
programs. The
old nvmutils
project has been deprecated, and
abandoned. All new development shall now be performed
on nvmutil
.
More info about git:
The nvmutil
software is an official project within osboot:
On many Intel systems with an IFD (Intel Flash Descriptor), the Intel PHY (Gigabit Ethernet) stores its configuration, binary encoded, into a special region of the main boot flash, alongside other flash regions such as: IFD, ME, BIOS.
This includes many configurations, such as your MAC address.
The purpose of nvmmac
, supplied by the nvmutil project, is
precisely to allow you to change your MAC address. Many other
useful programs are also provided.
Intel defines this as the Gigabit Ethernet Non-Volative Memory or just NVM for short. It is a 128-byte section, consisting of 64 words that are 2 bytes, stored in little-endian byte order.
Newer Intel PHYs define an extended area, which starts
immediately after the main one, but the nvmutil
program
does not modify or manipulate these in any way.
The final word in the NVM section is the checksum; all words
must add up, truncated, to the value 0xBABA
. The hardware
itself does not calculate or validate this, and will in
fact work nicely, but software such as Linux will check
that this is correct. If the checksum is invalid, your
kernel will refuse to make use of the NIC.
This NVM section is the first 128 bytes of a 4KB region in flash.
This 4KB region is then repeated, to make an 8KB region in
flash, known as the GbE region. In nvmutil
, the first part
is referred to as part 0 and the second part as part 1.
TODO: write here what actual PHYs are known to work.
It's probably all of them, but som newer ones might have changed the standard by which they are configured. This program actively avoids working on files that have invalid checksums, on most commands, precisely so that the user does not inadvertently use it on incompatible files.
This software is targeted at coreboot users, and users of coreboot distributions such as osboot, but this is a universal tool that is applicable to many Intel platforms, regardless of whether the user has coreboot or not.
You can learn about coreboot and osboot on these websites:
This software can also be used on most Libreboot-compatible ThinkPads (e.g. X200/T400). See:
Coreboot is a free and open source firmware project, which has support for many different kinds of computers. The osboot project provides an easy-to-use automated build system and friendly instructions for installing coreboot, for non-technical users who may otherwise find coreboot quite daunting.
The chip containing your BIOS/UEFI firmware (or coreboot) has it, if you have an Intel PHY for gigabit ethernet.
The sections below will teach you how to obtain the GbE file, containing your NIC's configuration. This is the part that many people will struggle with, so we will dedicated an entire next section to it:
If you wish to operate on the GbE section that's already flashed, you should dump the current full ROM image. If you already have a ROM image, you do not need to dump it, so you can skip this section.
Download flashrom here:
Using recent flashrom versions, you can extract this region. If your regions are unlocked, you can run flashrom on the target system, like so:
flashrom -p internal -r rom.bin
If your system has two flash chips, the GbE region is usually
stored on SPI1 (not SPI2). Otherwise, it may be that you have
a single-flash setup. In that case, it's recommended to dump
both chips, as spi1.rom
and spi2.rom
; you can then cat
them together:
cat spi1.rom spi2.rom > rom.bin
If your GbE region is locked (per IFD settings), you can dump
and flash it using external flashing equipment. The osboot
project has a handy guide for this; it can be used for reading
from and writing to the chip. See:
If you're using an external programmer, the -p internal
option should be changed accordingly. Read flashrom
documentation, and make sure you have everything
properly configured.
The ifdtool
program is a powerful tool, allowing you to
manipulate Intel Flash Descriptors. It's part of coreboot,
available in the coreboot.git
repository
under util/ifdtool/
. Just go in there and build it
with make
, to get an ifdtool binary.
To make internal flashing possible later on, you might do:
ifdtool --unlock rom.bin
Running this command will create a modified image,
named rom.bin.new
. This file will have all regions set
to read-write, per configuration in the Intel Flash Descriptor.
In addition to unlocked regions, you may wish to neuter the
Intel Management Engine, removing all the nasty spying features
from it, using me_cleaner
. See:
coreboot.git
, undir util/
The me_cleaner
program is outside the scope of this
article, so you should read their documentation.
Now run this:
ifdtool -x rom.bin
Several files will be created, and the one you need to
operate on is named flashregion_3_gbe.bin
so please
ensure that you have this file.
Read the notes below about how to use the nvmutil
program,
operating on this file. When you're done, you can insert the
modified GbE file back into your ROM image, like so:
ifdtool -i gbe:flashregion_3_gbe.bin rom.bin
This will create the file rom.bin.new
, which contains
your modified GbE section with the NVM images inside; this
includes your MAC address.
Refer to flashrom documentation. You may flash the new ROM like so, if running on the same system and the regions are read-write:
flashrom -p internal -w rom.bin.new
Newer versions of flashrom support flashing just the specified region, like so:
flashrom -p internal --ifd -i gbe -w rom.bin.new
If you're running flashrom from host CPU on the target
system, and it's dual flash, you can just flash the
concatenated image, which you created earlier by running
the cat
program; dual-IC flash configurations appear to
your operating system as one large flash area, as though
it were a single chip.
If you're using an external programmer, you should change
the -p internal
parameter to something else. In this
situation, you should re-split the file accordingly, if
you have a dual-IC flash set, like so:
dd if=rom.bin.new of=spi2.rom bs=1M skip=8
dd if=rom.bin.new of=spi1.rom bs=1M count=8
These files would then be flashed externally, separately, using an external programmer.
The above example (using dd
) is for setups with 12MB
flash, where you have 8MB as SPI1 and 4MB as SPI2. SPI1
would contain the IFD, and SPI2 is the upper flash area
containing your bootblock; GbE is probably located in
SPI1. You should adjust the above parameters, according
to your configuration.
The nvmutil programs will work just fine, on any BSD operating system, or unix-like system such as GNU+Linux, Chimera Linux or Alpine Linux. You must be sure to have toolchains installed, for building; a normal libc, C compiler and linker should be enough. GCC and LLVM have all these things included, so use whichever one you want.
The nvmutil
software has been build-tested on Clang
, GCC
and tcc
. Only standard library functions (plus err.h
) are
used, so you don't need any extra libraries.
First, ensure that the current working directory is your copy of the nvmutil source code!
You may run this in your terminal:
make
This will result in a binary being created named nvm
.
Install this to wherever you want, such as /usr/bin
(or
whatever is in your $PATH
for userspace programs).
TODO: Add make install
to the Makefile, portably.
You run it, passing as argument the path to a file, and you run commands on that file. This section will tell you how to perform various tasks, by using these commands.
In these examples, it is assumed that you have installed
the nvm
binary to somewhere in your $PATH
. If you haven't
done that, you could still run it in cwd for instance:
./nvm bla bla bla
The nvm
program lets you change the MAC address. It sets
a valid checksum, after changing the MAC address. This program
operates on both NVM parts, but it will only modify a given
part if the existing checksum is correct. It will exit with zero
status if at least one part is modified; otherwise, it will
exit with non-zero status (one).
How to use (the MAC address in just an example):
nvm gbe.bin setmac 00:de:ad:be:ef:00
The reason nvmutil doesn't alter a part with an existing
invalid checksum, is precisely so that if the algorithm
changes in future Intel PHYs, nvmmac will just fail and
not modify your file. This is because the checksum would
then be invalid, at all times. However, correct NVM parts
with otherwise invalid checksums do exist, and can be
corrected if you use the setchecksum
command
in nvmutil
.
The nvm
program can show a hexdump of both NVM parts, and
tell you whether each one is valid (as per checksum calculation).
How to use:
nvm gbe.bin dump
NOTE: This will return EXIT_FAILURE
only if both parts
contain invalid checksums. If at least one part is valid,
it will return EXIT_SUCCESS
.
The nvm
program can copy one NVM part to another. It copies
the entire 4KB part, within the 8KB file.
Overwrite part 0 with the contents of part 1:
nvm gbe.bin copy 1
Overwrite part 1 with the contents of part 0:
nvm gbe.bin copy 0
NOTE: The copy
command will fail if the part being
copied has an invalid checksum. If the checksum is
invalid, you should inspect it in dump
first, and
then run the setchecksum
command if you're happy
with it. This is to guard against accidental usage
of nvmutil
on the wrong file.
The nvm
program can swap both 4KB parts in the GbE
file. It does this, via simple XOR swaps.
How to use:
nvm gbe.bin swap
NOTE: This operation will be aborted if BOTH checksums
are invalid. This is to guard against accidentally
using nvmutil
on the wrong file.
The nvm
program can calculate and sets a valid checksum, on
the desired NVM part. Usage:
Fix part 0:
nvm gbe.bin setchecksum 0
Fix part 1:
nvm gbe.bin setchecksum 1
WARNING: NO validity checks are performed. This will simply set the checksum. There is no feasible way to guard against use on the wrong file, unlike with the other commands. Please make SURE you're running this on the correct file!
The nvm
program can intentionally set an invalid checksum, on
the desired NVM part. Usage:
Invalidate part 0:
nvm gbe.bin brick 0
Invalidate part 1:
nvm gbe.bin brick 1
NOTE: If the part already has an invalid checksum, no operation
will be performed. This is to guard against nvmutil
being
used on the wrong file.
This may be desirable, if you've made modifications to both
parts but you want to guarantee that only one of them is
used. Also, the setmac
command will only operate on
parts that already have a valid checksum, so you could
run brick
before running setmac
(or run it afterwards).
The Linux kernel's e1000
driver will refuse to initialise
Intel gigabit NICs that don't have a valid checksum. This
is software-defined, and not enforced by the hardware.
The nvmutil
software and documentation are released under the following
terms (MIT/Expat license):
Copyright 2022 Leah Rowe
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.