使用dmesg打印所有日志( 九 )

< 0)return -ENODEV;//从这里返回,下边的不再执行//若找到early console用的串口号,更新当初传入内核参数使用的console_cmdline[i],名称改成ttyS 。。。。ret = update_console_cmdline("uart", 8250, "ttyS", line, device->options);if (ret < 0)ret = update_console_cmdline("uart", 0,"ttyS", line, device->options);return ret;}static int __init serial8250_console_setup(struct console *co, char *options){struct uart_port *port;int baud = 9600;int bits = 8;int parity = 'n';int flow = 'n';if (co->index >= nr_uarts)//console的索引,这里是2,即ttyS2co->index = 0;port = &serial8250_ports[co->index].port;//找到对应的ttyS2的uart_port结构//由于console_init在注册serial8250_console时调用的register_console()函数调用serial8250_console_setup()//进入这个函数时,由于ttyS2的uart_port结构没有初始化,port->iobase 和port->membase值都未设置,所以直接从下边返回//当进行串口初始化时,还会回来注册serial8250_console,再调用到这里,由于设置了ttyS2的uart_port结构,所以下边的配置就会成功if (!port->iobase && !port->membase)//第一次注册时,由于未设置,从这里直接返回return -ENODEV;if (options)//如果options不为空,就将options里的数值写给baud, &parity, &bits, &flowuart_parse_options(options, &baud, &parity, &bits, &flow);//没有配置options,则使用缺省值,否则使用传下来的的参数options里的串口配置return uart_set_options(port, co, baud, parity, bits, flow);}五、通过四知道,在对console注册时,没有成功,由于串口还没有配置 。当对串口配置时再对console注册就能成功 。serial8250_console就能注册到内核全局变量console_drivers中 。这样终端打印时就通过注册的serial8250_console就能将信息打印到终端上 。//内核的打印函数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); //调用vprintk函数va_end(args);//释放可变参数链表指针return r;}//vprintk函数asmlinkage int vprintk(const char *fmt, va_list args){int printed_len = 0;int current_log_level = default_message_loglevel;unsigned long flags;int this_cpu;char *p;boot_delay_msec();printk_delay();preempt_disable();raw_local_irq_save(flags);this_cpu = smp_processor_id();if (unlikely(printk_cpu == this_cpu)) {if (!oops_in_progress) {recursion_bug = 1;goto out_restore_irqs;}zap_locks();}lockdep_off();spin_lock(&logbuf_lock);printk_cpu = this_cpu;if (recursion_bug) {recursion_bug = 0;strcpy(printk_buf, recursion_bug_msg);printed_len = strlen(recursion_bug_msg);}printed_len += vscnprintf(printk_buf + printed_len,sizeof(printk_buf) - printed_len, fmt, args);p = printk_buf;if (p[0] == '<') {//处理打印级别字段unsigned char c = p[1];if (c && p[2] == '>') {switch (c) {case '0' ... '7': /* loglevel */current_log_level = c - '0';case 'd': /* KERN_DEFAULT */if (!new_text_line) {emit_log_char('\n');new_text_line = 1;}case 'c': /* KERN_CONT */p += 3;break;}}}for ( ; *p; p++) {if (new_text_line) {/* Always output the token */emit_log_char('<');emit_log_char(current_log_level + '0');emit_log_char('>');printed_len += 3;new_text_line = 0;if (printk_time) {//打印时间信息/* Follow the token with the time */char tbuf[50], *tp;unsigned tlen;unsigned long long t;unsigned long nanosec_rem;t = cpu_clock(printk_cpu);nanosec_rem = do_div(t, 1000000000);tlen = sprintf(tbuf, "[%5lu.lu] ",(unsigned long) t,nanosec_rem / 1000);for (tp = tbuf; tp < tbuf + tlen; tp++)emit_log_char(*tp);printed_len += tlen;}if (!*p)break;}emit_log_char(*p);if (*p == '\n')new_text_line = 1;}if (acquire_console_semaphore_for_printk(this_cpu))release_console_sem();lockdep_on();out_restore_irqs:raw_local_irq_restore(flags);preempt_enable();return printed_len;}//接着调用release_console_sem函数 void release_console_sem(void){unsigned long flags;unsigned _con_start, _log_end;unsigned wake_klogd = 0;if (console_suspended) {up(&console_sem);return;}console_may_schedule = 0;for ( ; ; ) {spin_lock_irqsave(&logbuf_lock, flags);wake_klogd |= log_start - log_end;if (con_start == log_end)break;/* Nothing to print */_con_start = con_start;_log_end = log_end;con_start = log_end;/* Flush */spin_unlock(&logbuf_lock);stop_critical_timings();/* don't trace print latency */call_console_drivers(_con_start, _log_end);start_critical_timings();local_irq_restore(flags);}console_locked = 0;up(&console_sem);spin_unlock_irqrestore(&logbuf_lock, flags);if (wake_klogd)wake_up_klogd();}EXPORT_SYMBOL(release_console_sem);//调用call_console_drivers函数static void call_console_drivers(unsigned start, unsigned end){unsigned cur_index, start_print;static int msg_level = -1;BUG_ON(((int)(start - end)) > 0);cur_index = start;start_print = start;while (cur_index != end) {if (msg_level