assimilate nvmutil documentation

hslick-master
Leah Rowe 2022-11-17 11:51:52 +00:00
parent 3ffcc8f093
commit 7034a9b745
8 changed files with 862 additions and 1 deletions

View File

@ -97,3 +97,29 @@ On GM45 laptops with ICH9M southbridge and Intel PHY module, the MAC address
is hardcoded in boot flash, which means it can be changed if you re-flash.
See [ich9utils documentation](../install/ich9utils.md)
If *all* you want to do is change the MAC address, you might try `nvmutil`
instead. See notes below:
Changing the MAC address on ivybridge/sandybridge/haswell (e.g. X230/T440p)
=========================================================
See [nvmutil documentation](../install/nvmutil.md)
This tool was originally written for changing the MAC address on Intel
Sandybridge, Ivybridge and Haswell platforms, but it can be used on any
platform with a valid GbE region in flash, where an Intel Flash Descriptor
is used; this includes older GM45+ICH9M machines supported by Libreboot.
The `ich9utils` program is more useful in an lbmk context, because it
generates an entire Intel Flash Descriptor and GbE region from scratch;
coreboot has a similar method in its build system, using its own utility
called bincfg, but this tool is unused in lbmk.
No tool like ich9utils exists for these boards yet, but lbmk includes the IFD
and GbE files in-tree (Intel ME is handled by extracting from Lenovo updates,
which the build system automatically fetches from the internet).
You can use `nvmutil` to change the existing MAC address in a GbE region. This
sets the "hardcoded" MAC address, typically a globally assigned one set by
the vendor.

View File

@ -3,6 +3,9 @@ title: ich9utils
x-toc-enable: true
...
If all you want to do is change the MAC address, you might use `nvmutil`
instead. See: [nvmutil documentation](../install/nvmutil.md).
Introduction
============

View File

@ -123,6 +123,12 @@ Which systems are supported?
[Refer to the hardware compatibility page](../hardware/)
MAC address on Sandybridge/Ivybridge/Haswell (e.g. X230, X220, T440p)
=====================================================================
You can change the MAC address in flash, on these machines. See:
[nvmutil documentation](nvmutil.md)
MAC address on GM45+ICH9M hardware (ThinkPad X200/R400/T400/T500/W500)
======================================================================
@ -130,7 +136,8 @@ The MAC address is stored in a region of the boot flashed called *GbE NVM*
which is short for *gigabit ethernet non-volatile memory*. Refer to the
following article:
[ich9utils documentation](ich9utils.md)
[ich9utils documentation](ich9utils.md) (you can also use nvmutil, see link
above)
libreboot puts a default MAC address in the available ROM images, but this is
a generic MAC address and it's identical on every ROM image. Technically, you

View File

@ -71,6 +71,9 @@ For example:
./blobutil inject -r x230_libreboot.rom -b x230_12mb -m 00:f6:f0:40:71:fd
NOTE: this makes use of `nvmutil`, which you can read more about in
the [nvmutil documentation](nvmutil.md).
Splitting The Rom
-----------------

View File

@ -0,0 +1,555 @@
---
title: nvmutil: MAC address changer and/or randomiser for IFD/GbE
x-toc-enable: true
...
With this software, you can change the MAC address inside GbE regions
on any system that uses an Intel Flash Descriptor.
This is the reference documentation for `nvmutil`, but an automated script
using nvmutil is available for ivy/sandybridge and haswell hardware, when
inserting blobs, which you can use to change the MAC address. See:
[docs/install/ivy_has_common.md](ivy_has_common.md)
You can use the documentation below, if you wish to use `nvmutil` manually.
Continue reading...
Introduction
============
This is the manual for `nvmutil`, included in the Libreboot,
build system (lbmk) under `util/nvmutil/`. 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.
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`.
How to download newer versions
==============================
Simply pull down the latest changes in `lbmk.git`. The `nvmutil`
software is now part of lbmk, since 17 November 2022.
More info about git:
* <https://git-scm.com/>
Context
=======
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 nvmutil project, is precisely to allow you to change your
MAC address. Many other useful features 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*.
Known compatible PHYs
---------------------
TODO: write a full list her ofe what actual PHYs are known to work.
It's probably all of them, but some 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; it is assumed that intel would later change the
file size and/or checksum value and/or checksum location.
How to obtain the GbE file
==========================
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:
Use flashrom
------------
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:
* <https://flashrom.org/>
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 Libreboot
project has a handy guide for this; it can be used for reading
from and writing to the chip. See:
* <https://libreboot.org/docs/install/spi.html>
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.
Use ifdtool
-----------
NOTE: This has only been tested on systems that use IFDv1
(Intel Flash Descriptor, version 1). This distinction, between
v1 and v2, is made in the `ifdtool` source code, which you
should read if you're interested. Intel`s v2 specification
has more regions in it, whereas v1 systems usually
defined: IFD, GbE, PD, ME and BIOS regions.
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:
* <https://github.com/corna/me_cleaner>
* Also available in `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.
How to compile source code
==========================
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.
As of nvmutil 20220808, OpenBSD `pledge(2)` is used in the code.
This is done with an `ifdef` rule, so that the code still compiles
on other systems. When the `dump` command is specified, pledge
will use these promises: `stdio rpath`. When any other command
is used, these pledge promises will be used: `stdio wpath`.
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.
How to compile it
-----------------
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.
How to use nvmutil
==================
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
Exit status
-----------
The `nvmutil` program uses `errno` extensively. The best error
handling is done this way, the Unix way. Error handling is extremely
strict, in nvmutil; on program exit, the errno message is printed (if not
zero) and the value of errno is returned (upon exit from `int main`).
The `main` function always returns `errno`, no matter what. This style
of programming (set errno and return) is a very old fashioned way of
doing things, and in many cases it is the most *correct* way.
This is why we say `zero status` and `non-zero status` in Unix
programs, when we talk about exit status. Zero is success, and
anything above zero is fail; errno is zero by default, unless
set, and it will always be set to a value above zero (if set).
All commands (except `dump`) require read and write access. The `dump`
command only requires read access on files. Where sufficient permission
is not given (read and/or write), nvmutil will exit with non-zero status.
Non-zero status will also be returned, if the target file is *not*
of size *8KB*.
Additional rules regarding exit status shall apply, depending on
what command you use. Commands are documented in the following sections:
Change MAC address
------------------
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.
On release 20220808 and below, validation merely
checks whether `xx:xx:xx:xx:xx:xx` is given, where each
nibble is a hexademical number. On release 20220810 and above,
the following additional rules are *also enforced*:
* User cannot specify multicast addresses
* User cannot specify `00:00:00:00:00:00`
* When generating random addresses, if the right
most nibble of the left-most byte is `?` (random),
nvmutil will (in code) force the generated MAC
address to be local (not global), and will prevent
a multicast address from being generated.
A multicast address is invalid because it represents
multiple devices; you must specify a unicast address.
A global address is one uniquely assigned by the vendor,
and a local address is an overridden one. You *can* set
global MAC addresses in nvmutil, for example if you are
simply copying what was officially assigned to your NIC,
you can do that. For example, if your MAC address
was `00:de:ad:be:ef:69` as assigned by the manufacturer,
which is a global unicast MAC address, you would type:
nvm gbe.bin setmac 00:de:ad:be:ef:69
How to use (the MAC address in just an example):
nvm gbe.bin setmac 00:de:ad:be:ef:00
You can also set random MAC addresses:
nvm gbe.bin setmac ??:??:??:??:??:??
In this example, every character is random. However, you
can mix and match random characters with static ones. For
example:
nvm gbe.bin setmac 00:1f:16:??:??:??
You can also pass it without a MAC address:
nvm gbe.bin setmac
If you only type `setmac` without specifying a MAC address,
it will do the same thing as `setmac ??:??:??:??:??:??`. This
behaviour is not present in 20220808, but is available in
release 20220810 and above.
This will set the last three bytes randomly, while the
MAC address would begin with `00:1f:16`.
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, nvmutil 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`. It is common for vendor gbe files to contain
one valid part and one invalid part, per checksum rules.
Verify checksums (and show MAC addresses)
-----------------------------------------
This command *only* requires *read* access on files.
The `nvm` program can show a hexdump of both NVM parts, and
tell you whether each one is valid (as per checksum calculation).
It also prints the MAC address from each part.
How to use:
nvm gbe.bin dump
NOTE: This will exit with zero status if at least one part
contains a valid checksum. If both parts are invalid, nvmutil
will exit with non-zero status.
Copy part
---------
This command requires read *and* write access on files.
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: If the part to be copied has a bad checksum, no operation
will be performed, and nvmutil will exit with non-zero status.
Otherwise, it will (if all other conditions are met) exit with
zero status.
Swap parts
----------
This command requires read *and* write access on files.
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.
If *at least one* part is valid, nvmutil will return
with zero exit status. If both parts are invalid, it will
return non-zero.
Set valid checksum
------------------
This command requires read *and* write access on files.
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!*
Set invalid checksum
--------------------
This command requires read *and* write access on files.
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, and nvmutil will exit with non-zero status.
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.
History
=======
The osboot project merged with Libreboot, and `nvmutil` was
imported into the `lbmk` repository. A historical change log
is included at [docs/install/nvmutilimport.md](nvmutilimport.md),
but this simply lists historical changes to nvmutil when it
was part of osboot. Future changes to nvmutil can be found by
running `git log util/nvmutil` in `lbmk.git`. No more changes
to `nvmutilimport.md` will be applied, but future releases of
Libreboot announced in `news/` will mention any nvmutil changes.
The *older* `nvmutils` is still available, for reference. See:
* <https://notabug.org/osboot/nvmutils/>
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`.
Libreboot's version of nvmutil is located at `util/nvmutil` in
the `lbmk.git` repository. The original nvmutil project, when
it was part of osboot, is still available (for reference) here:
* <https://notabug.org/osboot/nvmutil/>
LICENSE
=======
This page is released under different copyright terms than most other pages
on this website.
The `nvmutil` software and documentation are released under the following
terms:
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.

View File

@ -0,0 +1,261 @@
Detailed revision history can be found in the Git repository; for code,
look at `lbmk.git` and for documentation, look at `lbwww.git`.
Assimilation by Libreboot
=========================
With no additional changes to nvmutil, the project became part of lbmk,
which is the Libreboot build system. Please refer to Libreboot's imported
version of the nvmutil documentation: [nvmutil.md](nvmutil.md)
This code and documentation import was performed on November 17th, 2022.
The notes below are for historical purposes, as they show versioned
Change Logs from when nvmutil was part of osboot, but in its own
repository. Post-osboot-libreboot-merge, it was decided that nvmutil
shall now be part of the Libreboot build system proper.
Future changes to nvmutil (in `lbmk.git`) shall be included in regular
Libreboot release announcements, under `news/`, so please be sure to
check that from now on.
For historical and reference purposes, the original nvmutil repository
shall be preserved on notabug. See:
<https://notabug.org/osboot/nvmutil>
nvmutil 20221106
================
Very minor bugfix release:
* Pledge now changed to `stdio rpath` (instead of `stdio wpath`), only
when the `dump` command is used. (pledge is only used on OpenBSD
systems; an ifdef rule prevents its use on other systems)
* Documentation inaccuracies fixed (pertaining to nvmutil exit statuses)
* Documentation generally tidied up a bit
nvmutil 20221103
================
Not much has changed, as this just fixes minor bugs and behavioural
quirks seen in the previous release:
* Prototypes now fully declared, with variable names
* Fix implicit type conversion in readFromFile()
* Always exit with zero status if the file was successfully modified.
Previously, nvmutil would exit non-zero if one of the parts was invalid,
even if the other was OK (and successfully modified)
* Always exit with zero status when running dump, if at least one
part contained a valid checksum and the file is of the correct size,
fully readable. Previously, nvmutil would exit non-zero if one or both
checksums was correct, but it now only does this if both are invalid
nvmutil 20220828
================
No new features have been added. This is a code cleanup and bugfix release.
* General code cleanup (e.g. simpler argument handling)
* Do not print errno 0 (fixes error when using the libc in OpenBSD)
* Improved errno handling
* Endianness portability re-implemented
* The `dump` command no longer warns about multicast MAC addresses
(such a warning is unnecessary, and up to the user to prevent)
* The `setmac` command still prevents multicast MAC addresses being
set, but no longer specifically warns about them (the documentation
says not to use them already. No need to re-implement documentation
in code)
* Bug fix: errno now set, when an invalid file size is detected. The
previous nvmutil version would exit (no operation) when the file size
was wrong, but it would return with zero status. It now returns with
non-zero status
* The compiled binary size is still roughly the same as in the last
release; the endianness checks increase the size, but other optimizations
were made (e.g. cleaner argument handling). Tested with tcc on an x86\_64
machine, where a 0.16% binary size increase was observed.
nvmutil 20220815
================
No new features have been added. This is a code cleanup and bugfix release.
* Further 7% reduction in binary size, compared to the previous release.
This is tested with `tcc` in an x86\_64 machine. On my tests, `tcc`
produces a 10540 byte binary in the previous release; in this release
I got 9796 bytes.
* It should be noted that `nvmmac` from the older nvmutils is 9892 bytes
compiled with `tcc` on my test system; that's with the help/version
output text removed from nvmmac. *This* nvmutil release contains
so many more features and safety checks than just that lone `nvmmac`
utility, yet the `nvmutil` binary is 1% smaller in size! That's how
efficient the `nvmutil` code is, and there is probably room for further
improvement of code efficiency.
* Endianness portability code deleted; it was untested, and still is, so
now nvmutil will detect the host endianness and exit, if the host is
big endian (nearly all hosts these days are little endian, and it's
very unlikely that you will use a big endian host).
(the code will be properly tested and ported to big-endian hosts for the
next release)
* The `status` variable is no longer used; instead, `errno` is used
exclusively and extensively. Error handling is much simpler, and much
more unixy as a result.
* Error messages are more terse
* Fix build issues with clang, from the previous release
* The `dump` command no longer states whether the MAC address is local
or global; this can be easily done by yourself, and this change slightly
reduces code bloat in nvmutil. The code still warns you if the MAC address
is multicast
nvmutil 20220810
================
* 3.4% reduction in binary size (as tested with tcc on x86\_64),
due to code optimizations, *while* adding new checks and new features.
* Random MAC address generation now takes multicast/unicast and
local/global MAC addresses into account. The generator now *forces*
local MAC addresses to be generated; the only way to set a global
address is to set the corresponding nibble statically.
Multicast and all-zero MAC addresses are *no longer permitted* in code.
* The `dump` command now warns when the address is multicast, if set by
another tool or older nvmutil that way (it will also return non-zero
status upon exit). In addition, it will say whether the address is
locally or globally assigned.
* nvmutil now aborts when you try to open a directory
* Even more terse error/feedback messages than in the last release,
while still being friendly and informative
* word/setWord now done in a more efficient, endian-specific way
on x86\_64 platforms; if non-x86\_64, it falls back to the portable
functions
* The code has been simplified in general, and tidied up compared to
the previous release
* The `setmac` command can now be used without specifying a MAC address,
which will cause the same behaviour as `setmac ??:??:??:??:??:??`
nvmutil 20220808
================
Released on 8 August 2022. Changes:
* Vastly reduced binary size (21% reduction); the source line
count has reduced by roughly the same amount (slightly higher
than 21%, because of the extra stuff compilers add).
This is *with* new features and behaviours added; the code
is just that much more efficient, and I've thoroughly audited it.
* OpenBSD `pledge(2)` now used, if available at build time
(ifdef rule used, so it still compiles on Linux/FreeBSD)
* New feature: `setmac` is now able to set *random* MAC addresses.
This is done by reading from `/dev/urandom`. It is done
conditionally, per-nibble, as specified by the user. For example,
you can specify `??:??:??:??:??:??` and every nibble will be
random, or you could set some of them statically. For
example: `00:1f:16:??:4?:?2`
* The `read()` and `pwrite()` functions are now used for reading
and writing files; older nvmutil versions used fopen/fseek/ftell
and so on. The read/write functions are POSIX, and enable
more robust file handling.
* On `showmac` and `dump`, `O_RDONLY` is now set when
executing `read()`. This means that these commands can now be
used on read-only files.
* Makefile: `-Os` flag used, instead of `-O2`
* Error messages and feedback are much more user-friendly,
and useful in general, while being much more terse.
* The returned status on exit is *much* stricter. For example,
the `dump` command will always cause an `EXIT_FAILURE` status
when at least *one* part in the NVM image has a bad checksum.
When writing a new MAC address, it will *work* only on valid
parts like before, but *now* nvmutil will return with `EXIT_FAILURE`
if *one OR* both parts are bad; older nvmutil versions *always*
returned `EXIT_SUCCESS` after modifying the file.
* The `help` and `version` commands have been removed; it is
best to simply read the documentation. Programs should not
include documentation inside themselves, but documentation should
always be supplied separately, alongside that program. This
change alone accounts for roughly 1/3 (33%) of the code size
reduction; the other 2/3 of that reduction is due to increased
code efficiency in general.
Regarding code size reduction
-----------------------------
My test setup is an x86\_64 machine with `tcc` used
as the compiler; the libc doesn't really matter, if
you use dynamic linking. Command:
make CC=tcc
Observations (dynamic linking with libc files):
* 20220808: 10.67KB
* 20220802 (unmodified): 13.51KB
* 20220802 (help/version command removed): 12.56KB
SLOC (source lines of code):
* 20220808: 321 lines
* 20220802 (unmodified): 421 lines
* 20220802 (help/version command removed): 373 lines
These numbers were obtained, using the `sloccount` program
by David A. Wheeler, which you can find here:
* <https://dwheeler.com/sloccount/>
This means that the actual reduction in compiled *logic* is
about 1.89KB, or a 15% reduction, in nvmutil 20220808. By *logic*,
I mean all code excluding the help function; this distinction is
important, because the help/version commands are unavailable in
nvmutil 20220808, but they were available in nvmutil 20220802.
Extra note: I also tested compressed sizes. With `tar` piped to `xz -9e`,
I saw: about 3KB if compiled with tcc, and 5KB using gcc. Clang
produces binaries of similar size, when compared with GCC.
Since the performance of nvmutil is largely disk-bound, I really
recommend compiling it with `tcc`, not GCC or Clang because the
binary sizes are much larger with those compilers, even with
optimization flags; despite this, the Makefile in nvmutil
assumes GCC/Clang and sets `CFLAGS` to `-Os`.
nvmutil 20220802
================
Released on 2 August 2022. Changes:
* Another major code cleanup
* More reliable argument handling
* Files now loaded *after* verifying arguments
* Files no longer written unless all checks pass
(files were previously written unconditionally, even
if no changes were made, wasting disk i/o)
* Makefile now explicitly declares CFLAGS
(strictest flags possible, warnings treated as errors)
* More secure handling of strings; strnlen used instead
of strlen, strncmp used instead of strcmp, number of
characters limited
* New command added: show mac
(show what mac addresses are stored in both parts)
* More human-friendly messages and help text
* help/version commands actually listed in help output
nvmutil 20220731
================
Released on 31 July 2022. Changes:
* Major code cleanup
* Most operations now abort, if being performed
on invalid files.
* More robust error handling
* More user-friendly error messages
* The `malloc` function is no longer used
That's it. Bug fixes and safety features added. Enjoy!
nvmutil 20220728
================
Initial release. It is functionally equivalent to the
older `nvmutils`, developed for the osboot project. This
newer version is reduced to a single source file instead
of many, and builds as a single binary instead of many.

View File

@ -30,6 +30,9 @@ For example:
./blobutil inject -r t440p_libreboot.rom -b t440p_12mb -m 00:f6:f0:40:71:fd
NOTE: this makes use of `nvmutil`, which you can read more about in
the [nvmutil documentation](nvmutil.md).
Splitting The Rom
-----------------

View File

@ -30,6 +30,9 @@ For example:
./blobutil inject -r x230_libreboot.rom -b x230_12mb -m 00:f6:f0:40:71:fd
NOTE: this makes use of `nvmutil`, which you can read more about in
the [nvmutil documentation](nvmutil.md).
Splitting The Rom
-----------------