printk调用过程

来源:互联网 发布:专业的vb振动电机 编辑:程序博客网 时间:2024/05/01 05:52

asmlinkage int printk(const char *fmt, ...){va_list args;int r;#ifdef CONFIG_KGDB_KDBif (unlikely(kdb_trap_printk)) {va_start(args, fmt);r = vkdb_printf(fmt, args);va_end(args);return r;}#endifva_start(args, fmt);r = vprintk(fmt, args);  -》》跟踪vprintkva_end(args);return r;}


vprintk->console_unlock->call_console_drivers->_call_console_drivers->con->write

 con是注册的各个终端

con->write是调用console的写方法

static struct console ram_console = {    .name    = "ram",    .write    = ram_console_write,    .flags    = CON_PRINTBUFFER | CON_ENABLED | CON_ANYTIME,    .index    = -1,};

对于 ram_console就是ram_console_write


对于串口控制台为 mux_console_write

static struct console mux_console = {.name ="ttyB",.write =mux_console_write,.device =mux_console_device,.setup =mux_console_setup,.flags =CON_ENABLED | CON_PRINTBUFFER,.index =0,};
mux_console_write 直接操作到硬件

static void mux_console_write(struct console *co, const char *s, unsigned count){/* Wait until the FIFO drains. */while(UART_GET_FIFO_CNT(&mux_ports[0].port))udelay(1);while(count--) {if(*s == '\n') {UART_PUT_CHAR(&mux_ports[0].port, '\r');}UART_PUT_CHAR(&mux_ports[0].port, *s++);}}

#define UART_PUT_CHAR(p, c) __raw_writel((c), (p)->membase + IO_DATA_REG_OFFSET)

可见,如果要自定义一个控制台,就得自定义一个console结构体,和它的方法,设置好标志位,对于每个console来说,如果设置了CON_ENABLE,提供write方法,则printk被调用时将把数据通过console输出。

static void __call_console_drivers(unsigned start, unsigned end){struct console *con;for_each_console(con) {if (exclusive_console && con != exclusive_console)continue;if ((con->flags & CON_ENABLED) && con->write &&(cpu_online(smp_processor_id()) ||(con->flags & CON_ANYTIME)))con->write(con, &LOG_BUF(start), end - start);}}






0 0
原创粉丝点击