Seems the recent termios related changes broke the build of some u-boot tools on ppc64le. Please see build log from https://koji.fedoraproject.org/koji/taskinfo?taskID=134460943 for all details. https://github.com/u-boot/u-boot/blob/master/tools/termios_linux.h is the u-boot file broken. .. gcc -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wno-complain-wrong-lang -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection -Wp,-MD,tools/.kwboot.d -Itools -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu11 -DCONFIG_FIT_SIGNATURE -DCONFIG_FIT_SIGNATURE_MAX_SIZE=0xffffffff -DCONFIG_FIT_CIPHER -include ../include/compiler.h -idirafterinclude -idirafter../include -idirafter../arch/sandbox/include -idirafter../dts/upstream/include -I../scripts/dtc/libfdt -I../tools -DUSE_HOSTCC -D__KERNEL_STRICT_NAMES -D_GNU_SOURCE -pthread -o tools/kwboot ../tools/kwboot.c -pthread -ltinfo In file included from ../tools/kwboot.c:153: ../tools/termios_linux.h:36:17: warning: ‘struct termios2’ declared inside parameter list will not be visible outside of this definition or declaration 36 | #define termios termios2 | ^~~~~~~~ ../tools/termios_linux.h:39:44: note: in expansion of macro ‘termios’ 39 | static inline int tcgetattr(int fd, struct termios *t) | ^~~~~~~ In file included from /usr/include/asm/ioctl.h:12, from /usr/include/asm/ioctls.h:5, from /usr/include/bits/ioctls.h:23, from /usr/include/sys/ioctl.h:26, from ../tools/termios_linux.h:30: ../tools/termios_linux.h: In function ‘tcgetattr’: ../tools/termios_linux.h:42:26: error: invalid application of ‘sizeof’ to incomplete type ‘struct termios2’ 42 | return ioctl(fd, TCGETS2, t); | ^~~~~~~ ../tools/termios_linux.h: At top level: ../tools/termios_linux.h:36:17: warning: ‘struct termios2’ declared inside parameter list will not be visible outside of this definition or declaration 36 | #define termios termios2 | ^~~~~~~~ ../tools/termios_linux.h:48:57: note: in expansion of macro ‘termios’ 48 | static inline int tcsetattr(int fd, int a, const struct termios *t) | ^~~~~~~ ../tools/termios_linux.h: In function ‘tcsetattr’: ../tools/termios_linux.h:55:23: error: invalid application of ‘sizeof’ to incomplete type ‘struct termios2’ 55 | cmd = TCSETS2; | ^~~~~~~ ../tools/termios_linux.h:58:23: error: invalid application of ‘sizeof’ to incomplete type ‘struct termios2’ 58 | cmd = TCSETSW2; | ^~~~~~~~ ../tools/termios_linux.h:61:23: error: invalid application of ‘sizeof’ to incomplete type ‘struct termios2’ 61 | cmd = TCSETSF2; | ^~~~~~~~ ../tools/termios_linux.h: At top level: ../tools/termios_linux.h:36:17: warning: ‘struct termios2’ declared inside parameter list will not be visible outside of this definition or declaration 36 | #define termios termios2 | ^~~~~~~~ ../tools/termios_linux.h:116:48: note: in expansion of macro ‘termios’ 116 | static inline speed_t cfgetospeed(const struct termios *t) | ^~~~~~~ ../tools/termios_linux.h: In function ‘cfgetospeed’: ../tools/termios_linux.h:118:17: error: invalid use of undefined type ‘const struct termios2’ 118 | return t->c_cflag & CBAUD; | ^~ ../tools/termios_linux.h: At top level: ../tools/termios_linux.h:36:17: warning: ‘struct termios2’ declared inside parameter list will not be visible outside of this definition or declaration 36 | #define termios termios2 | ^~~~~~~~ ../tools/termios_linux.h:121:38: note: in expansion of macro ‘termios’ 121 | static inline int cfsetospeed(struct termios *t, speed_t s) | ^~~~~~~ ../tools/termios_linux.h: In function ‘cfsetospeed’: ../tools/termios_linux.h:128:10: error: invalid use of undefined type ‘struct termios2’ 128 | t->c_cflag &= ~CBAUD; | ^~ ../tools/termios_linux.h:129:10: error: invalid use of undefined type ‘struct termios2’ 129 | t->c_cflag |= s; | ^~ ... Reproducible: Always
This looks like an attempt in uboot-tools to use the termios2 kernel interfaces with the old glibc headers. Quoting the uboot-tools header: /* * We need to use raw TCGETS2/TCSETS2 or TCGETS/TCSETS ioctls with the BOTHER * flag in struct termios2/termios, defined in Linux headers <asm/ioctls.h> * (included by <sys/ioctl.h>) and <asm/termbits.h>. Since these headers * conflict with glibc's header file <termios.h>, it is not possible to use * libc's termios functions and we need to reimplement them via ioctl() calls. * * An arbitrary baudrate is supported when the macro BOTHER is defined. The * baudrate value itself is then stored into the c_ospeed and c_ispeed members. * If ioctls TCGETS2/TCSETS2 are defined and supported then these fields are * present in struct termios2, otherwise these fields are present in struct * termios. * * Note that the Bnnn constants from <termios.h> need not be compatible with Bnnn * constants from <asm/termbits.h>. */ If the uboot-tools developers have suggestions how we can make the porting easier for them, maybe they can suggest that on libc-alpha?
I'll reach out to upstream
I've posted an RFC patch for u-boot: https://lists.denx.de/pipermail/u-boot/2025-June/593131.html The problem as I understand it is that the PowerPC architecture does not define a struct termios2 as is the case for other architectures. In https://elixir.bootlin.com/linux/v6.16-rc3/source/arch/powerpc/include/uapi/asm/termbits.h it says: #define NCCS 19 struct termios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ tcflag_t c_cflag; /* control mode flags */ tcflag_t c_lflag; /* local mode flags */ cc_t c_cc[NCCS]; /* control characters */ cc_t c_line; /* line discipline (== c_cc[19]) */ speed_t c_ispeed; /* input speed */ speed_t c_ospeed; /* output speed */ }; /* For PowerPC the termios and ktermios are the same */ struct ktermios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ tcflag_t c_cflag; /* control mode flags */ tcflag_t c_lflag; /* local mode flags */ cc_t c_cc[NCCS]; /* control characters */ cc_t c_line; /* line discipline (== c_cc[19]) */ speed_t c_ispeed; /* input speed */ speed_t c_ospeed; /* output speed */ }; while all other architectures have a legacy struct termios and a struct termios2 that is the same than struct ktermios: https://elixir.bootlin.com/linux/v6.16-rc3/source/include/uapi/asm-generic/termbits.h #define NCCS 19 struct termios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ tcflag_t c_cflag; /* control mode flags */ tcflag_t c_lflag; /* local mode flags */ cc_t c_line; /* line discipline */ cc_t c_cc[NCCS]; /* control characters */ }; struct termios2 { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ tcflag_t c_cflag; /* control mode flags */ tcflag_t c_lflag; /* local mode flags */ cc_t c_line; /* line discipline */ cc_t c_cc[NCCS]; /* control characters */ speed_t c_ispeed; /* input speed */ speed_t c_ospeed; /* output speed */ }; struct ktermios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ tcflag_t c_cflag; /* control mode flags */ tcflag_t c_lflag; /* local mode flags */ cc_t c_line; /* line discipline */ cc_t c_cc[NCCS]; /* control characters */ speed_t c_ispeed; /* input speed */ speed_t c_ospeed; /* output speed */ }; Given that the u-boot header that Florian mentioned, includes the kernel headers, then of course there's no struct termios2 for PowerPC.
Dan also mentioned this glibc https://sourceware.org/git/?p=glibc.git;a=commit;h=5f54d8bc48983bed844c02e1fe614ad223e78838 But AFAICT that change is not completely correct because is defining the TCGETS2/TCSETS*2 ioctls but using a struct termios2 that is not defined for PowerPC. Unless the #include <asm/ioctls.h> somehow includes the asm-generic headers that define the struct termios2 ?
(In reply to Javier Martinez Canillas from comment #4) > Dan also mentioned this glibc > https://sourceware.org/git/?p=glibc.git;a=commit; > h=5f54d8bc48983bed844c02e1fe614ad223e78838 > > But AFAICT that change is not completely correct because is defining the > TCGETS2/TCSETS*2 ioctls but using a struct termios2 > that is not defined for PowerPC. Unless the #include <asm/ioctls.h> somehow > includes the asm-generic headers that define the > struct termios2 ? None of this should be necessary with current glibc (at least I hope so) because it's now termios2-based on all architectures. We could define _LIBC_LINUX_TERMIOS2 in <features.h> to help u-boot to help to disable the compatibility hacks.
(In reply to Florian Weimer from comment #5) > (In reply to Javier Martinez Canillas from comment #4) > > Dan also mentioned this glibc > > https://sourceware.org/git/?p=glibc.git;a=commit; > > h=5f54d8bc48983bed844c02e1fe614ad223e78838 > > > > But AFAICT that change is not completely correct because is defining the > > TCGETS2/TCSETS*2 ioctls but using a struct termios2 > > that is not defined for PowerPC. Unless the #include <asm/ioctls.h> somehow > > includes the asm-generic headers that define the > > struct termios2 ? > > None of this should be necessary with current glibc (at least I hope so) > because it's now termios2-based on all architectures. We could define > _LIBC_LINUX_TERMIOS2 in <features.h> to help u-boot to help to disable the > compatibility hacks. I'm confused, but who defines the struct termios2 for the PowerPC architecture? You said that current glibc it is now termios2-based on all architectures, but I couldn't find where is defined for PowerPC.
Hmm. I missed the incorrect definition problem. I raised it on libc-alpha. Hopefully it's just a typo, and the constant should use struct termios.
(In reply to Florian Weimer from comment #7) > Hmm. I missed the incorrect definition problem. I raised it on libc-alpha. > Hopefully it's just a typo, and the constant should use struct termios. Yes, that should work too.
for the record, https://sourceware.org/pipermail/libc-alpha/2025-July/168322.html
What is mentioned in https://sourceware.org/pipermail/libc-alpha/2025-July/168339.html is not accurate AFAICT: "<linux/termios.h> defines it, but that header conflicts with <termios.h>." but what I see in the Linux kernel source repo is the following: $ make x86_64_defconfig prepare modules_prepare $ cat ./arch/x86/include/generated/uapi/asm/termbits.h #include <asm-generic/termbits.h> $ grep "struct termios2" include/uapi/asm-generic/termbits.h 19:struct termios2 { $ head -n 40 arch/powerpc/include/uapi/asm/termbits.h /* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ #ifndef _ASM_POWERPC_TERMBITS_H #define _ASM_POWERPC_TERMBITS_H /* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ #include <asm-generic/termbits-common.h> typedef unsigned int tcflag_t; /* * termios type and macro definitions. Be careful about adding stuff * to this file since it's used in GNU libc and there are strict rules * concerning namespace pollution. */ #define NCCS 19 struct termios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ tcflag_t c_cflag; /* control mode flags */ tcflag_t c_lflag; /* local mode flags */ cc_t c_cc[NCCS]; /* control characters */ cc_t c_line; /* line discipline (== c_cc[19]) */ speed_t c_ispeed; /* input speed */ speed_t c_ospeed; /* output speed */ }; /* For PowerPC the termios and ktermios are the same */ struct ktermios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ tcflag_t c_cflag; /* control mode flags */ tcflag_t c_lflag; /* local mode flags */
In other words, struct termios and struct termios2 (if defined for the arch) are defined in <asm/termbits.h>, which for x86 is just <asm-generic/termbits.h> and powerpc has its own that does not define a struct termios2.