linux内核编程_linux内核是什么

2022-11-08 10:04:21 浏览数 (1)

什么是操作系统?

指在系统中负责完成最基本功能和系统管理的部分,

操作系统有哪些组成部分?

  • 内核——操作系统的内在核心
  • 设备驱动程序
  • 启动引导程序
  • 命令行shell
  • 其他种类的用户界面—-操作系统的外在表象
  • 基本的文件管理工具和系统工具

Linux内核的组成

Linux内核源代码目录结构是什么,各目录有什么含义?

  • arch:包含和硬件体系结构相关的代码,每种平台占一个相应的目录,如i386、ARM、PowerPC、MIPS等。
  • block:块设备驱动程序I/O 调度。
  • crypto:常用加密和散列算法(如AES、SHA等),还有一些压缩和CRC校验算法。
  • Documentation:内核各部分的通用解释和注释。
  • drivers:设备驱动程序,每个不同的驱动占用一个子目录,如char、block、net、mtd、i2c等。
  • fs:支持的各种文件系统,如EXT、FAT、NTFS、JFFS2 等。
  • include:头文件,与系统相关的头文件被放置在include/linux 子目录下。
  • init:内核初始化代码。
  • ipc:进程间通信的代码。
  • kernel:内核的最核心部分,包括进程调度、定时器等,而和平台相关的一部分代码放在arch/*/kernel目录下。
  • lib:库文件代码。
  • mm:内存管理代码,和平台相关的一部分代码放在arch/*/mm目录下。
  • net:网络相关代码,实现了各种常见的网络协议。
  • scripts:包含用于配置内核的脚本文件。
  • security:主要包含SELinux 模块。
  • sound:ALSA、OSS音频设备的驱动核心代码和常用设备驱动。
  • usr:实现了用于打包和压缩的cpio等。

Linux内核的有哪些组成部分?

进程调度(SCHED)、内存管理(MM)、虚拟文件系统(VFS)、网络接口(NET)和进程间通信(IPC)

Linux内核的的组成部分之间有什么关系?

  • 进程调度与内存管理之间互相依赖。在多道程序环境下,必须为程序创建进程,而创建进程的第一件事情就是将程序和数据装入内存。
  • 进程间通信子系统要依赖内存管理支持共享内存通信机制,这种机制允许两个进程除了拥有自己的私有空间,还可以存取共同的内存区域。
  • 虚拟文件系统利用网络接口支持网络文件系统(NFS),也利用内存管理支持RAMDISK 设备。
  • 内存管理利用虚拟文件系统支持交换,依赖于进程调度完成交换进程(swapd)定期由调度程序调度。当一个进程存取的内存映射被换出时,内存管理向文件系统发出请求,同时,挂起当前正在运行的进程。

进程调度有什么作用?

调度控制系统中的多个进程对CPU 的访问,使得多个进程能在CPU 中微观串行,宏观并行地执行。

进程调度为什么很重要?

进程调度处于系统的中心位置,内核中其他的子系统都依赖它,因为每个子系统都需要挂起或恢复进程

进程如何在几个状态间切换?

在设备驱动编程中,当请求的资源不能得到满足时会怎样?

驱动一般会调度其他进程执行,其对应的进程进入睡眠状态,直到它请求的资源被释放,才会被唤醒而进入就绪状态。

设备驱动中,如果需要几个并发执行的任务要怎么做?

调用函数int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);启动内核线程。

内存管理的主要作用是什么?

控制多个进程安全地共享主内存区域。当CPU提供内存管理单元(MMU)时,Linux 内存管理完成为每个进程进行虚拟内存到物理内存的转换。

进程的地址空间时怎样划分的?

Linux 的每个进程享有4GB的内存空间,0~3GB属于用户空间,3~4GB属于内核空间

虚拟文件系统有什么作用?

Linux 虚拟文件系统(VFS)隐藏各种了硬件的具体细节,为所有设备提供了统一的接口。而且,它独立于各个具体的文件系统,是对各种文件系统的一个抽象

虚拟文件系统如何描述文件相关信息?

使用超级块super block存放文件系统相关信息,使用索引节点inode存放文件的物理信息,使用目录项dentry存放文件的逻辑信息。

网络接口有什么作用?

提供了对各种网络标准的存取和各种网络硬件的支持。

网络接口包括那两个部分?

网络协议和网络设备驱动程序

网络协议有什么作用?

负责实现每一种可能的网络传输协议

网络设备驱动程序有什么作用?

负责与硬件设备进行通信,每一种可能的硬件设备都有相应的设备驱动程序。

进程通信有什么作用?

协助多个进程、多资源的互斥访问、进程间的同步和消息传递

有哪些进程通信机制?

信号量、共享内存、管道、消息队列、Socket通信、Binder通信

ARM处理器有几种工作模式?

  • 用户模式(usr):大多数的应用程序运行在用户模式下,当处理器运行在用户模式下时,某些被保护的系统资源是不能被访问的。
  • 快速中断模式(fiq):用于高速数据传输或通道处理。
  • 外部中断模式(irq):用于通用的中断处理。
  • 管理模式(svc):操作系统使用的保护模式。
  • 数据访问终止模式(abt):当数据或指令预取终止时进入该模式,可用于虚拟存储及存储保护。
  • 系统模式(sys):运行具有特权的操作系统任务。
  • 未定义指令中止模式(und):当未定义的指令执行时进入该模式,可用于支持硬件协处理器的软件仿真。

为什么要划分内核空间和用户空间?

内核可进行任何操作,而应用程序则被禁止对硬件的直接访问和对内存的未授权访问。划分内核空间和用户空间用来区分程序执行的这两种不同状态,它们使用不同的地址空间。

如何实现从用户空间到内核空间的控制转移?

只能通过系统调用和硬件中断完成

Linux内核的编译及加载

内核的配置系统由哪既部分组成?

  • Makefile:分布在Linux 内核源代码中的Makefile,定义Linux 内核的编译规则。
  • 配置文件(Kconfig):给用户提供配置选择的功能。
  • 配置工具:包括配置命令解释器(对配置脚本中使用的配置命令进行解释)和配置用户界面(提供字符界面和图形界面)。这些配置工具都是使用脚本语言编写的,如Tcl/TK、Perl等。

使用make config、make menuconfig等命令后生成一个.config配置文件,有什么作用?

记录哪些部分被编译入内核、哪些部分被编译为内核模块。

在Linux 内核中增加程序需要完成哪些工作?

  • 将编写的源代码复制到Linux 内核源代码的相应目录。
  • 在目录的Kconfig文件中增加新源代码对应项目的编译配置选项。
  • 在目录的 Makefile文件中增加对新源代码的编译条目。

为S3C2410 的LED 编写了驱动,源代码为s3c2410-led.c,为使内核能支持对该模块的编译配置,需要完成哪些工作?

  • 将编写的s3c2410-led.c源代码复制到linux-2.6.15.5driverschar 目录。
  • 在目录的Kconfig文件中增加LED 的编译配置选项,如下所示:
代码语言:javascript复制
config S3C2410_LED
bool "S3C2410 LED Driver"
depends on ARCH_S3C2410
help
LED driver for the Samsung S3C2410.
  • 在目录的 Makefile文件中增加对s3c2410-led.c源代码的编译,obj-$(CONFIG_S3C2410_LED) = s3c2410-led.o

kbuild Makefile的语法中目标定义有什么作用?

目标定义,用来定义哪些内容要作为模块编译,哪些要编译并连接进内核

kbuild Makefile的语法中如何进行目标定义?

  1. 例如:obj-y = foo.o
  2. 根据.config 文件的CONFIG_变量来决定文件的编译方式,如下所示:
代码语言:javascript复制
 obj-$(CONFIG_ISDN)  = isdn.o
 obj-$(CONFIG_ISDN_PPP_BSDCOMP)  = isdn_bsdcomp.o

什么是多文件模块的定义?

如果一个模块由多个文件组成,这时候应采用模块名加-objs后缀或者-y后缀的形式来定义模块的组成文件。

如何进行多文件模块的定义?

代码语言:javascript复制
///1---如-y形式
obj-$(CONFIG_EXT2_FS)  = ext2.o
ext2-y := balloc.o bitmap.o
ext2-$(CONFIG_EXT2_FS_XATTR)  = xattr.o

///2---如-objs的形式:
obj-$(CONFIG_ISDN)  = isdn.o
isdn-objs := isdn_net_lib.o isdn_v110.o isdn_common.o

什么是目录层次的迭代?

形如obj-$(CONFIG_EXT2_FS) = ext2/的定义,如果CONFIG_EXT2_FS值为y或m时,kbuild将会把ext2 目录列入向下迭代的目标中,具体ext2 目录下的文件是要作为模块编译还是链入内核由ext2 目录下的Makefile文件的内容决定。

内核配置脚本文件Kconfig的语法中“config”关键字有什么作用?

“config”关键字定义新的配置选项,之后的几行定义了该配置选项的属性。

配置选项的属性有哪些?

类型、数据范围、输入提示、依赖关系(及反向依赖关系)、帮助信息和默认值等

配置选项的类型有哪些?

配置选项都必须指定类型,类型包括bool、tristate、string、hex 和int。

如何指定配置选项的类型?

代码语言:javascript复制
///方法1---:
bool "Networking support"
///方法2----:
bool
prompt "Networking support"

如何定义数据范围?

range <symbol> <symbol> [if <expr>]

数据范围symbol的值如何指定?

symbol 分为两类,一类是由菜单入口定义配置选项定义的非常数symbol,另一类是作为expr 组成部分的常数symbol。为int 和hex 类型的选项设可以接受的输入值范围,用户只能输入大于等于第一个symbol,小于等于第二个symbol 的值。

如何定义输入提示? prompt <prompt> [if <expr>]

如何定义依赖关系?

代码语言:javascript复制
///方法1---
bool "foo" if BAR
default y if BAR
///方法2---
depends on BAR
bool "foo"
default y

depends 能限定一个symbol 的上限,即如果A依赖于B,B的配置如何影响A?

在B被配置为“Y”的情况下,A可以为“Y”、“M”和“N”;在B被配置为“M”的情况下,A可以被配置为“M”或“N”;B在被配置为“N”的情况下,A只能为“N”。

如何定义反向依赖关系?

select <symbol> [if <expr>]

select能限定一个symbol的下限,若A反向依赖于B,B的配置如何影响A?

A的配置值会高于或等于B(正好与depends 相反)。如果symbol 反向依赖于多个对象,则它的下限是这些对象的最大值。

如何定义多个依赖关系?

多个依赖关系之间用“&&”间隔,

如何定义expr(表达式)?

代码语言:javascript复制
 <expr> ::= <symbol>
            <symbol> '=' <symbol>
            <symbol> '!=' <symbol>
            '(' <expr> ')''!' <expr>
             <expr> '&&' <expr>
             <expr> '||' <expr>

如何定义帮助信息?

代码语言:javascript复制
help(或---help---)
开始
…
结束

如何定义配置选项的默认值?

default <expr> [if <expr>]

配置选项的默认值有什么作用?

如果用户不设置对应的选项,配置选项的值就是默认值。

任意多个默认值情况下,如何确定哪个配置选项的默认值是有效的?

存在任意多个默认值情况下,只有第一个被定义的值是可用的。

在菜单树结构中如何确定菜单入口的位置?

  1. 所有处于“menu”和“endmenu”之间的菜单入口都会成为“Network device support”的子菜单。而且,所有子菜单选项都会继承父菜单的依赖关系,比如,“Network device support”对“NET”的依赖被加到了配置选项NETDEVICES的依赖列表中。
  2. 如果菜单选项在一定程度上依赖于前面的选项,它就能成为该选项的子菜单。如果父选项为“N”,则子选项不可见;如果父选项为“Y”或“M”,则子选项可见。MODVERSIONS直接依赖MODULES,如果MODULES不为“N”,该选项才可见。
代码语言:javascript复制
///方法1---
menu "Network device support"
      depends on NET
      config NETDEVICES
…
endmenu

///方法2---
config MODULES
bool "Enable loadable module support"
config MODVERSIONS
bool "Set version information on all module symbols"
depends on MODULES
comment "module support disabled"
depends on !MODULES

在X86 PC上从上电/复位到运行Linux 用户空间,进入与Linux 相关代码之前,会经历哪些阶段?

  1. 当系统上电或复位时,CPU会将PC指针赋值为一个特定的地址0xFFFF0,并执行该地址处的指令。在PC 中,该地址位于BIOS 中,它保存在主板上的ROM 或Flash中。
  2. BIOS运行时按照CMOS的设置定义的启动设备顺序来搜索处于活动状态,并且可以引导的设备。若从硬盘启动,BIOS会将硬盘MBR(主引导记录)中的内容加载到RAM。MBR 是一个512 字节大小的扇区,位于磁盘上的第一个扇区中(0 道0柱面1 扇区)。当MBR被加载到RAM 中之后,BIOS就会将控制权交给MBR。
  3. 主引导加载程序查找并加载次引导加载程序。它在分区表中查找活动分区,当找到一个活动分区时,扫描分区表中的其他分区,以确保它们都不是活动的。当这个过程验证完成之后,就将活动分区的引导记录从这个设备中读入RAM中并执行它。
  4. 次引导加载程序加载Linux内核和可选的初始RAM 磁盘,将控制权交给Linux内核源代码。
  5. 运行被加载的内核,并启动用户空间应用程序。

Linux下的C 编程

Linux中宏定义、变量名、函数名命名习惯是什么?

代码语言:javascript复制
#define PI 3.1415926
int min_value, max_value;//单词之间以_相连
void send_data(void);

如何定义零长数组?

代码语言:javascript复制
struct var_data
{
int len;
char data[0];
};

零长数组有什么作用?

char data[0]仅仅意味着程序中通过var_data 结构体实例的data[index]成员可以访问len 之后的第index 个地址,它并没有为data[]数组分配内存,因此sizeof(structvar_data)=sizeof(int)。

如何利用零长数组访问数据?

代码语言:javascript复制
struct var_data s;
...
for (i = 0; i < s.len; i  )
{
printf("x", s.data[i]);
}

如何使用case语法结构?

代码语言:javascript复制
//case x…y这样的语法,区间[x,y]的数都会满足这个case的条件,
switch (ch)
{
case '0'... '9': c -= '0';
break;
case 'a'... 'f': c -= 'a' - 10;
break;
case 'A'... 'F': c -= 'A' - 10;
break;
}
//代码中的case '0'... '9'等价于标准C中的如下代码:
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':

什么是语句表达式?

包含在括号中的复合语句看做是一个表达式,称为语句表达式,它可以出现在任何允许表达式的地方

如何定义和使用语句表达式?

代码语言:javascript复制
#define min_t(type,x,y) ({ type _ _x = (x); type _ _y = (y); _ _x < _ _y ? _ _x: _ _y; })
int ia, ib, mini;
float fa, fb, minf;
mini = min_t(int, ia, ib);
minf = min_t(float, fa, fb);

typeof 关键字有什么作用?

typeof(x)语句可以获得x 的类型

如何使用typeof 关键字?

通过代码行(void) (&_x == &_y)的作用是检查_x 和_y的类型是否一致

代码语言:javascript复制
#define min(x,y) ({ const typeof(x) _x = (x); const typeof(y) _y = (y); (void) (&_x == &_y); _x < _y ? _x : _y; })

如何定义可变参数的宏?

arg 表示其余的参数可以是零个或多个,这些参数以及参数之间的逗号构成 arg 的值,在宏扩展时替换arg,使用“##”的原因是处理arg 不代表任何参数的情况,这时候,前面的逗号就变得多余了。使用“##”之后,GNU C预处理器会丢弃前面的逗号。

代码语言:javascript复制
#define pr_debug(fmt,arg...) printk(fmt,##arg)
//例如下列代码:
pr_debug("%s:%d",filename,line)
//会被扩展为:
printk("%s:%d", filename, line)

如何使用当前函数名?

_ _FUNCTION_ _保存函数在源码中的名字,_ _PRETTY_FUNCTION_ _保存带语言特色的名字

代码语言:javascript复制
void example()
{
printf("This is function:%s", _ _FUNCTION_ _);
}
//代码中的_ _FUNCTION_ _意味着字符串“example”

什么是特殊属性声明?

GNU C允许声明函数、变量和类型的特殊属性,以便进行手工的代码优化和定制代码检查的方法。

如何进行特殊属性声明?

指定一个声明的属性,只需要在声明后添加__attribute__(( ATTRIBUTE ))。其中ATTRIBUTE 为属性说明,如果存在多个属性,则以逗号分隔。

代码语言:javascript复制
//noreturn
# define ATTRIB_NORET _ _attribute_ _((noreturn)) ....
asmlinkage NORET_TYPE void do_exit(long error_code) ATTRIB_NORET;
//format
asmlinkage int printk(const char * fmt, ...) _ _attribute_ _ ((format(printf, 1, 2)));
//aligned,表示该结构类型的变量以4 字节对界。
struct example_struct{
char a;
int b;
long c;
} _ _attribute_ _((aligned(4)));
//packed
struct example_struct{
char a;
int b;
long c _ _attribute_ _((packed));
};

有哪些特殊属性?

  • noreturn 属性作用于函数,表示该函数从不返回。这会让编译器优化代码,并消除不必要的警告信息
  • format属性也用于函数,表示该函数使用printf、scanf 或strftime 风格的参数,指定format属性可以让编译器根据格式串检查参数类型
  • unused属性作用于函数和变量,表示该函数或变量可能不会被用到,这个属性可以避免编译器产生警告信息。
  • aligned属性用于变量、结构体或联合体,指定变量、结构体或联合体的对界方式,以字节为单位,
  • packed属性作用于变量和类型,用于变量或结构体成员时表示使用最小可能的对界,用于枚举、结构体或联合体类型时表示该类型使用最小的内存

do{}while(0)有什么作用?

保证宏定义的使用者能无编译错误地使用宏,它不对其使用者做任何假设。

用于错误处理的goto使用时需要注意什么?

需保证在错误处理时注销、资源释放的顺序与正常的注册、释放申请的顺序相反。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/184494.html原文链接:https://javaforall.cn

0 人点赞