Linux系统的内核启动(linuxstartkernel)

Linux系统是一种非常流行并且广泛使用的操作系统,它提供了强大的功能和灵活性,可以在各种不同的设备上使用。在Linux系统中,内核是整个系统的核心,并且是系统启动时更先加载的组件。在本文中,我们将深入探讨过程,了解它的所有步骤和阶段。

公司主营业务:做网站、成都做网站、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。成都创新互联公司是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。成都创新互联公司推出迎泽免费做网站回馈大家。

1. 引导加载程序

在任何操作系统的启动过程中,之一步始终是启动引导加载程序。引导加载程序负责在计算机启动时加载操作系统的内核,并且它通常存储在计算机的启动磁盘驱动器中。在Linux系统中,引导加载程序通常是Grub(GRand Unified Bootloader)。

2. 初始化内核

启动引导加载程序之后,计算机将开始初始化操作系统内核。这是一个非常关键的步骤,因为它将为系统中的其他组件提供必要的基础设施,并确保内核能够正常工作。在Linux系统中,内核初始化包括以下步骤:

– 计算机检测硬件。

– 内核加载相应的驱动程序以支持硬件设备。

– 内核初始化内存管理子系统、进程管理子系统和文件系统子系统。

– 内核启动守护程序,并设置其他系统设置。

3. 用户空间初始化

完成内核初始化后,Linux系统将开始用户空间初始化。用户空间是一个操作系统中的一部分,它是用户和应用程序运行的地方。在Linux系统中,用户空间初始化包括以下步骤:

– 管理用户和用户组。

– 初始化系统服务和设置程序,以便它们可以正常运行。

– 启动登录管理器(如GDM或KDM),以便用户可以登录到系统。

4. shell启动

一旦用户空间初始化完成,Linux系统将启动shell。shell是一个命令行界面,它允许用户与操作系统交互。在Linux系统中,有多个shell可供选择,例如bash和zsh。

5. 启动应用程序和服务

在完成用户空间初始化和shell启动之后,Linux系统将启动应用程序和服务。这些应用程序和服务可能是从命令行启动的,也可能是在系统启动时自动启动的,以确保它们一直在后台运行。

过程是一个非常复杂和精细的过程。没有引导加载程序和内核初始化,操作系统无法正常运行。通过深入了解过程,我们可以更好地理解操作系统的工作原理,并且可以进行调试和优化,使其更加高效和可靠。

成都网站建设公司-创新互联为您提供网站建设、网站制作、网页设计及定制高端网站建设服务!

linux kernel 没有输出信息 怎么调试

最近工作在调试u虚拟串口,让其作为kernel启动的调试串口老埋,以及user空间的输入输出控制台。

利用这个机会,学习下printk如何选择往哪个console输出以及user空间下控制台如何选择,记录与此,与大家共享,也尺含绝方便自己以后翻阅。

Kernel版本号:3.4.55

依照我的思路(还是时间顺序)分了4部分,指定kernel调试console , kernel下printk console的选择 ,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来解析,如下:

view plain copy

static int __init console_setup(char *str)

{

char buf.name) + 4>; /* 4 for index */

char *s, *options, *brl_options = NULL;

int idx;

#ifdef CONFIG_A11Y_BRAILLE_CONSOLE

if (!memcmp(str, “brl,”, 4)) {

brl_options = “”;

str += 4;

} else if (!memcmp(str, “brl=”, 4)) {

brl_options = str + 4;

str = strchr(brl_options, ‘,’);

if (!str) {

printk(KERN_ERR “need port name after brl=\n”);

return 1;

}

*(str++) = 0;

}

#endif

/*

* Decode str into name, index, options.

*/

if (str >= ‘0’ && str = ‘0’ && *s name, name, sizeof(c->name));

c->options = options;

#ifdef CONFIG_A11Y_BRAILLE_CONSOLE

c->brl_options = brl_options;

#endif

c->index = idx;

return 0;

}

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

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

比如cmdline中有“console=ttyS0,console=ttyS1,9600”

则在console_cmdline数组中console_cmdline代表ttyS0,console_cmdline代表ttyS1,而selected_console=1.

二 kernel下printk console的选择

kernel下调试信息是通过printk输出,如果要kernel正常打印,则需要搞明白printk怎么选择输出的设备。

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

printk首先将输出内容添加到一个kernel缓冲区中,叫log_buf,log_buf相关代码如下:

view plain copy

#define MAX_CMDLINECONSOLES 8

static struct console_cmdline console_cmdline;

static int selected_console = -1;

static int preferred_console = -1;

int console_set_on_cmdline;

EXPORT_SYMBOL(console_set_on_cmdline);

/* Flag: console code may call schedule() */

static int console_may_schedule;

#ifdef CONFIG_PRINTK

static char __log_buf;

static char *log_buf = __log_buf;

static int log_buf_len = __LOG_BUF_LEN;

static unsigned logged_chars; /* Number of chars produced since last read+clear operation */

static int saved_console_loglevel = -1;

log_buf的大小由kernel menuconfig配置,我配置的CONFIG_LOG_BUF_SHIFT为17,则log_buf为128k。

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

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

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

printk->vprintk->console_unlock->call_console_drivers->_call_console_drivers->_call_console_drivers->__call_console_drivers

看线索更底层__call_console_drivers代码。如下:

view plain copy

/*

* Call the console drivers on a range of log_buf

*/

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(p_processor_id()) ||

(con->flags & CON_ANYTIME)))

con->write(con, &LOG_BUF(start), end – start);

}

}

for_each_console定义如下:

view plain copy

/*

* for_each_console() allows you to iterate on each console

*/

#define for_each_console(con) \

for (con = console_drivers; con != NULL; con = con->next)

遍历console_drivers链表所有console struct,如果有exclusive_console,则调用与exclusive_console一致console的write,

如果exclusive_console为NULL,则调用所有ENABLE的console的write方法将log buf中start到end的内容发出。

可以看出,execlusive_console来指定printk输出唯一console,如果未指定,则向所有enable的console写。

默认情况下execlusive_console=NULL,所以printk默认是向所有enable的console写!

只有一种情况是指定execlusive_console,就是在console注册时,下面会讲到。

到这里就很明了了,kernel下每次printk打印,首先存log_buf,然后遍历console_drivers,找到合适console(execlusive_console或所有enable的),刷出log。

console_drivers链表的成员是哪里来的,谁会指定execulsive_console?接着来看下一部分,kernel下console的注册

linux start kernel的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于linux start kernel,Linux系统的内核启动,linux kernel 没有输出信息 怎么调试的信息别忘了在本站进行查找喔。

香港云服务器机房,创新互联(www.cdcxhl.com)专业云服务器厂商,回大陆优化带宽,安全/稳定/低延迟.创新互联助力企业出海业务,提供一站式解决方案。香港服务器-免备案低延迟-双向CN2+BGP极速互访!

分享名称:Linux系统的内核启动(linuxstartkernel)
网页URL:http://www.shufengxianlan.com/qtweb/news31/106681.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联