* [PATCH v2 0/5] edison: Convert the image build to binman
@ 2026-06-16 14:24 Simon Glass
2026-06-16 14:24 ` [PATCH v2 1/5] binman: Add an entry type for the Intel OSIP header Simon Glass
` (4 more replies)
0 siblings, 5 replies; 11+ messages in thread
From: Simon Glass @ 2026-06-16 14:24 UTC (permalink / raw)
To: u-boot
Cc: Simon Glass, Alper Nebi Yasak, Andy Shevchenko, Aristo Chen,
Bin Meng, Bryan Brattlof, Heinrich Schuchardt, Ilias Apalodimas,
Marek Vasut, Michal Simek, Neha Malcom Francis, Peng Fan,
Philippe Reynes, Quentin Schulz, Raymond Mao,
Stefan Herbrechtsmeier, Sughosh Ganu, Tom Rini, Wojciech Dubowik,
Yannic Moog
The Intel Edison image is assembled by a board config.mk hack that
prepends a 4KB alignment gap to u-boot.bin, plus a static OSIP-header
blob checked into the tree. This series is a cleanup of that, not a boot
fix: the mainline boot regression from the Kbuild-6.1 bump is fixed
directly by the 'Repair boards broken by the 6.1 kbuild bump' series,
which this one applies on top of.
Assemble the whole image with binman instead. A new intel-osip entry
generates the OSIP header (with the GPT-protective MBR the mask ROM
needs) and a fill provides the 4KB gap that the mask ROM's load/entry
offset requires. The gap and U-Boot are emitted together as
u-boot-edison-dfu.bin, the ready-to-flash payload for the u-boot0
partition, so a DFU update no longer needs a hand-rolled prepend. The
OSIP load address and entry point come from CONFIG_TEXT_BASE rather than
hard-coded magic numbers.
It also widens the DFU auto-probe window so an automated flash has time
to start, adds the board to the sjg-lab CI and rewrites the
documentation to separate a normal DFU update from xFSTK recovery.
Tested on real hardware: a bricked board recovers via xFSTK, takes a
fresh U-Boot over DFU and boots the result.
Changes in v2:
- Drop Bay Trail from the SoC list and add Moorefield (it is not an
Intel MID part)
- Refer to the board as the Intel Edison in the MBR sector comment
- Write the 0x55aa boot signature as a single 16-bit value
- Derive the Edison OSIP load address and entry point from
CONFIG_TEXT_BASE instead of hard-coding them
- Require intel,load-address and intel,entry-point rather than
defaulting to Edison's addresses
- Reframe as a binman conversion (the boot fix is now a precursor) and
drop the duplicate 'Fixes' tag
- Wrap the gap and U-Boot in a section emitted as u-boot-edison-dfu.bin,
the ready-to-flash DFU payload
- Keep a reference to the stock U-Boot v2014.04 the board ships with
- Flash the binman-built u-boot-edison-dfu.bin over DFU instead of
prepending the 4KB gap to u-boot.bin by hand
- Restore the xFSTK progress output and the note that the reconnection
attempts are normal
- Refer to the board as the Intel Edison
Simon Glass (5):
binman: Add an entry type for the Intel OSIP header
edison: Widen the DFU auto-probe window for flashing U-Boot
x86: edison: Move U-Boot alignment into binman
CI: Add an sjg-lab job for the Intel Edison
doc: edison: Rewrite the update instructions
.gitlab-ci.yml | 6 +
arch/x86/dts/edison.dts | 28 +++-
board/intel/edison/config.mk | 10 --
board/intel/edison/edison-environment.txt | 2 +-
board/intel/edison/edison-osip.dat | 0
doc/board/intel/edison.rst | 178 +++++++++-------------
tools/binman/etype/intel_osip.py | 120 +++++++++++++++
tools/binman/ftest.py | 25 +++
tools/binman/test/entry/intel_osip.dts | 17 +++
9 files changed, 266 insertions(+), 120 deletions(-)
delete mode 100644 board/intel/edison/edison-osip.dat
create mode 100644 tools/binman/etype/intel_osip.py
create mode 100644 tools/binman/test/entry/intel_osip.dts
---
base-commit: 7492f24148a31a1d92b1f722996e4882bd7f955a
branch: edison-us2
--
2.43.0
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH v2 1/5] binman: Add an entry type for the Intel OSIP header 2026-06-16 14:24 [PATCH v2 0/5] edison: Convert the image build to binman Simon Glass @ 2026-06-16 14:24 ` Simon Glass 2026-06-17 6:31 ` Andy Shevchenko 2026-06-16 14:24 ` [PATCH v2 2/5] edison: Widen the DFU auto-probe window for flashing U-Boot Simon Glass ` (3 subsequent siblings) 4 siblings, 1 reply; 11+ messages in thread From: Simon Glass @ 2026-06-16 14:24 UTC (permalink / raw) To: u-boot Cc: Simon Glass, Alper Nebi Yasak, Andy Shevchenko, Aristo Chen, Bin Meng, Bryan Brattlof, Marek Vasut, Neha Malcom Francis, Peng Fan, Philippe Reynes, Quentin Schulz, Stefan Herbrechtsmeier, Tom Rini, Wojciech Dubowik, Yannic Moog Intel Atom SoCs (Medfield, Clovertrail, Merrifield and Moorefield) boot via an 'OS Image Profile' (OSIP): a 512-byte '$OS$' header which tells the boot ROM where the OS image lives, where to load it and where to start executing. On the Intel Edison (Merrifield) the OS image is U-Boot. The Edison image embeds this header as the static blob board/intel/edison/edison-osip.dat which is an empty stub in the tree, so a fresh build emits an all-zero, non-functional header. Add an 'intel-osip' entry type which builds the header from devicetree properties, computing the checksum and taking the load address and entry point (both required) plus the logical block address, image size and attribute as parameters. The same sector doubles as the eMMC's protective MBR, which the boot ROM requires before it loads the OS image, so emit a GPT-protective (0xee) partition entry and the 0x55aa signature too. Use it for the Edison image in place of that blob, and remove the now-unused stub file. The Edison node derives the load address and entry point from CONFIG_TEXT_BASE (entry point) and CONFIG_TEXT_BASE - 0x1000 (load address), rather than repeating the magic numbers, since the 0x1000 difference is the mask ROM's load/entry gap. Signed-off-by: Simon Glass <sjg@chromium.org> --- Changes in v2: - Drop Bay Trail from the SoC list and add Moorefield (it is not an Intel MID part) - Refer to the board as the Intel Edison in the MBR sector comment - Write the 0x55aa boot signature as a single 16-bit value - Derive the Edison OSIP load address and entry point from CONFIG_TEXT_BASE instead of hard-coding them - Require intel,load-address and intel,entry-point rather than defaulting to Edison's addresses arch/x86/dts/edison.dts | 7 +- board/intel/edison/edison-osip.dat | 0 tools/binman/etype/intel_osip.py | 120 +++++++++++++++++++++++++ tools/binman/ftest.py | 25 ++++++ tools/binman/test/entry/intel_osip.dts | 17 ++++ 5 files changed, 166 insertions(+), 3 deletions(-) delete mode 100644 board/intel/edison/edison-osip.dat create mode 100644 tools/binman/etype/intel_osip.py create mode 100644 tools/binman/test/entry/intel_osip.dts diff --git a/arch/x86/dts/edison.dts b/arch/x86/dts/edison.dts index 7af8507e456..8fdacfb0fd8 100644 --- a/arch/x86/dts/edison.dts +++ b/arch/x86/dts/edison.dts @@ -171,9 +171,10 @@ u-boot-edison { filename = "u-boot-edison.img"; - /* This is the OSIP */ - blob { - filename = "edison-osip.dat"; + /* OSIP ($OS$) header pointing at the U-Boot image below */ + intel-osip { + intel,entry-point = <CONFIG_TEXT_BASE>; + intel,load-address = <(CONFIG_TEXT_BASE - 0x1000)>; }; u-boot { diff --git a/board/intel/edison/edison-osip.dat b/board/intel/edison/edison-osip.dat deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/tools/binman/etype/intel_osip.py b/tools/binman/etype/intel_osip.py new file mode 100644 index 00000000000..c685a721327 --- /dev/null +++ b/tools/binman/etype/intel_osip.py @@ -0,0 +1,120 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright 2025 Google LLC +# +# Entry-type module for the Intel OS Image Profile (OSIP) header + +"""Entry-type module for an Intel OS Image Profile (OSIP) header + +This generates the 512-byte '$OS$' header used by the boot ROM on Intel Atom +SoCs (Medfield / Clovertrail / Merrifield / Moorefield) to locate and load the +OS image. On the Intel Edison (Merrifield) this OS image is U-Boot. + +The OS image is expected to immediately follow this header, i.e. at offset +0x200 in the containing section. A single OS Image Identifier (OSII) descriptor +is emitted, pointing at that image. +""" + +import struct + +from binman.entry import Entry +from dtoc import fdt_util + +OSIP_SIGNATURE = b'$OS$' +OSIP_SIZE = 0x200 # The header occupies one 512-byte block +HEADER_SIZE = 0x38 # Size of the parsed OSIP header (sig + one OSII) +OSII_OFFSET = 0x20 # First OS Image Identifier descriptor +MBR_OFFSET = 0x1b8 # Start of the protective MBR (disk sig + table) +MBR_PART_OFFSET = 0x1be # First MBR partition entry +BOOT_SIG_OFFSET = 0x1fe # Legacy 0x55aa boot signature +GPT_PROTECTIVE_TYPE = 0xee # MBR partition type for a GPT-protective entry + +# Sector count placed in the protective MBR entry, matching the reference +# Intel Edison images. The on-disk GPT is authoritative, so this is +# informational. +PROTECTIVE_MBR_SECTORS = 0x03a3e000 + +class Entry_intel_osip(Entry): + """Intel OS Image Profile (OSIP) header + + Properties / Entry arguments: + - intel,load-address (int): DDR address to load the OS image to + (required) + - intel,entry-point (int): Execution entry point of the OS image + (required) + - intel,lba (int): Logical block address of the image on the boot + media (default 0x800) + - intel,size-blocks (int): Size of the OS image in 512-byte blocks + (default 0x3000) + - intel,attribute (int): OSII attribute byte (default 0x0f) + + The header checksum is calculated automatically (an XOR over the header + bytes). A GPT protective MBR and the legacy 0x55aa boot signature are + placed in the final bytes of the block, as the boot ROM requires a valid + protective MBR in this sector before it will load the OS image. + """ + def __init__(self, section, etype, node): + super().__init__(section, etype, node) + self.required_props = ['intel,load-address', 'intel,entry-point'] + self.load = fdt_util.GetInt(self._node, 'intel,load-address') + self.entry = fdt_util.GetInt(self._node, 'intel,entry-point') + self.lba = fdt_util.GetInt(self._node, 'intel,lba', 0x800) + self.size_blocks = fdt_util.GetInt(self._node, 'intel,size-blocks', + 0x3000) + self.attribute = fdt_util.GetInt(self._node, 'intel,attribute', 0x0f) + + def _build_header(self): + data = bytearray(b'\xff' * OSIP_SIZE) + + # OSIP header: signature, revisions, checksum, pointer/image counts and + # the header size. The checksum byte is filled in last. + struct.pack_into('<4sBBBBBBH', data, 0, + OSIP_SIGNATURE, # 0x00 '$OS$' + 0, # 0x04 reserved + 0, # 0x05 header minor revision + 1, # 0x06 header major revision + 0, # 0x07 header checksum (see below) + 1, # 0x08 number of pointers + 1, # 0x09 number of images + HEADER_SIZE) # 0x0a header size + # Reserved area between the header and the first OSII descriptor + data[0x0c:OSII_OFFSET] = bytes(OSII_OFFSET - 0x0c) + + # OS Image Identifier (OSII) descriptor describing the OS image + struct.pack_into('<HHIIIIB', data, OSII_OFFSET, + 0, # 0x20 OS minor revision + 0, # 0x22 OS major revision + self.lba, # 0x24 logical start block + self.load, # 0x28 DDR load address + self.entry, # 0x2c entry point + self.size_blocks, # 0x30 size in 512-byte blocks + self.attribute) # 0x34 attribute + data[0x35:HEADER_SIZE] = bytes(HEADER_SIZE - 0x35) # OSII reserved + + # GPT protective MBR. The Edison's x86 mask ROM only boots U-Boot from + # an eMMC whose first sector is a valid protective MBR; this OSIP header + # doubles as that sector. Without the 0xee entry the ROM drops to DnX + # instead of loading U-Boot. The entry covers the disk from LBA 1. + data[MBR_OFFSET:BOOT_SIG_OFFSET] = bytes(BOOT_SIG_OFFSET - MBR_OFFSET) + struct.pack_into('<B3sB3sII', data, MBR_PART_OFFSET, + 0, # boot indicator (inactive) + b'\0\0\0', # start CHS (unused) + GPT_PROTECTIVE_TYPE, # partition type 0xee + b'\0\0\0', # end CHS (unused) + 1, # first LBA (the GPT header) + PROTECTIVE_MBR_SECTORS) # number of sectors + + # Legacy boot signature at the end of the block + struct.pack_into('<H', data, BOOT_SIG_OFFSET, 0xaa55) + + # Header checksum: XOR over the header bytes (checksum byte counted + # as zero, since it is still zero at this point) + checksum = 0 + for byte in data[:HEADER_SIZE]: + checksum ^= byte + data[7] = checksum + + return bytes(data) + + def ObtainContents(self): + self.SetContents(self._build_header()) + return True diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index bf98b268ac1..573bf7698c5 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -2047,6 +2047,31 @@ class TestFunctional(unittest.TestCase): data = self._DoReadFile('entry/fill_empty.dts') self.assertEqual(tools.get_bytes(0, 16), data) + def testIntelOsip(self): + """Test that binman can generate an Intel OSIP header""" + data = self._DoReadFile('entry/intel_osip.dts') + self.assertEqual(0x200, len(data)) + + # '$OS$' signature and the self-cancelling header checksum + self.assertEqual(b'$OS$', data[:4]) + checksum = 0 + for byte in data[:0x38]: + checksum ^= byte + self.assertEqual(0, checksum) + + # The OSII descriptor picks up the devicetree properties + lba, load, entry, blocks = struct.unpack_from('<IIII', data, 0x24) + self.assertEqual(0x1000, lba) + self.assertEqual(0x02200000, load) + self.assertEqual(0x02201000, entry) + self.assertEqual(0x4000, blocks) + self.assertEqual(0x07, data[0x34]) + + # GPT-protective MBR partition entry and the legacy boot signature + self.assertEqual(0xee, data[0x1c2]) + self.assertEqual(1, struct.unpack_from('<I', data, 0x1c6)[0]) + self.assertEqual(b'\x55\xaa', data[0x1fe:0x200]) + def testTextMissing(self): """Test for a text entry type where there is no text""" with self.assertRaises(ValueError) as e: diff --git a/tools/binman/test/entry/intel_osip.dts b/tools/binman/test/entry/intel_osip.dts new file mode 100644 index 00000000000..b13c3f8fae6 --- /dev/null +++ b/tools/binman/test/entry/intel_osip.dts @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0+ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + intel-osip { + intel,load-address = <0x02200000>; + intel,entry-point = <0x02201000>; + intel,lba = <0x1000>; + intel,size-blocks = <0x4000>; + intel,attribute = <0x07>; + }; + }; +}; -- 2.43.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v2 1/5] binman: Add an entry type for the Intel OSIP header 2026-06-16 14:24 ` [PATCH v2 1/5] binman: Add an entry type for the Intel OSIP header Simon Glass @ 2026-06-17 6:31 ` Andy Shevchenko 2026-06-17 6:42 ` Andy Shevchenko 0 siblings, 1 reply; 11+ messages in thread From: Andy Shevchenko @ 2026-06-17 6:31 UTC (permalink / raw) To: Simon Glass Cc: u-boot, Alper Nebi Yasak, Aristo Chen, Bin Meng, Bryan Brattlof, Marek Vasut, Neha Malcom Francis, Peng Fan, Philippe Reynes, Quentin Schulz, Stefan Herbrechtsmeier, Tom Rini, Wojciech Dubowik, Yannic Moog On Tue, Jun 16, 2026 at 08:24:16AM -0600, Simon Glass wrote: > Intel Atom SoCs (Medfield, Clovertrail, Merrifield and Moorefield) boot > via an 'OS Image Profile' (OSIP): a 512-byte '$OS$' header which tells > the boot ROM where the OS image lives, where to load it and where to > start executing. On the Intel Edison (Merrifield) the OS image is > U-Boot. > > The Edison image embeds this header as the static blob > board/intel/edison/edison-osip.dat which is an empty stub in the tree, > so a fresh build emits an all-zero, non-functional header. > > Add an 'intel-osip' entry type which builds the header from devicetree > properties, computing the checksum and taking the load address and entry > point (both required) plus the logical block address, image size and > attribute as parameters. The same sector doubles as the eMMC's > protective MBR, which the boot ROM requires before it loads the OS > image, so emit a GPT-protective (0xee) partition entry and the 0x55aa > signature too. Use it for the Edison image in place of that blob, and > remove the now-unused stub file. > > The Edison node derives the load address and entry point from > CONFIG_TEXT_BASE (entry point) and CONFIG_TEXT_BASE - 0x1000 (load > address), rather than repeating the magic numbers, since the 0x1000 > difference is the mask ROM's load/entry gap. Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> ... > +# Copyright 2025 Google LLC I dunno the source of this, but it's 2026 outside. ... > data = self._DoReadFile('entry/fill_empty.dts') > self.assertEqual(tools.get_bytes(0, 16), data) > Trailing whitespace, a chance to get rid of it. > + def testIntelOsip(self): > + """Test that binman can generate an Intel OSIP header""" > + data = self._DoReadFile('entry/intel_osip.dts') > + self.assertEqual(0x200, len(data)) -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 1/5] binman: Add an entry type for the Intel OSIP header 2026-06-17 6:31 ` Andy Shevchenko @ 2026-06-17 6:42 ` Andy Shevchenko 0 siblings, 0 replies; 11+ messages in thread From: Andy Shevchenko @ 2026-06-17 6:42 UTC (permalink / raw) To: Simon Glass Cc: u-boot, Alper Nebi Yasak, Aristo Chen, Bin Meng, Bryan Brattlof, Marek Vasut, Neha Malcom Francis, Peng Fan, Philippe Reynes, Quentin Schulz, Stefan Herbrechtsmeier, Tom Rini, Wojciech Dubowik, Yannic Moog On Wed, Jun 17, 2026 at 09:31:30AM +0300, Andy Shevchenko wrote: > On Tue, Jun 16, 2026 at 08:24:16AM -0600, Simon Glass wrote: > > Intel Atom SoCs (Medfield, Clovertrail, Merrifield and Moorefield) boot > > via an 'OS Image Profile' (OSIP): a 512-byte '$OS$' header which tells > > the boot ROM where the OS image lives, where to load it and where to > > start executing. On the Intel Edison (Merrifield) the OS image is > > U-Boot. > > > > The Edison image embeds this header as the static blob > > board/intel/edison/edison-osip.dat which is an empty stub in the tree, > > so a fresh build emits an all-zero, non-functional header. > > > > Add an 'intel-osip' entry type which builds the header from devicetree > > properties, computing the checksum and taking the load address and entry > > point (both required) plus the logical block address, image size and > > attribute as parameters. The same sector doubles as the eMMC's > > protective MBR, which the boot ROM requires before it loads the OS > > image, so emit a GPT-protective (0xee) partition entry and the 0x55aa > > signature too. Use it for the Edison image in place of that blob, and > > remove the now-unused stub file. > > > > The Edison node derives the load address and entry point from > > CONFIG_TEXT_BASE (entry point) and CONFIG_TEXT_BASE - 0x1000 (load > > address), rather than repeating the magic numbers, since the 0x1000 > > difference is the mask ROM's load/entry gap. > > Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> While I gave a tag, please check the comment in my reply to patch 5. -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2 2/5] edison: Widen the DFU auto-probe window for flashing U-Boot 2026-06-16 14:24 [PATCH v2 0/5] edison: Convert the image build to binman Simon Glass 2026-06-16 14:24 ` [PATCH v2 1/5] binman: Add an entry type for the Intel OSIP header Simon Glass @ 2026-06-16 14:24 ` Simon Glass 2026-06-16 14:24 ` [PATCH v2 3/5] x86: edison: Move U-Boot alignment into binman Simon Glass ` (2 subsequent siblings) 4 siblings, 0 replies; 11+ messages in thread From: Simon Glass @ 2026-06-16 14:24 UTC (permalink / raw) To: u-boot; +Cc: Simon Glass, Andy Shevchenko, Tom Rini On boot the Edison environment opens a brief DFU window (do_probe_dfu) so a host can reflash U-Boot over USB before the board continues booting. The length of that window is governed by dfu_to_sec, which is 3 seconds. Three seconds is not enough, but not because the transfer is slow. The window is a hard deadline measured from when do_probe_dfu starts: the dfu command records its start time once and never resets it on activity, despite the 'inactivity timeout' wording in the command's help. Sending U-Boot through the lab uses most of the window before the transfer even begins -- the gadget must enumerate, labgrid must detect the resource, sync the image and launch dfu-util over SSH, about 3 seconds of setup. The 700KB transfer itself takes only about 1.3 seconds (including the eMMC write), so the real window usage is roughly 4.4 seconds; a 3-second window expires during the setup, before the write can finish. Raise dfu_to_sec to 8 to cover the setup and transfer with margin. The board waits out this timeout on every boot where no host connects, so there is no benefit in making it longer than necessary. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> --- (no changes since v1) board/intel/edison/edison-environment.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/intel/edison/edison-environment.txt b/board/intel/edison/edison-environment.txt index afe00920461..caa5d773740 100644 --- a/board/intel/edison/edison-environment.txt +++ b/board/intel/edison/edison-environment.txt @@ -43,6 +43,6 @@ bootdelay=1 do_flash_os_done=1 bootargs_target=multi-user bootargs_ethconfig=cdc -dfu_to_sec=3 +dfu_to_sec=8 do_probe_dfu=run do_dfu_alt_info_mmc ; dfu 0 mmc 0 $dfu_to_sec boot_target_cmd=run do_flash_os;run do_probe_dfu;run do_compute_target;run mmc-bootargs;run load_kernel;zboot ${loadaddr} -- 2.43.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2 3/5] x86: edison: Move U-Boot alignment into binman 2026-06-16 14:24 [PATCH v2 0/5] edison: Convert the image build to binman Simon Glass 2026-06-16 14:24 ` [PATCH v2 1/5] binman: Add an entry type for the Intel OSIP header Simon Glass 2026-06-16 14:24 ` [PATCH v2 2/5] edison: Widen the DFU auto-probe window for flashing U-Boot Simon Glass @ 2026-06-16 14:24 ` Simon Glass 2026-06-16 14:24 ` [PATCH v2 4/5] CI: Add an sjg-lab job for the Intel Edison Simon Glass 2026-06-16 14:24 ` [PATCH v2 5/5] doc: edison: Rewrite the update instructions Simon Glass 4 siblings, 0 replies; 11+ messages in thread From: Simon Glass @ 2026-06-16 14:24 UTC (permalink / raw) To: u-boot Cc: Simon Glass, Andy Shevchenko, Bin Meng, Ilias Apalodimas, Sughosh Ganu, Tom Rini The mask ROM loads the OS image to 0x01100000 but enters it at 0x01101000, so U-Boot must sit 0x1000 (4KB) into the loaded image. This is arranged by board/intel/edison/config.mk, which prepends 4096 zero bytes to u-boot.bin through an 'INPUTS-y += u-boot-align.bin' rule whose recipe moves its output back over u-boot.bin. Since the Edison image is assembled by binman, provide the gap there instead: pad with a 'fill' of 4096 zero bytes ahead of the u-boot entry. Wrap the fill and U-Boot in a section that is also written out as u-boot-edison-dfu.bin, the [gap + U-Boot] payload to flash into the u-boot0 partition over DFU, so that no longer needs a manual prepend. Drop the now-redundant alignment hack from the board config.mk. Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Simon Glass <sjg@chromium.org> --- Changes in v2: - Reframe as a binman conversion (the boot fix is now a precursor) and drop the duplicate 'Fixes' tag - Wrap the gap and U-Boot in a section emitted as u-boot-edison-dfu.bin, the ready-to-flash DFU payload arch/x86/dts/edison.dts | 21 +++++++++++++++++++-- board/intel/edison/config.mk | 10 ---------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/arch/x86/dts/edison.dts b/arch/x86/dts/edison.dts index 8fdacfb0fd8..00eb787deb1 100644 --- a/arch/x86/dts/edison.dts +++ b/arch/x86/dts/edison.dts @@ -177,8 +177,25 @@ intel,load-address = <(CONFIG_TEXT_BASE - 0x1000)>; }; - u-boot { - offset = <0x200>; + /* + * The OSII loads the image to (CONFIG_TEXT_BASE - 0x1000) but + * enters it at CONFIG_TEXT_BASE, so U-Boot must sit 0x1000 + * (4KB) into the loaded data. Pad with zeroes ahead of U-Boot + * to provide that gap, and emit the [gap + U-Boot] payload as + * its own file (u-boot-edison-dfu.bin) for flashing into the + * u-boot0 partition over DFU. + */ + u-boot-dfu { + type = "section"; + filename = "u-boot-edison-dfu.bin"; + + fill { + size = <0x1000>; + fill-byte = [00]; + }; + + u-boot { + }; }; u-boot-env { diff --git a/board/intel/edison/config.mk b/board/intel/edison/config.mk index fff187caa15..da7c9acf1a2 100644 --- a/board/intel/edison/config.mk +++ b/board/intel/edison/config.mk @@ -4,14 +4,4 @@ # Copyright (c) 2017 Intel Corporation # -# Add 4096 bytes of zeroes to u-boot.bin -quiet_cmd_mkalign_eds = EDSALGN $@ -cmd_mkalign_eds = \ - dd if=$< of=$@ bs=4k seek=1 2>/dev/null && \ - mv $@ $< - -INPUTS-y += u-boot-align.bin -u-boot-align.bin: u-boot.bin FORCE - $(call if_changed,mkalign_eds) - HOSTCFLAGS_include/autoconf.mk.dep = -Wno-variadic-macros -- 2.43.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2 4/5] CI: Add an sjg-lab job for the Intel Edison 2026-06-16 14:24 [PATCH v2 0/5] edison: Convert the image build to binman Simon Glass ` (2 preceding siblings ...) 2026-06-16 14:24 ` [PATCH v2 3/5] x86: edison: Move U-Boot alignment into binman Simon Glass @ 2026-06-16 14:24 ` Simon Glass 2026-06-17 6:34 ` Andy Shevchenko 2026-06-16 14:24 ` [PATCH v2 5/5] doc: edison: Rewrite the update instructions Simon Glass 4 siblings, 1 reply; 11+ messages in thread From: Simon Glass @ 2026-06-16 14:24 UTC (permalink / raw) To: u-boot Cc: Simon Glass, Heinrich Schuchardt, Michal Simek, Raymond Mao, Tom Rini Add the Intel Edison (Merrifield/Tangier) to the sjg-lab CI matrix. U-Boot is sent over DFU into the board's eMMC u-boot0 partition during U-Boot's brief do_probe_dfu window, and a reset then boots it from there. The lab environment handles the build and the DFU send, so the job only has to name the role. Signed-off-by: Simon Glass <sjg@chromium.org> --- (no changes since v1) .gitlab-ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 245e422d72f..b207a113383 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -797,3 +797,9 @@ qemu-x86_64: ROLE: qemu-x86_64 TEST_PY_TEST_SPEC: "not sleep" <<: *sjg_lab_dfn + +# Intel Edison (Merrifield/Tangier); U-Boot sent over DFU into eMMC u-boot0 +edison: + variables: + ROLE: edison + <<: *sjg_lab_dfn -- 2.43.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v2 4/5] CI: Add an sjg-lab job for the Intel Edison 2026-06-16 14:24 ` [PATCH v2 4/5] CI: Add an sjg-lab job for the Intel Edison Simon Glass @ 2026-06-17 6:34 ` Andy Shevchenko 0 siblings, 0 replies; 11+ messages in thread From: Andy Shevchenko @ 2026-06-17 6:34 UTC (permalink / raw) To: Simon Glass Cc: u-boot, Heinrich Schuchardt, Michal Simek, Raymond Mao, Tom Rini On Tue, Jun 16, 2026 at 08:24:19AM -0600, Simon Glass wrote: > Add the Intel Edison (Merrifield/Tangier) to the sjg-lab CI matrix. > U-Boot is sent over DFU into the board's eMMC u-boot0 partition during > U-Boot's brief do_probe_dfu window, and a reset then boots it from > there. The lab environment handles the build and the DFU send, so the > job only has to name the role. Acked-by: Andy Shevchenko <andriy.shevchenko@intel.com> -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2 5/5] doc: edison: Rewrite the update instructions 2026-06-16 14:24 [PATCH v2 0/5] edison: Convert the image build to binman Simon Glass ` (3 preceding siblings ...) 2026-06-16 14:24 ` [PATCH v2 4/5] CI: Add an sjg-lab job for the Intel Edison Simon Glass @ 2026-06-16 14:24 ` Simon Glass 2026-06-17 6:41 ` Andy Shevchenko 4 siblings, 1 reply; 11+ messages in thread From: Simon Glass @ 2026-06-16 14:24 UTC (permalink / raw) To: u-boot; +Cc: Simon Glass, Tom Rini Split the two ways of getting U-Boot onto the board: a plain DFU transfer into u-boot0 when a working U-Boot is already present, and the xFSTK mask ROM recovery when it is not. Drop the steps that only applied to replacing the original 2014 U-Boot, document the 4KB alignment gap the mask ROM needs and which binman output to flash (rather than the bare u-boot.bin), note that a bricked board enters DnX without any straps, and add udev rules for running the tools without sudo. Signed-off-by: Simon Glass <sjg@chromium.org> --- Changes in v2: - Keep a reference to the stock U-Boot v2014.04 the board ships with - Flash the binman-built u-boot-edison-dfu.bin over DFU instead of prepending the 4KB gap to u-boot.bin by hand - Restore the xFSTK progress output and the note that the reconnection attempts are normal - Refer to the board as the Intel Edison doc/board/intel/edison.rst | 178 +++++++++++++++---------------------- 1 file changed, 74 insertions(+), 104 deletions(-) diff --git a/doc/board/intel/edison.rst b/doc/board/intel/edison.rst index 782d75a6745..9594d4d7721 100644 --- a/doc/board/intel/edison.rst +++ b/doc/board/intel/edison.rst @@ -4,48 +4,77 @@ Edison ====== -Build Instructions for U-Boot as main bootloader ------------------------------------------------- +Building U-Boot +--------------- -Simple you can build U-Boot and obtain u-boot.bin:: +Build U-Boot for the Edison:: $ make edison_defconfig - $ make all + $ make -Updating U-Boot on Edison -------------------------- +This produces ``u-boot.bin`` (the raw U-Boot binary), ``u-boot-edison-dfu.bin`` +(U-Boot with the 4KB alignment gap ahead of it, for flashing over DFU) and +``u-boot-edison.img`` (the full image, with the OSIP header that the mask ROM +expects, used by the xFSTK recovery flow below). -By default Intel Edison boards are shipped with preinstalled heavily -patched U-Boot v2014.04. Though it supports DFU which we may be able to -use. +.. note:: -1. Prepare u-boot.bin as described in chapter above. You still need one - more step (if and only if you have original U-Boot), i.e. run the - following command:: + The mask ROM loads the OS image to 0x01100000 but jumps to 0x01101000, so + U-Boot must sit 4KB into the loaded data. binman provides this gap, padding + with 4KB of zeroes ahead of U-Boot in both ``u-boot-edison-dfu.bin`` and + ``u-boot-edison.img``. The bare ``u-boot.bin`` does not contain the padding, + so flash one of those binman outputs rather than ``u-boot.bin`` itself. - $ truncate -s %4096 u-boot.bin +There are two ways to get U-Boot onto the board: -2. Run your board and interrupt booting to U-Boot console. In the console - call:: +- over DFU, when the board already runs a working U-Boot -- this is the normal + case and needs nothing but ``dfu-util``; +- with the xFSTK downloader, when the board has no usable firmware and has to + be recovered through the mask ROM. - => run do_force_flash_os +Updating U-Boot over DFU +------------------------ -3. Wait for few seconds, it will prepare environment variable and runs - DFU. Run DFU command from the host system:: +Once a working U-Boot is present, updating it is just a DFU transfer into the +``u-boot0`` eMMC partition; the board boots the new U-Boot on the next reset. - $ dfu-util -v -d 8087:0a99 --alt u-boot0 -D u-boot.bin +By default Intel Edison boards ship with a heavily patched stock U-Boot +v2014.04. It also provides DFU, so this same procedure can replace it with an +upstream build. -4. Return to U-Boot console and following hint. i.e. push Ctrl+C, and - reset the board:: +1. Reset the board, interrupt autoboot to reach the U-Boot prompt and start + DFU:: + + => run do_dfu_alt_info_mmc + => dfu 0 mmc 0 + + U-Boot also opens this window automatically for a few seconds during boot + (see ``dfu_to_sec`` and ``do_probe_dfu`` in the environment), so a host can + flash without stopping at the prompt. + +2. From the host, write the binman-built payload to the ``u-boot0`` + partition:: + + $ dfu-util -d 8087:0a99 --alt u-boot0 -D u-boot-edison-dfu.bin + +3. Stop DFU on the board (Ctrl+C) and reset:: => reset -Updating U-Boot using xFSTK ---------------------------- +Recovering a board with xFSTK +----------------------------- -You can also update U-Boot using the xfstk-dldr-solo tool if you can build it. -One way to do that is to follow the `xFSTK`_ instructions. In short, after you -install all necessary dependencies and clone repository, it will look like this: +Use this when the board has no usable U-Boot -- a blank or bricked board, or to +install U-Boot for the first time. It reflashes both the Intel firmware (IFWI) +and U-Boot through the mask ROM, so it needs the Intel Edison recovery image +(the DNX and IFWI blobs) in addition to ``u-boot-edison.img``. + +A board with no valid firmware drops into the mask ROM's DnX download mode (USB +ID 8086:e005) automatically on power-up; no recovery straps are needed for that. +The FM/RM straps only force an otherwise-healthy board into recovery. + +You need the ``xfstk-dldr-solo`` tool. If your distribution does not package it, +build it from the `xFSTK`_ sources: .. code-block:: sh @@ -55,12 +84,12 @@ install all necessary dependencies and clone repository, it will look like this: git checkout v$BUILD_VERSION ... -Once you have built it, you can copy xfstk-dldr-solo to /usr/local/bin and -libboost_program_options.so.1.54.0 to /usr/lib/i386-linux-gnu/ and with luck -it will work. You might find this `drive`_ helpful. +Copy ``xfstk-dldr-solo`` to ``/usr/local/bin`` and +``libboost_program_options.so.1.54.0`` to ``/usr/lib/i386-linux-gnu/``. You +might find this `drive`_ helpful for the recovery image and the libraries. -If it does, then you can download and unpack the Edison recovery image, -install dfu-util, reset your board and flash U-Boot like this: +Download and unpack the Intel Edison recovery image, then, with the board +powered off, run: .. code-block:: sh @@ -70,101 +99,42 @@ install dfu-util, reset your board and flash U-Boot like this: --fwimage recover/edison_ifwi-dbg-00.bin \ --osdnx recover/edison_dnx_osr.bin -This should show the following +and power-cycle the board within about 10 seconds. The tool prints progress +similar to this: .. code-block:: none - XFSTK Downloader Solo 1.8.5 - Copyright (c) 2015 Intel Corporation - Build date and time: Aug 15 2020 15:07:13 - - .Intel SoC Device Detection Found Parsing Commandline.... Registering Status Callback.... .Initiating Download Process.... .......(lots of dots)........XFSTK-STATUS--Reconnecting to device - Attempt #1 .......(even more dots)...................... -You have about 10 seconds after resetting the board to type the above command. -If you want to check if the board is ready, type: +The reconnection attempts are normal and not a sign of trouble. To check that +the board is in download mode, look for the mask ROM: .. code-block:: none - lsusb | grep -E "8087|8086" + $ lsusb | grep -E "8087|8086" Bus 001 Device 004: ID 8086:e005 Intel Corp. -If you see a device with the same ID as above, the board is waiting for your -command. - -After about 5 seconds you should see some console output from the board: +A few seconds after the reset the board prints its PSH boot output, ending with: .. code-block:: none - ****************************** - PSH KERNEL VERSION: b0182b2b - WR: 20104000 - ****************************** - - SCU IPC: 0x800000d0 0xfffce92c - - PSH miaHOB version: TNG.B0.VVBD.0000000c - - microkernel built 11:24:08 Feb 5 2015 - - ******* PSH loader ******* - PCM page cache size = 192 KB - Cache Constraint = 0 Pages - Arming IPC driver .. - Adding page store pool .. - PagestoreAddr(IMR Start Address) = 0x04899000 - pageStoreSize(IMR Size) = 0x00080000 - *** Ready to receive application *** -After another 10 seconds the xFSTK tool completes and the board resets. About -10 seconds after that should see the above message again and then within a few -seconds U-Boot should start on your board: +The tool then flashes the firmware and U-Boot and the board resets. Within a +few seconds U-Boot starts, and once the DFU alt list appears (USB ID 8087:0a99) +the board is ready for the DFU updates described above. -.. code-block:: none - - U-Boot 2020.10-rc3 (Sep 03 2020 - 18:44:28 -0600) - - CPU: Genuine Intel(R) CPU 4000 @ 500MHz - DRAM: 980.6 MiB - WDT: Started with servicing (60s timeout) - MMC: mmc@ff3fc000: 0, mmc@ff3fa000: 1 - Loading Environment from MMC... OK - In: serial - Out: serial - Err: serial - Saving Environment to MMC... Writing to redundant MMC(0)... OK - Saving Environment to MMC... Writing to MMC(0)... OK - Net: No ethernet found. - Hit any key to stop autoboot: 0 - Target:blank - Partitioning using GPT - Writing GPT: success! - Saving Environment to MMC... Writing to redundant MMC(0)... OK - Flashing already done... - 5442816 bytes read in 238 ms (21.8 MiB/s) - Valid Boot Flag - Setup Size = 0x00003c00 - Magic signature found - Using boot protocol version 2.0c - Linux kernel version 3.10.17-poky-edison+ (ferry@kalamata) #1 SMP PREEMPT Mon Jan 11 14:54:18 CET 2016 - Building boot_params at 0x00090000 - Loading bzImage at address 100000 (5427456 bytes) - Magic signature found - Kernel command line: "rootwait ..." - Magic signature found - - Starting kernel ... - - ... +.. note:: - Poky (Yocto Project Reference Distro) 1.7.2 edison ttyMFD2 + To run ``dfu-util`` and ``xfstk-dldr-solo`` without ``sudo``, add udev rules + granting access to the Edison USB IDs, for example:: - edison login: + SUBSYSTEM=="usb", ATTR{idVendor}=="8086", ATTR{idProduct}=="e005", MODE="0666" + SUBSYSTEM=="usb", ATTR{idVendor}=="8087", ATTR{idProduct}=="0a99", MODE="0666" .. _xFSTK: https://github.com/edison-fw/xFSTK .. _drive: https://drive.google.com/drive/u/0/folders/1URPHrOk9-UBsh8hjv-7WwC0W6Fy61uAJ -- 2.43.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v2 5/5] doc: edison: Rewrite the update instructions 2026-06-16 14:24 ` [PATCH v2 5/5] doc: edison: Rewrite the update instructions Simon Glass @ 2026-06-17 6:41 ` Andy Shevchenko 2026-06-17 6:44 ` Andy Shevchenko 0 siblings, 1 reply; 11+ messages in thread From: Andy Shevchenko @ 2026-06-17 6:41 UTC (permalink / raw) To: Simon Glass; +Cc: u-boot, Tom Rini On Tue, Jun 16, 2026 at 08:24:20AM -0600, Simon Glass wrote: > Split the two ways of getting U-Boot onto the board: a plain DFU > transfer into u-boot0 when a working U-Boot is already present, and the > xFSTK mask ROM recovery when it is not. Drop the steps that only applied > to replacing the original 2014 U-Boot, document the 4KB alignment gap > the mask ROM needs and which binman output to flash (rather than the > bare u-boot.bin), note that a bricked board enters DnX without any > straps, and add udev rules for running the tools without sudo. ... > -1. Prepare u-boot.bin as described in chapter above. You still need one > - more step (if and only if you have original U-Boot), i.e. run the > - following command:: > > - $ truncate -s %4096 u-boot.bin Still missing this important detail. The DFU on v2014.04 is broken in a way that it requires also the whole binary to be aligned by 4k. The above pads the tail to full 4k (last block). Btw, now I realised that I haven't checked if this is inherited in your binman case. Note, I haven't put that into the Makefile hack as I expected users to do this once, but perhaps if somebody wants to start over (by flashing the last official image), the file size needs to be aligned. -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 5/5] doc: edison: Rewrite the update instructions 2026-06-17 6:41 ` Andy Shevchenko @ 2026-06-17 6:44 ` Andy Shevchenko 0 siblings, 0 replies; 11+ messages in thread From: Andy Shevchenko @ 2026-06-17 6:44 UTC (permalink / raw) To: Simon Glass; +Cc: u-boot, Tom Rini On Wed, Jun 17, 2026 at 08:41:30AM +0200, Andy Shevchenko wrote: > On Tue, Jun 16, 2026 at 08:24:20AM -0600, Simon Glass wrote: > > Split the two ways of getting U-Boot onto the board: a plain DFU > > transfer into u-boot0 when a working U-Boot is already present, and the > > xFSTK mask ROM recovery when it is not. Drop the steps that only applied > > to replacing the original 2014 U-Boot, document the 4KB alignment gap > > the mask ROM needs and which binman output to flash (rather than the > > bare u-boot.bin), note that a bricked board enters DnX without any > > straps, and add udev rules for running the tools without sudo. ... > > -1. Prepare u-boot.bin as described in chapter above. You still need one > > - more step (if and only if you have original U-Boot), i.e. run the > > - following command:: > > > > - $ truncate -s %4096 u-boot.bin > > Still missing this important detail. The DFU on v2014.04 is broken in a way > that it requires also the whole binary to be aligned by 4k. The above pads > the tail to full 4k (last block). > > Btw, now I realised that I haven't checked if this is inherited in your binman > case. Note, I haven't put that into the Makefile hack as I expected users to > do this once, but perhaps if somebody wants to start over (by flashing the last > official image), the file size needs to be aligned. TL;DR: Either we leave this in documentation, or we always have a bigger blob. However I don't remember how (current) upstream U-Boot DFU will react on the trailing garbage (nulls). -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-06-17 6:44 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-06-16 14:24 [PATCH v2 0/5] edison: Convert the image build to binman Simon Glass 2026-06-16 14:24 ` [PATCH v2 1/5] binman: Add an entry type for the Intel OSIP header Simon Glass 2026-06-17 6:31 ` Andy Shevchenko 2026-06-17 6:42 ` Andy Shevchenko 2026-06-16 14:24 ` [PATCH v2 2/5] edison: Widen the DFU auto-probe window for flashing U-Boot Simon Glass 2026-06-16 14:24 ` [PATCH v2 3/5] x86: edison: Move U-Boot alignment into binman Simon Glass 2026-06-16 14:24 ` [PATCH v2 4/5] CI: Add an sjg-lab job for the Intel Edison Simon Glass 2026-06-17 6:34 ` Andy Shevchenko 2026-06-16 14:24 ` [PATCH v2 5/5] doc: edison: Rewrite the update instructions Simon Glass 2026-06-17 6:41 ` Andy Shevchenko 2026-06-17 6:44 ` Andy Shevchenko
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox