1import os
2
3import infra.basetest
4
5BASIC_CONFIG = \
6    """
7    BR2_x86_pentium4=y
8    BR2_TOOLCHAIN_EXTERNAL=y
9    BR2_TOOLCHAIN_EXTERNAL_CUSTOM=y
10    BR2_TOOLCHAIN_EXTERNAL_DOWNLOAD=y
11    BR2_TOOLCHAIN_EXTERNAL_URL="http://autobuild.buildroot.org/toolchains/tarballs/br-i386-pentium4-full-2017.05-1078-g95b1dae.tar.bz2"
12    BR2_TOOLCHAIN_EXTERNAL_GCC_6=y
13    BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_2=y
14    BR2_TOOLCHAIN_EXTERNAL_LOCALE=y
15    # BR2_TOOLCHAIN_EXTERNAL_HAS_THREADS_DEBUG is not set
16    BR2_TOOLCHAIN_EXTERNAL_CXX=y
17    BR2_TARGET_GENERIC_GETTY_PORT="ttyS0"
18    BR2_TARGET_GENERIC_GETTY_BAUDRATE_115200=y
19    BR2_LINUX_KERNEL=y
20    BR2_LINUX_KERNEL_CUSTOM_VERSION=y
21    BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="4.19.204"
22    BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
23    BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="{}"
24    # BR2_TARGET_ROOTFS_TAR is not set
25    """.format(infra.filepath("conf/minimal-x86-qemu-kernel.config"))
26
27
28def test_mount_internal_external(emulator, builddir, internal=True, efi=False):
29    img = os.path.join(builddir, "images", "rootfs.iso9660")
30    if efi:
31        efi_img = os.path.join(builddir, "images", "OVMF.fd")
32        # In QEMU v5.1.0 up to v7.2.0, the CPU hotplug register block misbehaves.
33        # EDK2 hang if the bug is detected in Qemu after printing errors to IO port 0x402
34        # (requires BR2_TARGET_EDK2_OVMF_DEBUG_ON_SERIAL to see them)
35        # The Docker image used by the Buildroot gitlab-ci uses Qemu 5.2.0, the workaround
36        # can be removed as soon as the Docker image is updated to provided Qemu >= 8.0.0.
37        # This workaround is needed only when efi=True since it imply EDK2 is used.
38        # https://github.com/tianocore/edk2/commit/bf5678b5802685e07583e3c7ec56d883cbdd5da3
39        # http://lists.busybox.net/pipermail/buildroot/2023-July/670825.html
40        qemu_fw_cfg = "name=opt/org.tianocore/X-Cpuhp-Bugcheck-Override,string=yes"
41        emulator.boot(arch="i386", options=["-cdrom", img, "-bios", efi_img, "-fw_cfg", qemu_fw_cfg])
42    else:
43        emulator.boot(arch="i386", options=["-cdrom", img])
44    emulator.login()
45
46    if internal:
47        cmd = "mount | grep 'rootfs on / type rootfs'"
48    else:
49        cmd = "mount | grep '/dev/root on / type iso9660'"
50
51    _, exit_code = emulator.run(cmd)
52    return exit_code
53
54
55def test_touch_file(emulator):
56    _, exit_code = emulator.run("touch test")
57    return exit_code
58
59#
60# Grub 2
61
62
63class TestIso9660Grub2External(infra.basetest.BRTest):
64    config = BASIC_CONFIG + \
65        """
66        BR2_TARGET_ROOTFS_ISO9660=y
67        # BR2_TARGET_ROOTFS_ISO9660_INITRD is not set
68        BR2_TARGET_GRUB2=y
69        BR2_TARGET_GRUB2_BOOT_PARTITION="cd"
70        BR2_TARGET_GRUB2_BUILTIN_MODULES_PC="boot linux ext2 fat part_msdos part_gpt normal biosdisk iso9660"
71        BR2_TARGET_ROOTFS_ISO9660_BOOT_MENU="{}"
72        """.format(infra.filepath("conf/grub2.cfg"))
73
74    def test_run(self):
75        exit_code = test_mount_internal_external(self.emulator,
76                                                 self.builddir, internal=False)
77        self.assertEqual(exit_code, 0)
78
79        exit_code = test_touch_file(self.emulator)
80        self.assertEqual(exit_code, 1)
81
82
83class TestIso9660Grub2ExternalCompress(infra.basetest.BRTest):
84    config = BASIC_CONFIG + \
85        """
86        BR2_TARGET_ROOTFS_ISO9660=y
87        # BR2_TARGET_ROOTFS_ISO9660_INITRD is not set
88        BR2_TARGET_ROOTFS_ISO9660_TRANSPARENT_COMPRESSION=y
89        BR2_TARGET_GRUB2=y
90        BR2_TARGET_GRUB2_BOOT_PARTITION="cd"
91        BR2_TARGET_GRUB2_BUILTIN_MODULES_PC="boot linux ext2 fat part_msdos part_gpt normal biosdisk iso9660"
92        BR2_TARGET_ROOTFS_ISO9660_BOOT_MENU="{}"
93        """.format(infra.filepath("conf/grub2.cfg"))
94
95    def test_run(self):
96        exit_code = test_mount_internal_external(self.emulator,
97                                                 self.builddir, internal=False)
98        self.assertEqual(exit_code, 0)
99
100        exit_code = test_touch_file(self.emulator)
101        self.assertEqual(exit_code, 1)
102
103
104class TestIso9660Grub2Internal(infra.basetest.BRTest):
105    config = BASIC_CONFIG + \
106        """
107        BR2_TARGET_ROOTFS_ISO9660=y
108        BR2_TARGET_ROOTFS_ISO9660_INITRD=y
109        BR2_TARGET_GRUB2=y
110        BR2_TARGET_GRUB2_BOOT_PARTITION="cd"
111        BR2_TARGET_GRUB2_BUILTIN_MODULES_PC="boot linux ext2 fat part_msdos part_gpt normal biosdisk iso9660"
112        BR2_TARGET_ROOTFS_ISO9660_BOOT_MENU="{}"
113        """.format(infra.filepath("conf/grub2.cfg"))
114
115    def test_run(self):
116        exit_code = test_mount_internal_external(self.emulator,
117                                                 self.builddir, internal=True)
118        self.assertEqual(exit_code, 0)
119
120        exit_code = test_touch_file(self.emulator)
121        self.assertEqual(exit_code, 0)
122
123
124class TestIso9660Grub2EFI(infra.basetest.BRTest):
125    config = BASIC_CONFIG + \
126        """
127        BR2_TARGET_ROOTFS_ISO9660=y
128        BR2_TARGET_ROOTFS_ISO9660_INITRD=y
129        BR2_TARGET_GRUB2=y
130        BR2_TARGET_GRUB2_I386_EFI=y
131        BR2_TARGET_GRUB2_BUILTIN_MODULES_EFI="boot linux ext2 fat part_msdos part_gpt normal iso9660"
132        BR2_TARGET_GRUB2_BUILTIN_CONFIG_EFI="{}"
133        BR2_TARGET_ROOTFS_ISO9660_BOOT_MENU="{}"
134        BR2_TARGET_EDK2=y
135        """.format(infra.filepath("conf/grub2-efi.cfg"),
136                   infra.filepath("conf/grub2.cfg"))
137
138    def test_run(self):
139        exit_code = test_mount_internal_external(self.emulator,
140                                                 self.builddir, internal=True,
141                                                 efi=True)
142        self.assertEqual(exit_code, 0)
143
144        exit_code = test_touch_file(self.emulator)
145        self.assertEqual(exit_code, 0)
146
147
148class TestIso9660Grub2Hybrid(infra.basetest.BRTest):
149    config = BASIC_CONFIG + \
150        """
151        BR2_TARGET_ROOTFS_ISO9660=y
152        BR2_TARGET_ROOTFS_ISO9660_INITRD=y
153        BR2_TARGET_GRUB2=y
154        BR2_TARGET_GRUB2_I386_PC=y
155        BR2_TARGET_GRUB2_I386_EFI=y
156        BR2_TARGET_GRUB2_BOOT_PARTITION="cd"
157        BR2_TARGET_GRUB2_BUILTIN_MODULES_PC="boot linux ext2 fat squash4 part_msdos part_gpt normal iso9660 biosdisk"
158        BR2_TARGET_GRUB2_BUILTIN_CONFIG_PC=""
159        BR2_TARGET_GRUB2_BUILTIN_MODULES_EFI="boot linux ext2 fat squash4 part_msdos part_gpt normal iso9660 efi_gop"
160        BR2_TARGET_GRUB2_BUILTIN_CONFIG_EFI="{}"
161        BR2_TARGET_ROOTFS_ISO9660_BOOT_MENU="{}"
162        BR2_TARGET_EDK2=y
163        """.format(infra.filepath("conf/grub2-efi.cfg"),
164                   infra.filepath("conf/grub2.cfg"))
165
166    def test_run(self):
167        exit_code = test_mount_internal_external(self.emulator,
168                                                 self.builddir, internal=True,
169                                                 efi=False)
170        self.assertEqual(exit_code, 0)
171
172        exit_code = test_touch_file(self.emulator)
173        self.assertEqual(exit_code, 0)
174
175        self.emulator.stop()
176
177        exit_code = test_mount_internal_external(self.emulator,
178                                                 self.builddir, internal=True,
179                                                 efi=True)
180        self.assertEqual(exit_code, 0)
181
182        exit_code = test_touch_file(self.emulator)
183        self.assertEqual(exit_code, 0)
184
185
186#
187# Syslinux
188
189
190class TestIso9660SyslinuxExternal(infra.basetest.BRTest):
191    config = BASIC_CONFIG + \
192        """
193        BR2_TARGET_ROOTFS_ISO9660=y
194        # BR2_TARGET_ROOTFS_ISO9660_INITRD is not set
195        BR2_TARGET_ROOTFS_ISO9660_HYBRID=y
196        BR2_TARGET_ROOTFS_ISO9660_BOOT_MENU="{}"
197        BR2_TARGET_SYSLINUX=y
198        """.format(infra.filepath("conf/isolinux.cfg"))
199
200    def test_run(self):
201        exit_code = test_mount_internal_external(self.emulator,
202                                                 self.builddir, internal=False)
203        self.assertEqual(exit_code, 0)
204
205        exit_code = test_touch_file(self.emulator)
206        self.assertEqual(exit_code, 1)
207
208
209class TestIso9660SyslinuxExternalCompress(infra.basetest.BRTest):
210    config = BASIC_CONFIG + \
211        """
212        BR2_TARGET_ROOTFS_ISO9660=y
213        # BR2_TARGET_ROOTFS_ISO9660_INITRD is not set
214        BR2_TARGET_ROOTFS_ISO9660_TRANSPARENT_COMPRESSION=y
215        BR2_TARGET_ROOTFS_ISO9660_HYBRID=y
216        BR2_TARGET_ROOTFS_ISO9660_BOOT_MENU="{}"
217        BR2_TARGET_SYSLINUX=y
218        """.format(infra.filepath("conf/isolinux.cfg"))
219
220    def test_run(self):
221        exit_code = test_mount_internal_external(self.emulator,
222                                                 self.builddir, internal=False)
223        self.assertEqual(exit_code, 0)
224
225        exit_code = test_touch_file(self.emulator)
226        self.assertEqual(exit_code, 1)
227
228
229class TestIso9660SyslinuxInternal(infra.basetest.BRTest):
230    config = BASIC_CONFIG + \
231        """
232        BR2_TARGET_ROOTFS_ISO9660=y
233        BR2_TARGET_ROOTFS_ISO9660_INITRD=y
234        BR2_TARGET_ROOTFS_ISO9660_HYBRID=y
235        BR2_TARGET_ROOTFS_ISO9660_BOOT_MENU="{}"
236        BR2_TARGET_SYSLINUX=y
237        """.format(infra.filepath("conf/isolinux.cfg"))
238
239    def test_run(self):
240        exit_code = test_mount_internal_external(self.emulator,
241                                                 self.builddir, internal=True)
242        self.assertEqual(exit_code, 0)
243
244        exit_code = test_touch_file(self.emulator)
245        self.assertEqual(exit_code, 0)
246