1:信息

内核版本: Linux 2.6.22
busybox版本:busybox-1.7.0

2:文件系统的出现位置

板卡上电后先由UBOOT启动初始化办卡,将Linux移到内存中运行

  • 由linux内核自行做初始化操作,挂载了第一个应用程序(根文件系统 /linuxrc)
  • 根文件系统会提供磁盘管理服务,glic设备节点,配置文件,应用程序 shell命令(Android就是linux多了个文件系统)

文件系统的重要部分:
1:标准库:glibc OpenGl media framwork
2:配置文件:/etc/init.d/rcS (开机运行的软件,显示的画面,执行的命令),/sys/ 开机挂载的设备节点
3:设备节点:/dev/console 控制节点 /dev/null -->mknode
4:架构程序:对多种服务和功能进行系统接口封装
5:shell的实现:所有的shell命令都在文件系统中

根文件系统:类似电脑的C盘:最小的文件系统

微观:
常用的到的一种文件系统: BusyBox 官网:各版本下载:主要实现shell命令
创建一些shell命令,并根据此类的shell命令进行相应的操作

3:文件系统起点

3.1 内核启动的部分代码

start_kernel -> rest_init-> init_post -> run_init_process(execute_command)

//main.c linux-2.6.22.6\init 20513   2007-08-31
asmlinkage void __init start_kernel(void)
{....../* Do the rest non-__init'ed, we're now alive */rest_init();
}
static void noinline __init_refok rest_init(void)__releases(kernel_lock)
{int pid;kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);......
}
static int __init kernel_init(void * unused)
{......init_post();return 0;
}static int noinline init_post(void)
{   if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) //打开控制台作为标准输入printk(KERN_WARNING "Warning: unable to open an initial console.\n");(void) sys_dup(0);//复制,作为标准输出(void) sys_dup(0);//复制,作为标准错误/** We try each of these until one succeeds.** The Bourne shell can be used instead of init if we are* trying to recover a really broken machine.*/if (execute_command) { //如果命令串被定义执行自定义的命令run_init_process(execute_command);  //run_init_process执行成功会把代码段替换成execute_command对应的内容,下面的代码都会被覆盖掉,就不会执行。如果失败就会执行下面的语句printk(KERN_WARNING "Failed to execute %s.  Attempting ""defaults...\n", execute_command);}//如果命令串未被定义则进行默认程序执行run_init_process("/sbin/init"); //同上, 这个有busybox提供,是一个软链接指向busyboxrun_init_process("/etc/init");run_init_process("/bin/init");run_init_process("/bin/sh");//如果当前系统中没有可执行的程序,则内核文件系统启动失败panic("No init found.  Try passing init= option to kernel.");
}

3.2 execute_command的来源

对execute_command 进行赋值

static int __init init_setup(char *str)
{unsigned int i;execute_command = str;/** In case LILO is going to boot us with default command line,* it prepends "auto" before the whole cmdline which makes* the shell think it should execute a script with such name.* So we ignore all arguments entered _before_ init=... [MJ]*/for (i = 1; i < MAX_INIT_ARGS; i++)argv_init[i] = NULL;return 1;
}
__setup("init=", init_setup); //init_setup 由__setup调用,并将函数init_setup放到指定得段位置

3.2.1 __setup的定义

//init.h linux-2.6.22.6\include\linux    10382   2007-08-31
#define __setup(str, fn)                    \__setup_param(str, fn, fn, 0)#define __setup_param(str, unique_id, fn, early)          \static char __setup_str_##unique_id[] __initdata = str;   \static struct obs_kernel_param __setup_##unique_id \__attribute_used__             \__attribute__((__section__(".init.setup")))  \__attribute__((aligned((sizeof(long)))))   \= { __setup_str_##unique_id, fn, early }

3.2.2 对宏进行代入解析

__setup("init=", init_setup);
__setup_param("init=",init_setup, init_setup, 0)
 static char __setup_str_init_setup[] __initdata = "init=";  \static struct obs_kernel_param __setup_init_setup  \  //定义结构体,规定一下属性__attribute_used__              \__attribute__((__section__(".init.setup")))  \ //属于这个段__attribute__((aligned((sizeof(long)))))   \ //4字节对齐= { __setup_str_init_setup, init_setup, 0}

下面是段定义的位置

//vmlinux.lds.S  linux-2.6.22.6\arch\arm\kernel  3724    2007-08-31  .init : {           /* Init code and data       */__setup_start = .;*(.init.setup)__setup_end = .;

表示上面的结构体 obs_kernel_param存放在".init.setup"段中,每个结构体包括下面3个部分

struct obs_kernel_param {const char *str; //字符串int (*setup_func)(char *);  //函数int early; //标志位
};

3.3 该结构体使用位置

3.3.1 p->early 等于0 时调用的函数

参数是一个整体。例如line 是 “init = xxxxx”

//main.c linux-2.6.22.6\init 20513   2007-08-31
static int __init obsolete_checksetup(char *line)
{struct obs_kernel_param *p;int had_early_param = 0;p = __setup_start; //p指向*(.init.setup)的开头//对p从开头到结尾进行遍历, do {int n = strlen(p->str);if (!strncmp(line, p->str, n)) { //如果遍历中p的字符串和传进来的line相等if (p->early) { //如果p->early 不等于0, /* Already done in parse_early_param?* (Needs exact match on param part).* Keep iterating, as we can have early* params and __setups of same names 8( */if (line[n] == '\0' || line[n] == '=')had_early_param = 1;} else if (!p->setup_func) {//如果对应的函数p->setup_func为NULL,打印错误信息printk(KERN_WARNING "Parameter %s is obsolete,"" ignored\n", p->str);return 1;} else if (p->setup_func(line + n))//如果p->early 等于0 ,n是结构体中已存在的字符串的长度("init ="的长度),//line指向的字符串是这样的 "init = xxxxx" 那么line + n 就会指向" xxxxx", 目的就是提取字符串的参数部分return 1;}p++;} while (p < __setup_end);return had_early_param;
}

调用的顺序

start_kernel ->parse_args->unknown_bootoption->obsolete_checksetup

asmlinkage void __init start_kernel(void)
{//parse_args会对传进来参数static_command_line进行处理,init = xxxxx会被处理成xxxxx,然后传递到unknown_bootoption中去parse_args("Booting kernel", static_command_line, __start___param,__stop___param - __start___param,&unknown_bootoption);
}
static int __init unknown_bootoption(char *param, char *val)
{/* Handle obsolete-style parameters */if (obsolete_checksetup(param))return 0;
}

3.3.2 p->early 不等于0 时调用的函数

参数是分成两部分。例如"init = xxxxx" (param 是 "init = " ) ( val是 “xxxxx”)

//main.c linux-2.6.22.6\init 20513   2007-08-31
/* Check for early params. */
static int __init do_early_param(char *param, char *val)
{struct obs_kernel_param *p;for (p = __setup_start; p < __setup_end; p++) {if (p->early && strcmp(param, p->str) == 0) { //p->early为1 并且传进来的param和p-str相同if (p->setup_func(val) != 0)printk(KERN_WARNING"Malformed early option '%s'\n", param);}}/* We accept everything at this stage. */return 0;
}

这里的p->setup_func(val) 就是前面往结构体中存放的函数 static int __init init_setup(char *str)(对execute_command 进行赋值)
uboot传入得的以init = xxxxx的参数, 会 通过"init"在固定端位置遍历结构体,等找到对应的结构体,然后利用这个这个的函数setup_func,把参数xxxx放到这个函数中p->setup_func(xxxxx),这个函数中会对execute_command 赋值execute_command = xxxxx

3.4 总结

U-boot传递了很多参数,taglist
被解析成很多的setup段,这些段都存放在.ini.setup的代码段中,形式为CMD(字符串)命令对应得处理函数
在两个函数 obsolete_checksetup(处理early = 0) 和do_early_param(处理early != 0)中进行了所有存放在.init.setup代码段得命令执行
针对setup段得CMD(execute_command)进行全局变量得赋值

execute_command 时uboot传入得的以init = xxxxx的参数
例如uboot传入得command得参数 init = linuxrc 那么execute_command = linuxrc
针对3.1 的代码

 if (execute_command) { run_init_process(execute_command);

可以转化为

 if (linuxrc) { run_init_process(linuxrc);  内核切换到文件系统的中进行linuxrc应用程序的运行

linuxrc指向busybox

如果没有定义linuxrc 就会运行"/sbin/init"

 run_init_process("/sbin/init"); //同上, 这个有busybox提供,是一个软链接指向busyboxrun_init_process("/etc/init");run_init_process("/bin/init");run_init_process("/bin/sh");

"/sbin/init"也指向busybox

4 进入busybox

查看:内核文件系统-busybox

4.0 内核文件系统-kernel部分相关推荐

  1. CentOS6下Xen 4.1的安装(编译linux3.0内核)

    一.    准备工作 a)    一台计算机(是否支持intel-VT或AMD-V均可) 注:支持intel-VT或AMD-V技术可以实现全虚拟化(full virtualization),不支持的话 ...

  2. 编译小米4的linux内核,初次编译 linux kernel 3.0 内核

    第一次编译 内核,在网络上找了教程-于是就怀着玩玩的 当时的想法是能够进入系统就不错鸟--- 现在用着这个 3.0 的内核,一个字--爽.比之前系统自带的内核快多了--比如打开 LibreOffice ...

  3. DM365 linux内核文件系统的烧写步骤及其uboot参数配置

    DM365 linux内核&文件系统的烧写步骤及其uboot参数配置     目录 源文档下载:http://download.csdn.net/detail/zhangjikuan/6443 ...

  4. linux内核wifi,8192DU双频wifi模块移植到linux3.6.0内核

    1.1 下载驱动代码 官方网站()上需找自己匹配的型号的驱动,这里我们使用的是8192du型号的wifi芯片,所以下载匹配的wifi驱动,还有就是使用的linux内核要在官方所指定的版本范围内,这部分 ...

  5. 索引节点inode: Linux内核文件系统之(inode)

    inode译成中文就是索引节点,它用来存放档案及目录的基本信息,包含时间.档名.使用者及群组等. static int eachreg_open(struct inode *inode, struct ...

  6. 《Linux设备驱动开发详解(第3版)》(即《Linux设备驱动开发详解:基于最新的Linux 4.0内核》)进展同步更新

    本博实时更新<Linux设备驱动开发详解(第3版)>的最新进展. 目前已经完成稿件. 2015年8月9日,china-pub开始上线预售: http://product.china-pub ...

  7. 《LINUX3.0内核源代码分析》第一章:内存寻址

    https://blog.csdn.net/ekenlinbing/article/details/7613334 摘要:本章主要介绍了LINUX3.0内存寻址方面的内容,重点对follow_page ...

  8. 《LINUX3.0内核源代码分析》第二章:中断和异常 【转】

    转自:http://blog.chinaunix.net/uid-25845340-id-2982887.html 摘要:第二章主要讲述linux如何处理ARM cortex A9多核处理器的中断.异 ...

  9. Linux文件系统:编写一个内核文件系统

    Linux文件系统在著名的VFS模型下工作,因此符合POSIX.编写Linux文件系统有两种方法 保险丝文件系统 内核文件系统 保险丝本身是一个内核文件系统.它将从VFS接收到的文件系统调用转发到用户 ...

最新文章

  1. 开发日记-20190707 关键词 读书笔记 《Perl语言入门》Day 4
  2. 下 终端_Linux/UNIX 下终端复用利器 tmux
  3. 461. 汉明距离 golang
  4. linux uefi无法启动文件,解决UEFI安装无法启动的问题
  5. 如何在金山毒霸软件里安装腾讯视频
  6. Mr.J--JavaScript-恶搞小代码
  7. 写了10年Javascript未必全了解的标识符顺序
  8. 阶段5 3.微服务项目【学成在线】_day02 CMS前端开发_06-vuejs研究-vuejs基础-v-on指令...
  9. unity2020 for Mac 安装下载详解
  10. 创建oracle数据库实例
  11. 机器学习原理与实践(开源图书)-总目录
  12. JAVA招聘管理系统计算机毕业设计Mybatis+系统+数据库+调试部署
  13. EasyRecovery数据恢复软件100%恢复的成功率
  14. Linux设置小红点键盘,debian linux上安装thinkpad小红点驱动/Installing Debian On Thinkpad – Trackpoint...
  15. 计算机磁盘分为硬盘和什么,win10磁盘分区合并的方法是什么_win10电脑分盘怎么合并...
  16. Java、JSP高速公路收费系统
  17. Android如何隐藏底部虚拟按键
  18. Introduction to Python(2)
  19. 靶场环境的搭建(2020年6月15日学习笔记)
  20. 探索艾利特机器人|EC66机器人在生猪疫苗注射中的应用

热门文章

  1. CS285课程笔记(4)——Exploration Method
  2. 变压器阻抗匹配-考虑线圈感抗吗
  3. JData算法大赛-用户购买预测
  4. 使用mybatis分页插件报错Error parsing SQL Mapper Configuration; Cause: java.lang.ClassCastException: com.gith
  5. 2020升降机司机模拟考试系统及升降机司机操作证考试
  6. onedrive共享文件_如何从OneDrive共享内容
  7. 杰理之播放电话来电号码声音,前面播放“嘟嘟”声【篇】
  8. Android音乐播放器开发的MediaPlayer出现IllegalStateException
  9. Linux 实现自动安装服务组件以及优化内核参数
  10. Tunnel 接口UP Down 分析