diff -u -ruN linux-2.4.20.orig/Documentation/Configure.help linux-2.4.20.time_bootup/Documentation/Configure.help --- linux-2.4.20.orig/Documentation/Configure.help Thu Nov 28 15:53:08 2002 +++ linux-2.4.20.time_bootup/Documentation/Configure.help Fri Sep 19 14:43:39 2003 @@ -25505,6 +25505,15 @@ early in the boot process, but only if you have a VGA screen attached. If you're unsure, select N. +Configure timing instrumentation for printk +CONFIG_TIME_BOOTUP + Selecting this option causes extra timing information to be included + in printks from the kernel, which allows you to see how long + bootup operations take. It also moves console_init to later in the + kernel initialization sequence, to avoid having console output overhead + interfere with the timing measurements. This option should only be + used during development for identifying long delays in kernel startup. + Print possible IA64 hazards to console CONFIG_IA64_PRINT_HAZARDS Selecting this option prints more information for Illegal Dependency diff -u -ruN linux-2.4.20.orig/arch/i386/config.in linux-2.4.20.time_bootup/arch/i386/config.in --- linux-2.4.20.orig/arch/i386/config.in Thu Nov 28 15:53:09 2002 +++ linux-2.4.20.time_bootup/arch/i386/config.in Fri Sep 26 13:14:13 2003 @@ -316,6 +316,11 @@ bool ' Use real mode APM BIOS call to power off' CONFIG_APM_REAL_MODE_POWER_OFF fi +bool 'Configure timing instrumentation in printk' CONFIG_TIME_BOOTUP +if [ "$CONFIG_TIME_BOOTUP" != "n" ]; then + define_bool CONFIG_DELAY_CONSOLE_INIT y +fi + endmenu source drivers/mtd/Config.in diff -u -ruN linux-2.4.20.orig/include/asm-i386/timex.h linux-2.4.20.time_bootup/include/asm-i386/timex.h --- linux-2.4.20.orig/include/asm-i386/timex.h Wed Oct 1 10:30:52 2003 +++ linux-2.4.20.time_bootup/include/asm-i386/timex.h Fri Sep 26 16:06:36 2003 @@ -9,6 +9,10 @@ #include #include +#ifdef CONFIG_TIME_BOOTUP +#include +#endif + #ifdef CONFIG_MELAN # define CLOCK_TICK_RATE 1189200 /* AMD Elan has different frequency! */ #else @@ -52,6 +56,38 @@ extern unsigned long cpu_khz; +#ifdef CONFIG_TIME_BOOTUP +static inline void highres_timer_read_ticks (u32 *slow, u32 *fast) +{ +#ifndef CONFIG_X86_TSC + fast = slow = 0; + return; +#else + /* rdtsc(fast, slow); */ + unsigned long long ticks; + rdtscll(ticks); + *slow = ticks>>32; + *fast = ticks & 0xffffffff; + +#endif +} + + +static inline void highres_timer_ticks_to_timeval(u32 slow, u32 fast, struct timeval *tv) +{ + /* would be nice to use probed cpu_khz here, but it + * likely isn't set yet. Set the following for your + * machine! Hint: boot once and look at /proc/cpuinfo */ + u32 fixed_cpu_khz = 645206; + + /* a little sloppy math here... */ + tv->tv_sec = slow*(0xffffffff/(fixed_cpu_khz*1000)); + tv->tv_sec += fast/(fixed_cpu_khz*1000); + tv->tv_usec = (fast%(fixed_cpu_khz*1000))/(fixed_cpu_khz/1000); +} +#endif + + #define vxtime_lock() do {} while (0) #define vxtime_unlock() do {} while (0) diff -u -ruN linux-2.4.20.orig/kernel/printk.c linux-2.4.20.time_bootup/kernel/printk.c --- linux-2.4.20.orig/kernel/printk.c Fri Aug 2 17:39:46 2002 +++ linux-2.4.20.time_bootup/kernel/printk.c Mon Sep 22 13:38:05 2003 @@ -29,6 +29,11 @@ #include +#ifdef CONFIG_TIME_BOOTUP +#include +#include +#endif + #if defined(CONFIG_MULTIQUAD) || defined(CONFIG_IA64) #define LOG_BUF_LEN (65536) #elif defined(CONFIG_ARCH_S390) @@ -434,11 +439,44 @@ */ for (p = printk_buf; *p; p++) { if (log_level_unknown) { +#ifdef CONFIG_TIME_BOOTUP + int loglev_char; + char tbuf[50], *tp; + unsigned tlen; + u32 slow, fast; + struct timeval tv; + + highres_timer_read_ticks (&slow, &fast); + highres_timer_ticks_to_timeval (slow, fast, &tv); + + /* Force the log level token to be + before our diagnostic output. */ + if (p[0] == '<' && p[1] >= '0' + && p[1] <= '7' && p[2] == '>') + { + loglev_char = p[1]; + p += 3; + } else + loglev_char = default_message_loglevel + '0'; + + tlen = sprintf (tbuf, + "<%c>[%5lu.%06lu <%5lu:%5lu>] ", + loglev_char, + tv.tv_sec, tv.tv_usec, + (unsigned long)slow, + (unsigned long)fast); + + for (tp = tbuf; tp < tbuf + tlen; tp++) + emit_log_char (*tp); + +#else /* !CONFIG_TIME_BOOTUP */ if (p[0] != '<' || p[1] < '0' || p[1] > '7' || p[2] != '>') { emit_log_char('<'); emit_log_char(default_message_loglevel + '0'); emit_log_char('>'); } +#endif /* CONFIG_TIME_BOOTUP */ + log_level_unknown = 0; } emit_log_char(*p);