linux 内核(系统)、函数的理解、宏的程序调试


1、操作系统

1.1、Linux 内核(系统)的组成的部分:

    内核主要有:进程调度、内存管理、虚拟文件系统、网络接口和进程通信五个部分组成。

                                            

(1)进程调度

    进程调度是CPU对多个进程对CPU访问的调度算法,使得进程宏观上并行执行。常用的调度算法有:先来先服务原则、高优先级别优先、短进程优先(谁执行的时间短,就上)、时间片轮训(每个进程都给点时间运行)。

    系统所有的进程,都必须使用进程调度算法,所以是处于中心的位置。

(2)内存管理

    内存管理的主要作用是管理进程之间内存。

    一般对于 32位的 Linux 系统而言,Linux进程都拥有自己独立的4GB的内存空间,0~3GB的用户空间,3~4GB的内核空间。

                                  

(3)虚拟文件系统

    Linux的虚拟文件系统(VFS)是实际文件系统的一种抽象,为所有的设备统一的接口。显示的文件系统:比如有 FAT16、FAT32、NTFS、YAFFS、JFFS2,ext,ext2,这么多的不同格式的系统,不同的格式有属于自己的一套文件操作数据据结构(file_operation)、那么写应用层代码的时候,难道要对这么多的文件系统做不同的处理操作么么,这个时候,虚拟文件系统就产生了,虚拟文件系统统一管理这些现实的的文件系统,然后提供统一的接口,这样应用层就可以使用统一的open read write 去访问了。

(4)网络接口

    网络接口实现了对各种的网络标准的存取和各种网络硬件的支持。所以网络接口可以分为网络协议和网络驱动程序。

    网络协议实现的是每一种网络传输协议,比如说TCP/IP协议具体是怎么实现的,

    网络驱动:其实就是网络硬件设备的驱动,实现硬件的这部分驱动。

(5)进程通信

    Linux进程间通信(IPC),包含:管道(无名管道和有名管道)、信号、消息队列、共享内存、套接字、信号量。

1.2、C库函数与API

    对于向外提供的 API 而言,有操作系统的提供的 API 和C库提供的 API。比如对

文件的操作而言: open、write、read、close。而C库提供的接口: fopen、fwrite、fread、fclose。本质上,fopen 就是使用 open 函数进行而二次封装。

    对于不同的系统而言,系统提供的 API 几乎都是不同的;而对于 C库 而言,不同的平台只要使用的是 C库,C库 的API 都是一样的,所以对于移植性的话,C库的移植性就高。


2、函数的理解

    通常来说,不论大大小小的子函数都是会存在一个返回值,函数的返回值一般都是不会直接使用void 类型。之所以函数即使不会被调用也都是会执行一个返回值:

    (1)首先,在C语言中,一般是,返回值为零,一般是正常退出,而返回值为负一的情况的话,就是出现异常,而返回值是正直的话,那么一般就是自己定义的。


return 0;
    return -1;
    return 1;

    (2)return 语句的话,那么就表示函数的代码到这里就已经是全部结束了。

    (3)函数的返回值与输入的参数可以理解为原材料以及经过加工(函数体)之后的产品。

3、NULL的理解

(1)NULL 的定义


#ifdef __cplusplus
#define NULL    0
#else  /* __cplusplus */
#define NULL    ((void *)0)
#endif  /* __cplusplus */
#endif  /* NULL */

    当定义了 __cplusplus 宏的时候,则 NULL 为零,也就是当编译器为 C++ 的时候,则 NULL为零;而是 C 编译器的时候,则 NULL 为 (void *)0。这里的零可以理解为:数字零以及地址零,具体的环境具体分析。

(2)NULL 的作用

让野指针指向安全零地址

一般指针定义的时候:


int *p = NULL;

    其将 p 指向地址零,因为一般来说零地址都是不可以被随便访问的。

(3)NULL 与 ‘\0‘、‘0‘、0

‘\0‘ :是一个转义的字符,对应的 ASCII 是 0
‘0‘ : 是一个字符,对应的 ASCII 是 48
0 : 是一个数字,本质就是零,对用的 ASCII 也是零。
NULL :是一个表达式,NULL 的本质就是 0。

注意:

    ‘\0‘ : 是字符串的结束的标志。

    ‘0‘ : 对应零这个字符的 ASCII,一般用于获取零的 ASCII 值。

    0 : 数字,

    NULL : 一般用于指针。

4、宏的调试

    宏的调试的方法是非常的方便,

应用调试:


#ifdef DEBUG
#define DBG(...) fprintf(stderr, " DBG(%s, %s(), %d): ", __FILE__, __FUNCTION__, __LINE__); fprintf(stderr, __VA_ARGS__)
#else
#define DBG(...)
#endif

    打印当前的文件、函数、行号。

__VA_ARGS__ :是将 DBG 括号里面的转为实际的字符串。当取消了 DEBUG 的定义,则后面的调试信息doing不会被编译进去已经打印出信息。

内核的调试:


#define DEBUG(fmt, args...)     printk(fmt, ##args)
#else
#define DEBUG(fmt, args...)     do {} while (0)
#endif

    ... : 三点表示的变参,也就是参数的个数是不定的。对于变参的理解在另外的帖子做详细的介绍。

时间: 2024-12-22 15:36:41

linux 内核(系统)、函数的理解、宏的程序调试的相关文章

从Linux内核LED驱动来理解字符设备驱动开发流程

目录 博客说明 开发环境 1. Linux字符设备驱动的组成 1.1 字符设备驱动模块加载与卸载函数 1.2 字符设备驱动的file_operations 结构体中的成员函数 2. 字符设备驱动--设备号注册卸载 2.1 设备号注册 2.2 设备号注销 3. 字符设备驱动--文件操作 参考资料 示例代码 @(从Linux内核LED驱动来理解字符设备驱动开发流程) 博客说明 撰写日期 2018.12.08 完稿日期 2019.10.06 最近维护 暂无 本文作者 multimicro 联系方式 [

[转帖]Linux内核系统体系概述

Linux内核系统体系概述 https://www.cnblogs.com/alantu2018/p/8447369.html Linux 内核主要由 5 个模块构成,它们分别是: 进程调度模块 用来负责控制进程对 CPU 资源的使用.所采取的调度策略是各进程能够公平合理地访问 CPU,同时保证内核能及时地执行硬件操作. 内存管理模块 用于确保所有进程能够安全地共享机器主内存区,同时,内存管理模块还支持虚拟内存管理方式,使得 Linux 支持进程使用比实际内存空间更多的内存容量.并可以利用文件系

linux 内核网络协议栈阅读理解--带详尽注释以及相关流程调用注释,附 github 注释后源码

linux 内核网络协议栈阅读理解--带详尽注释以及相关流程调用注释,对理解内核协议栈源码很有帮助 对理解阅读 linux 协议栈源码很用帮助 github 地址: https://github.com/y123456yz/Reading-and-comprehense-linux-Kernel-network-protocol-stack

嵌入式linux 内核关机函数实现

arch/arm/kernel/process.c 实现pm_power_off = 关机函数 参考 board-omap3touchbook.c 文件中 pm_power_off = omap3_touchbook_poweroff; static void omap3_touchbook_poweroff(void) { int pwr_off = TB_KILL_POWER_GPIO; if (gpio_request_one(pwr_off, GPIOF_OUT_INIT_LOW, "D

linux内核头文件kdev_t.h 宏定义解析

kdev_t.h 宏定义解析 这个header file反正不多,直接原因是--遇到了,就搞定它! dev_t 类型的变量定义在linux/types.h 用来保存设备编号--包括主设备号和次设备号.dev_t 是一个32位的数,其中12位用来表示设备号,其余20位用来表示次设备号. 始终不要对这32位是高12位是主设备号还是低2位是主设备号做出假定,不利于代码的可移植性,始终记得使用宏定义来处理dev_t ! 都在这里了: #define MINORBITS 20 //次设备号的占位数目 #d

Linux内核d_path函数应用的经验总结

问题背景 一个内核模块中,需要通过d_path接口获取文件的路径,然后与目标文件白名单做匹配. 在生产环境中,获取的文件是存在的,但是与文件白名单中的文件总是匹配失败. 问题定位: 通过打印d_path返回的字符串,发现获得的路径后面多了一个" (deleted)"字符串,在做完全匹配时不通过. 看了d_path函数说明:如果entry被删除了,会添加" (deleted)"字符串. * Convert a dentry into an ASCII path nam

Linux内核系统体系概述

Linux 内核主要由 5 个模块构成,它们分别是: 进程调度模块 用来负责控制进程对 CPU 资源的使用.所采取的调度策略是各进程能够公平合理地访问 CPU,同时保证内核能及时地执行硬件操作. 内存管理模块 用于确保所有进程能够安全地共享机器主内存区,同时,内存管理模块还支持虚拟内存管理方式,使得 Linux 支持进程使用比实际内存空间更多的内存容量.并可以利用文件系统把暂时不用的内存数据块会被交换到外部存储设备上去,当需要时再交换回来. 文件系统模块 用于支持对外部设备的驱动和存储.虚拟文件

标准c库函数与Linux下系统函数库 区别 (即带不带缓冲区的学习)

我们都知道,C语言在UNIX/Linux系统下有一套系统调用(系统函数),比如文件操作open().close().write().read()等,而标准C语言的库函数中也有一套对文件的操作函数fopen().fclose().fwrite().fread()等..那么同样是对文件的操作函数,标C与UC有什么区别呢?是标C效率高还是UC效率高呢?今天就让我们来一探究竟. 程序作用:将0~999999这1000000个整型数据写入文件. 1.标准C实现大量数据写入文件: /*文件名test1.c*

Linux内核@系统组成与内核配置编译

Linux系统由什么组成? 由用户空间(应用程序+GNU C标准库)和内核空间(系统调用接口+内核+内核架构代码)组成. Linux内核到底是什么?以及组成. ARM的七种操作级别? 内核网络协议栈(Network Stack)的作用? 为Linux提供了丰富的网络协议(TCP/IP.PPPOE)实现.将网络协议栈放在内核中为了提高网络性能,减少CPU开销. 虚拟文件系统的作用? 为了支持多种文件系统,并为它们提供统一的操作接口. Linux内核源代码结构 关于每个文件夹中的具体内容分析:参考h