#include #include #include #include #include #define LOG_BUFFER_SIZE 0x40000 #define LOG_MSG_SIZE 0x100 static console_t *early_console = NULL; static spin_lock_t log_buffer_lock = SPIN_LOCK_INIT; static char log_buffer[LOG_BUFFER_SIZE] = {0}; /* index of the last character in log_buffer that has been written to the console */ static unsigned int log_buffer_readp = 0; /* index of the last character in log_buffer that has been logged (but not necessarily written to the console) */ static unsigned int log_buffer_writep = 0; static void flush_log_buffer(void) { if (!early_console) { return; } console_write(early_console, log_buffer + log_buffer_readp, log_buffer_writep - log_buffer_readp); log_buffer_readp = log_buffer_writep; } static void save_log_message(const char *msg) { unsigned int i = 0; while (1) { if (log_buffer_writep == LOG_BUFFER_SIZE - 1) { log_buffer[log_buffer_writep] = '\0'; break; } if (msg[i] == '\0') { break; } log_buffer[log_buffer_writep++] = msg[i++]; } } void early_printk_init(console_t *con) { early_console = con; } int printk(const char *format, ...) { char msg[LOG_MSG_SIZE]; va_list arg; va_start(arg, format); int len = vsnprintf(msg, sizeof msg - 1, format, arg); va_end(arg); msg[len] = '\n'; msg[len + 1] = '\0'; if (log_buffer_writep == LOG_BUFFER_SIZE - 1) { console_write(early_console, msg, len + 1); } unsigned long flags; spin_lock_irqsave(&log_buffer_lock, &flags); save_log_message(msg); spin_unlock_irqrestore(&log_buffer_lock, flags); flush_log_buffer(); return 0; }