linux kernel下输入输出console如何实现.docx

上传人:b****3 文档编号:2995129 上传时间:2022-11-17 格式:DOCX 页数:6 大小:22.43KB
下载 相关 举报
linux kernel下输入输出console如何实现.docx_第1页
第1页 / 共6页
linux kernel下输入输出console如何实现.docx_第2页
第2页 / 共6页
linux kernel下输入输出console如何实现.docx_第3页
第3页 / 共6页
linux kernel下输入输出console如何实现.docx_第4页
第4页 / 共6页
linux kernel下输入输出console如何实现.docx_第5页
第5页 / 共6页
点击查看更多>>
下载资源
资源描述

linux kernel下输入输出console如何实现.docx

《linux kernel下输入输出console如何实现.docx》由会员分享,可在线阅读,更多相关《linux kernel下输入输出console如何实现.docx(6页珍藏版)》请在冰豆网上搜索。

linux kernel下输入输出console如何实现.docx

linuxkernel下输入输出console如何实现

linuxkernel下输入输出console如何实现

,kernel下printkconsole的选择,kernel下console的注册,user空间console的选择。

一指定kernel调试console首先看kernel启动时如何获取和处理指定的console参数。

kernel的启动参数cmdline可以指定调试console,如指定‘console=ttyS0,115200’,kernel如何解析cmdline,我之前写了一篇博文如下:

根据之前的分析,cmdline中有console=xxx,start_kernel中parse_args遍历.init.setup段所有obs_kernel_param。

kernel/printk.c中注册了‘console=’的解析函数console_setup(注册了obs_kernel_param),所以匹配成功,会调用console_setup来解析,如下:

[cpp]viewplaincopystaticint__initconsole_setup(char*str){charbuf[sizeof(console_cmdline[0].name)+4];/*4forindex*/char*s,*options,*brl_options=NULL;intidx;#ifdefCONFIG_A11Y_BRAILLE_CONSOLEif(!

memcmp(str,"brl,",4)){brl_options="";str+=4;}elseif(!

memcmp(str,"brl=",4)){brl_options=str+4;str=strchr(brl_options,',');if(!

str){printk(KERN_ERR"needportnameafterbrl=\n");return1;}*(str++)=0;}#endif/**Decodestrintoname,index,options.*/if(str[0]>='0'&&str[0]<='9'){strcpy(buf,"ttyS");strncpy(buf+4,str,sizeof(buf)-5);}else{strncpy(buf,str,sizeof(buf)-1);}buf[sizeof(buf)-1]=0;if((options=strchr(str,','))!

=NULL)*(options++)=0;#ifdef__sparc__if(!

strcmp(str,"ttya"))strcpy(buf,"ttyS0");if(!

strcmp(str,"ttyb"))strcpy(buf,"ttyS1");#endiffor(s=buf;*s;s++)if((*s>='0'&&*s<='9')||*s==',')break;idx=simple_strtoul(s,NULL,10);*s=0;__add_preferred_console(buf,idx,options,brl_options);console_set_on_cmdline=1;return1;}__setup("console=",console_setup);参数是console=的值字符串,如“ttyS0,115200”,console_setup对console=参数值做解析,以ttyS0,115200为例,最后buf=“ttyS”,idx=0,options="115200",brl_options=NULL。

调用__add_preferred_console如下:

[cpp]viewplaincopy/**Ifexclusive_consoleisnon-NULLthenonlythisconsoleistobeprintedto.*/staticstructconsole*exclusive_console;/**Arrayofconsolesbuiltfromcommandlineoptions(console=)*/structconsole_cmdline{charname[8];/*Nameofthedriver*/intindex;/*Minordev.touse*/char*options;/*Optionsforthedriver*/#ifdefCONFIG_A11Y_BRAILLE_CONSOLEchar*brl_options;/*Optionsforbrailledriver*/#endif};#defineMAX_CMDLINECONSOLES8staticstructconsole_cmdlineconsole_cmdline[MAX_CMDLINECONSOLES];staticintselected_console=-1;staticintpreferred_console=-1;intconsole_set_on_cmdline;EXPORT_SYMBOL(console_set_on_cmdline);staticint__add_preferred_console(char*name,intidx,char*options,char*brl_options){structconsole_cmdline*c;inti;/**Seeifthisttyisnotyetregistered,and*ifwehaveaslotfree.*/for(i=0;i<MAX_CMDLINECONSOLES&&console_cmdline[i].name[0];i++)if(strcmp(console_cmdline[i].name,name)==0&&console_cmdline[i].index==idx){if(!

brl_options)selected_console=i;return0;}if(i==MAX_CMDLINECONSOLES)return-E2BIG;if(!

brl_options)selected_console=i;c=&console_cmdline[i];strlcpy(c->name,name,sizeof(c->name));c->options=options;#ifdefCONFIG_A11Y_BRAILLE_CONSOLEc->brl_options=brl_options;#endifc->index=idx;return0;}

kernel利用结构体数组console_cmdline[8],最多可支持8个cmdline传入的console参数。

__add_preferred_console将nameidxoptions保存到数组下一个成员console_cmdline结构体中,如果数组中已有重名,则不添加,并置selected_console为最新添加的console_cmdline的下标号。

比如cmdline中有“console=ttyS0,115200console=ttyS1,9600”则在console_cmdline[8]数组中console_cmdline[0]代表ttyS0,console_cmdline[1]代表ttyS1,而selected_console=1.二kernel下printkconsole的选择kernel下调试信息是通过printk输出,如果要kernel正常打印,则需要搞明白printk怎么选择输出的设备。

关于printk的实现原理,我在刚工作的时候写过一篇博文,kernel版本是2.6.21的,但是原理还是一致的,可供参考:

viewplaincopy#defineMAX_CMDLINECONSOLES8staticstructconsole_cmdlineconsole_cmdline[MAX_CMDLINECONSOLES];staticintselected_console=-1;staticintpreferred_console=-1;intconsole_set_on_cmdline;EXPORT_SYMBOL(console_set_on_cmdline);/*Flag:

consolecodemaycallschedule()*/staticintconsole_may_schedule;#ifdefCONFIG_PRINTKstaticchar__log_buf[__LOG_BUF_LEN];staticchar*log_buf=__log_buf;staticintlog_buf_len=__LOG_BUF_LEN;staticunsignedlogged_chars;/*Numberofcharsproducedsincelastread+clearoperation*/staticintsaved_console_loglevel=-1;log_buf的大小由kernelmenuconfig配置,我配置的CONFIG_LOG_BUF_SHIFT为17,则log_buf为128k。

printk内容会一直存在log_buf中,log_buf满了之后则会从头在开始存,覆盖掉原来的数据。

根据printk的实现原理,printk最后调用console_unlock实现log_buf数据刷出到指定设备。

这里先不关心printk如何处理logbuf数据(比如添加内容级别),只关心printk如何一步步找到指定的输出设备,根据printk.c代码,可以找到如下线索。

printk->vprintk->console_unlock->call_console_drivers->_call_console_driv

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 小升初

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1