[PATCH] autoboot: Fix inconsistent countdown output
    Sam Protsenko 
    semen.protsenko at linaro.org
       
    Mon Oct 27 01:37:32 CET 2025
    
    
  
On Sun, Oct 26, 2025 at 7:24 PM Sam Protsenko
<semen.protsenko at linaro.org> wrote:
>
> Commit 5f70be08b015 ("Fix autoboot countdown printing wrong") introduces
> inconsistency in how the countdown is displayed. For example, in case
> when BOOTDELAY=5, the next output is observed during the boot:
>
>     Hit any key to stop autoboot:  5
>     Hit any key to stop autoboot: 4
>     Hit any key to stop autoboot: 3
>
> That happens due to different printf format (%2d vs %1d). Moreover, the
> mentioned commit fails to handle the case when the user is holding some
> key before the countdown is shown. E.g. if BOOTDELAY=101, the next
> malformed output is being produced:
>
>     Hit any key to stop autoboot: 1 0
>
> That's because the fast path code wasn't modified accordingly, and still
> tries to erase the number using '\b\b\b' format.
>
> Fix both issues by introducing a dedicated routine for printing the
> whole countdown line.
>
> Fixes: 5f70be08b015 ("Fix autoboot countdown printing wrong")
> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---
Just for the context: I also tried experimenting with only erasing the
countdown number, to avoid printing the whole line to the serial port
each second (as I/O is usually quite slow). The code is below, for the
reference. Maybe it works faster, I don't know, but the code is more
bulky and it grows the binary by +50 bytes:
            e850-96        : all +50 rodata -38 text +88
               u-boot: add: 1/0, grow: 1/0 bytes: 88/0 (88)
                 function                                   old     new   delta
                 erase_int                                    -      72     +72
                 autoboot_command                           304     320     +16
The patch I submitted reduces the footprint by 45 bytes:
            e850-96        : all -45 rodata -41 text -4
               u-boot: add: 0/0, grow: 0/-1 bytes: 0/-4 (-4)
                 function                                   old     new   delta
                 autoboot_command                           304     300      -4
So all in all I think the patch I submitted is more elegant than the
code below. But FWIW:
8<-------------------------------------------------------------------------->8
diff --git a/common/autoboot.c b/common/autoboot.c
index e39f4a32f957..dcdc1ca557b0 100644
--- a/common/autoboot.c
+++ b/common/autoboot.c
@@ -5,6 +5,7 @@
  */
 #include <config.h>
+#include <ansi.h>
 #include <autoboot.h>
 #include <bootretry.h>
 #include <cli.h>
@@ -376,19 +377,33 @@ static int abortboot_key_sequence(int bootdelay)
     return abort;
 }
+static void erase_int(int val)
+{
+    while (val > 9) {
+        val /= 10;
+        putc('\b');
+    }
+
+    putc('\b');
+    puts(ANSI_CLEAR_LINE_TO_END);
+}
+
 static int abortboot_single_key(int bootdelay)
 {
     int abort = 0;
     unsigned long ts;
+    int cur_bootdelay; /* currently printed boot delay */
-    printf("Hit any key to stop autoboot: %2d ", bootdelay);
+    printf("Hit any key to stop autoboot: %d", bootdelay);
+    cur_bootdelay = bootdelay;
     /*
      * Check if key already pressed
      */
     if (tstc()) {    /* we got a key press    */
         getchar();    /* consume input    */
-        puts("\b\b\b 0");
+        erase_int(cur_bootdelay);
+        putc('0');
         abort = 1;    /* don't auto boot    */
     }
@@ -410,7 +425,9 @@ static int abortboot_single_key(int bootdelay)
             udelay(10000);
         } while (!abort && get_timer(ts) < 1000);
-        printf("\rHit any key to stop autoboot: %1d\033[K", bootdelay);
+        erase_int(cur_bootdelay);
+        printf("%d", bootdelay);
+        cur_bootdelay = bootdelay;
     }
     putc('\n');
-- 
2.39.5
8<-------------------------------------------------------------------------->8
    
    
More information about the U-Boot
mailing list