Add a test for a FIT image with a fake Linux kernel and initrd, and a valid device tree into which a /chosen node is added (containing a bootargs property, as is relevant for Falcon mode boot).
Signed-off-by: Alexey Charkov <[email protected]> --- tools/binman/ftest.py | 107 +++++++++++++++++++++++++ tools/binman/test/fit/fit_chosen.dts | 62 ++++++++++++++ tools/binman/test/fit/fit_chosen_no_initrd.dts | 60 ++++++++++++++ tools/binman/test/fit/fit_chosen_no_load.dts | 57 +++++++++++++ 4 files changed, 286 insertions(+) diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 9553eb6b7366..bc65cb25ef25 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -4397,6 +4397,113 @@ class TestFunctional(unittest.TestCase): self.assertIn("default-dt entry argument 'test-fdt3' not found in fdt list: test-fdt1, test-fdt2", str(e.exception)) + def testFitChosen(self): + """Test patching /chosen (bootargs + initrd) into generated FIT FDTs""" + kernel = b'\x01\x02\x03\x04 kernel' + initrd = b'initramfs-contents' + self._MakeInputFile('test-kernel.bin', kernel) + self._MakeInputFile('test-initrd.bin', initrd) + entry_args = { + 'of-list': 'model1 model2', + 'default-dt': 'model2', + 'linux-kernel-path': 'test-kernel.bin', + 'linux-initrd-path': 'test-initrd.bin', + } + testdir, _ = self.SetupAlternateDts() + data = self._DoReadFileDtb( + 'fit/fit_chosen.dts', use_real_dtb=True, update_dtb=True, + entry_args=entry_args, extra_indirs=[testdir])[0] + fit_data = data[len(U_BOOT_DATA):-len(U_BOOT_NODTB_DATA)] + fit = fdt.Fdt.FromData(fit_data) + fit.Scan() + + # ramdisk is loaded at 0x1000 (see fit_chosen.dts) + rd_start = 0x1000 + rd_end = rd_start + len(initrd) + for seq in (1, 2): + fnode = fit.GetNode('/images/fdt-%d' % seq) + self.assertIsNotNone(fnode) + dtb = fdt.Fdt.FromData(fnode.props['data'].bytes) + dtb.Scan() + chosen = dtb.GetNode('/chosen') + self.assertIsNotNone(chosen) + self.assertEqual(b'console=ttyS0 root=/dev/ram\0', + chosen.props['bootargs'].bytes) + start = int.from_bytes(chosen.props['linux,initrd-start'].bytes, + 'big') + end = int.from_bytes(chosen.props['linux,initrd-end'].bytes, 'big') + self.assertEqual(rd_start, start) + self.assertEqual(rd_end, end) + # The initramfs region must be reserved in the FDT + fdt_obj = dtb.GetFdtObj() + self.assertEqual(1, fdt_obj.num_mem_rsv()) + _, addr, size = fdt_obj.get_mem_rsv(0) + self.assertEqual(rd_start, addr) + self.assertEqual(len(initrd), size) + + def testFitChosenNoInitrd(self): + """Test a Falcon-mode FIT where the optional initramfs is not supplied""" + self._MakeInputFile('test-kernel.bin', b'\x01\x02\x03\x04 kernel') + entry_args = { + 'of-list': 'model1 model2', + 'default-dt': 'model2', + 'linux-kernel-path': 'test-kernel.bin', + 'linux-initrd-path': '', + } + testdir, _ = self.SetupAlternateDts() + with terminal.capture() as (stdout, stderr): + data = self._DoReadFileDtb( + 'fit/fit_chosen_no_initrd.dts', use_real_dtb=True, + update_dtb=True, entry_args=entry_args, + extra_indirs=[testdir], allow_fake_blobs=False)[0] + self.assertRegex( + stderr.getvalue(), + "Image '.*' is missing optional external blobs but is still functional: linux-initrd") + + fit_data = data[len(U_BOOT_DATA):-len(U_BOOT_NODTB_DATA)] + fit = fdt.Fdt.FromData(fit_data) + fit.Scan() + + for seq in (1, 2): + # The node is still emitted and still listed as a loadable, as is + # already the case for an optional OP-TEE which was not supplied + # (see testFitFirmwareLoadables), but it carries no data + cnode = fit.GetNode('/configurations/config-%d' % seq) + self.assertEqual(b'kernel\0', cnode.props['firmware'].bytes) + self.assertEqual(['ramdisk'], + fdt_util.GetStringList(cnode, 'loadables')) + self.assertEqual(b'', fit.GetNode('/images/ramdisk') + .props['data'].bytes) + + # bootargs is still patched in, but the initrd properties are not + fnode = fit.GetNode('/images/fdt-%d' % seq) + dtb = fdt.Fdt.FromData(fnode.props['data'].bytes) + dtb.Scan() + chosen = dtb.GetNode('/chosen') + self.assertEqual(b'console=ttyS0\0', chosen.props['bootargs'].bytes) + self.assertNotIn('linux,initrd-start', chosen.props) + self.assertNotIn('linux,initrd-end', chosen.props) + self.assertEqual(0, dtb.GetFdtObj().num_mem_rsv()) + + def testFitChosenNoLoad(self): + """Test a fit,initrd image which is missing its load address""" + self._MakeInputFile('test-kernel.bin', b'\x01\x02\x03\x04 kernel') + self._MakeInputFile('test-initrd.bin', b'initramfs-contents') + entry_args = { + 'of-list': 'model1 model2', + 'default-dt': 'model2', + 'linux-kernel-path': 'test-kernel.bin', + 'linux-initrd-path': 'test-initrd.bin', + } + testdir, _ = self.SetupAlternateDts() + with self.assertRaises(ValueError) as e: + self._DoReadFileDtb( + 'fit/fit_chosen_no_load.dts', use_real_dtb=True, + update_dtb=True, entry_args=entry_args, + extra_indirs=[testdir]) + self.assertIn("fit,initrd image 'ramdisk' has no 'load' address", + str(e.exception)) + def testFitExtblobMissingHelp(self): """Test display of help messages when an external blob is missing""" control.missing_blob_help = control._ReadMissingBlobHelp() diff --git a/tools/binman/test/fit/fit_chosen.dts b/tools/binman/test/fit/fit_chosen.dts new file mode 100644 index 000000000000..ae2e4a084af6 --- /dev/null +++ b/tools/binman/test/fit/fit_chosen.dts @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + u-boot { + }; + fit { + description = "test-desc"; + #address-cells = <1>; + fit,fdt-list = "of-list"; + + images { + kernel { + description = "Linux kernel"; + type = "kernel"; + arch = "arm64"; + os = "linux"; + compression = "none"; + load = <0x100>; + entry = <0x100>; + linux-kernel { + }; + }; + ramdisk { + description = "ramdisk"; + type = "ramdisk"; + compression = "none"; + load = <0x1000>; + linux-initrd { + }; + }; + @fdt-SEQ { + description = "fdt-NAME.dtb"; + type = "flat_dt"; + compression = "none"; + fit,bootargs = "console=ttyS0 root=/dev/ram"; + fit,initrd = "ramdisk"; + hash { + algo = "sha256"; + }; + }; + }; + + configurations { + default = "@config-DEFAULT-SEQ"; + @config-SEQ { + description = "conf-NAME.dtb"; + firmware = "kernel"; + loadables = "ramdisk"; + fdt = "fdt-SEQ"; + }; + }; + }; + u-boot-nodtb { + }; + }; +}; diff --git a/tools/binman/test/fit/fit_chosen_no_initrd.dts b/tools/binman/test/fit/fit_chosen_no_initrd.dts new file mode 100644 index 000000000000..82468e94dcdb --- /dev/null +++ b/tools/binman/test/fit/fit_chosen_no_initrd.dts @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + u-boot { + }; + fit { + description = "test-desc"; + #address-cells = <1>; + fit,fdt-list = "of-list"; + + images { + kernel { + description = "Linux kernel"; + type = "kernel"; + arch = "arm64"; + os = "linux"; + compression = "none"; + load = <0x100>; + entry = <0x100>; + linux-kernel { + }; + }; + ramdisk { + description = "ramdisk"; + type = "ramdisk"; + compression = "none"; + load = <0x1000>; + linux-initrd { + optional; + }; + }; + @fdt-SEQ { + description = "fdt-NAME.dtb"; + type = "flat_dt"; + compression = "none"; + fit,bootargs = "console=ttyS0"; + fit,initrd = "ramdisk"; + }; + }; + + configurations { + default = "@config-DEFAULT-SEQ"; + @config-SEQ { + description = "conf-NAME.dtb"; + fit,firmware = "kernel", "ramdisk"; + fit,loadables; + fdt = "fdt-SEQ"; + }; + }; + }; + u-boot-nodtb { + }; + }; +}; diff --git a/tools/binman/test/fit/fit_chosen_no_load.dts b/tools/binman/test/fit/fit_chosen_no_load.dts new file mode 100644 index 000000000000..7a3d393dd210 --- /dev/null +++ b/tools/binman/test/fit/fit_chosen_no_load.dts @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + u-boot { + }; + fit { + description = "test-desc"; + #address-cells = <1>; + fit,fdt-list = "of-list"; + + images { + kernel { + description = "Linux kernel"; + type = "kernel"; + arch = "arm64"; + os = "linux"; + compression = "none"; + load = <0x100>; + entry = <0x100>; + linux-kernel { + }; + }; + ramdisk { + description = "ramdisk"; + type = "ramdisk"; + compression = "none"; + linux-initrd { + }; + }; + @fdt-SEQ { + description = "fdt-NAME.dtb"; + type = "flat_dt"; + compression = "none"; + fit,initrd = "ramdisk"; + }; + }; + + configurations { + default = "@config-DEFAULT-SEQ"; + @config-SEQ { + description = "conf-NAME.dtb"; + firmware = "kernel"; + loadables = "ramdisk"; + fdt = "fdt-SEQ"; + }; + }; + }; + u-boot-nodtb { + }; + }; +}; -- 2.54.0
