自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(29)
  • 收藏
  • 关注

原创 软总线源码分析7:认证模块

根据上一章节对发现模块的分析,我们知道当发现了外部设备后,InnerDeviceFound会被调用,InnerDeviceFound函数会根据infoNode是否为内部节点,调用回调函数。回想第4章节我们介绍组网模块的时候,组网会调用EnableCoapDisc函数将本地服务发布后,主动发现外部服务,EnableCoapDisc的源码如下:static int32_t EnableCoapDisc(void){ LOG_INFO("EnableCoapDisc begin");

2022-05-20 18:25:31 1482 1

原创 软总线源码分析6:发现模块(二)

继上一章节分析完PublishService接口后,本章节我们开始分析StartDiscovery接口。StartDiscovery接口根据g_discCoapFuncInterface的接口可以知道,当为主动发现时,调用CoapStartAdvertise函数,当为被动发现时,调用CoapSubscribe函数完成对应的处理。下面我们分别介绍这两种实现:CoapStartAdvertiseCoapStartAdvertise的源码如下所示:static int32_t CoapSta

2022-05-05 22:04:47 1460 2

原创 软总线源码分析6:发现模块(一)

软总线主要包括四大模块:发现,连接,组网,传输。今天我们主要详细介绍一下发现模块。之前我们已经介绍过软总线的PublishService接口和StartDiscovery接口。接下来我们分别详细介绍这些接口的实现细节。PublishService接口StartDiscovery接口PostEvent接口在上面我们看到PublishService接口和StartDiscovery接口都通过调用PostEvent来完成具体的业务功能,那么PostEvent主要干了一件什么事呢?以Publ

2022-04-28 16:57:08 2524 3

原创 软总线源码分析5: 组网状态机

组网过程首先需要经过设备认证,认证成功后又要交换设备状态信息,成功后设备间才算组完成工。为了管理组网过程中状态的迁移过程和对应处理,组网模块使用状态机来完成整体的业务逻辑。一.状态机机制状态机由函数LnnFsmInit完成初始化,其源码如下:int32_t LnnFsmInit(FsmStateMachine *fsm, char *name, FsmDinitCallback cb){ if (fsm == NULL || name == NULL) { retur

2022-04-22 18:14:52 1285 1

原创 软总线源码分析4: 接口解析之组网

组网过程

2022-04-13 20:36:30 2059 4

原创 软总线源码分析3:服务加载

软总线作为系统服务,在系统启动,Init进程加载时,通过解析配置文件softbus_server.rc完成系统服务的启动,软总线服务的加载函数为InitSoftBusServer,其源码如下:void InitSoftBusServer(void){ if (SoftBusTimerInit() != SOFTBUS_OK) { return; } if (LooperInit() != SOFTBUS_OK) { return; }

2022-04-01 18:50:39 2115 1

原创 软总线源码分析2: 接口解析之注册服务,发布服务和发现服务

软总线系统本身也是基于IPC对外提供服务,即软总线运行在系统进程中,对外提供一个名为SoftBusServer的服务。但是软总线与IPC系统存在一些区别,即软总线为双向通信系统,所以客户端进程同时会维护一个本地的名为SoftBusClient的服务。即客户端维护SoftBusServerProxy和SoftBusClientStub,软总线维护SoftBusServerStub和SoftBusClientProxy。接口1—注册服务:SoftbusRegisterService当客户端进程想要将

2022-03-28 00:02:54 2403 8

原创 软总线源码分析1:IPC与RPC

从通信两端的位置类看,软总线主要分为IPC与RPC。IPC与RPC使用统一的C/S通信模型,即即Client向Server发送请求,Server返回请求结果。IPC/RPC的主要有三个基础接口:IRemoteBroker, IRemoteStub, IRemoteProxy。还有一个基础类组:BrokerCreator, BrokerDelegator, BrokerRegistration。假设开发过程中需要自定义服务TestService,自定义服务的方法主要分为如下几步:定义服务接口类IT

2022-03-26 18:13:52 4406 3

原创 《Linux内核设计与实现》读书笔记—内核数据结构

链表因为环形双向链表提供了最大的灵活性,所以Linux内核的标准链表就是采用环形双向链表形式实现的。 相比较传统的将数据结构塞入链表的实现,Linux采用将链表节点塞入数据结构的实现方式实现链表,链表的数据结构为struct list_head。 使用container_of(ptr,type,member)或者list_entry(ptr,type,member)宏,便可以返回包含list_head的父类型结构体。 内核提供了一组函数来操作链表,例如list_add()向指定节点后插入一个节点,

2022-02-16 22:01:51 367

原创 《Linux内核设计与实现》读书笔记—调试

通过打印来调试内核提供的打印函数printk()和C库提供的printf()函数功能几乎相同,printk()在任何地方都能调用它,既可以在进程上下文和中断上下文中被调用,也可以在持有锁时被调用,还可以在多处理器上同时被调用。 printk()可以指定一个日志级别,内核根据这个级别来判断是否在终端上打印消息。内核级别最高位KERN_EMERG,最低位KERN_DEBUG,当调用printk()不指定日志等级时,默认的等级位KERN_WARNING。 内核消息都被保存在一个LOG_BUF_LEN大小的

2022-02-15 21:01:30 585

原创 《Linux内核设计与实现》读书笔记—设备与模块

内核的成分主要分为四种:设备类型—为了统一普通设备的操作所采取的分类;模块—内核用于按需加载和卸载目标码的机制;内核对象—内核数据结构中支持面向对象的操作,还可以简单维护对象间的父子关系;sysfs—表示系统设备树的一个文件系统。设备类型Linux中的设备类型主要分为三种:块设备,字符设备和网络设备。 块设备缩写为blkdev,其以块为单位进行寻址,不同的设备类型块大小不同。块设备通常支持重定位操作,即支持对数据的随即访问。 字符设备缩写为cdev,字符设备不可寻址,仅提供数据的流式访问,也就是

2022-02-13 23:56:59 511

原创 《Linux内核设计与实现》读书笔记—页高速缓存和页回写

缓存手段Linux操作系统采用虚拟内存技术,因此系统中的所有进程之间以虚拟方式共享内存。对一个进程而言,它可以访问整个系统的所有物理内存,并且它拥有的地址空间也可以远远大于系统物理内存。...

2022-02-10 21:59:37 515

原创 《Linux内核设计与实现》读书笔记—进程地址空间

地址空间Linux操作系统采用虚拟内存技术,因此系统中的所有进程之间以虚拟方式共享内存。对一个进程而言,它可以访问整个系统的所有物理内存,并且它拥有的地址空间也可以远远大于系统物理内存。 尽管一个进程可以寻址4GB的虚拟内存(以32位的系统为例),但这并不代表它有权访问所有的虚拟地址,进程只能访问有效内存区域内的内存地址。每个内存区域也具有相关权限控制(可读,可写,可执行),如果一个进程访问了非有效内存区域内的地址,或者以不正确的方式访问了有效地址,那么内核就会终止该进程并返回“段错误”信息。 内存

2022-02-07 17:32:22 572

原创 《Linux内核设计与实现》读书笔记—块IO层

块设备设备文件通常分为两大类型:块设备和字符设备。块设备指的是可以随机访问固定大小数据片的硬件设备,例如硬盘,软盘,闪存等。字符设备指的是以字符流方式被访问的硬件设备,比如键盘,串口和网卡。 块设备的管理要比字符设备细致复杂得多,因为字符设备仅仅需要控制一个位置—当前位置,而块设备访问的位置可以在介质的不同区间前后移动。所以内核提供了一个专门的子系统来管理块设备,被称为块IO层。 块设备中最小的可寻址单元是扇区,扇区大小一般是2的整数倍,比如最常见的大小为512字节。扇区的大小是设备的物理熟悉,块设

2022-01-30 17:23:10 812

原创 《Linux内核设计与实现》读书笔记—虚拟文件系统

VFSVFS作为内核子系统,位用户空间提供文件和文件系统相关的接口,如下图所示:VFS使得用户可以直接使用open(),read(),write()这样的系统调用而无需考虑具体文件系统和实际的物理介质。 之所以可以这样使用这种通用接口,是因为内核在底层文件系统接口上建立了一个抽象层,该抽象层提供了一个通用文件系统模型,该模型囊括了任何文件系统的常用功能集和行为。 以用户空间的代码 ret =write(fd,buf,len) 为例,该系统调用的实际行为如下所示:UNIX文件系统Uni

2022-01-29 13:15:09 1231

原创 《Linux内核设计与实现》读书笔记—定时器和时间管理

jiffiesjiffies是一个记录系统自启动到现在的节拍总数的全局变量。 jiffies可以用来执行一些推后固定时间的处理。由于其定义为unsigned long,因此在32为计算机上为一个32bit无符号整数,有溢出的风险。 使用宏time_before(unknown, known)和time_after(unknown, known)来规避掉jiffies溢出翻转的风险。硬时钟和定时器计算机体系结构一般提供两种设备进行计时,一种是实时时钟,一种是设备定时器。 实时时钟(RTC)

2022-01-21 00:08:06 435

原创 《Linux内核设计与实现》读书笔记—内核同步技术

同步技术简介在中断处理程序中能避免并发访问的安全代码被称为中断安全代码;在多核处理程序中能避免并发访问的安全代码被称为SMP安全代码;在内核抢占时能避免并发访问的安全代码被称为抢占安全代码。 避免死锁的重点一般如下:按顺序加锁,使用嵌套的锁时必须以相同的顺序获取锁 防止发生饥饿,试问,如果A不发生,B要一直等下去么? 不要重复请求同一个锁 设计应力求简单,却复杂的加锁方案越容易造成死锁设计初期,加锁方案应该力求简单,仅当需要时再进一步优化加锁方案原子操作原子类型的数据定义为atom

2022-01-09 17:45:46 579

原创 《Linux内核设计与实现》读书笔记—中断下半部

下半部简介下半部的任务就是执行与中断处理密切相关但中断处理程序本身不执行的工作。 如果一个任务对时间非常敏感,则应放到中断处理程序中执行。如果一个任务和硬件相关,将其放在中断处理程序中执行。如果一个任务要保证不被其他中断打断,将其放在中断处理程序中执行。其他所有任务,考虑放置在下半部中执行。 Linux内核常用的下半部机制包括:任务队列,软中断,Tasklet和内核定时器 软中断是一组静态定义的接口,总共有32个,可以在所有处理器上同时执行,即使是同类型的也可以。 Tasklet是一种基于软中断

2022-01-09 17:43:42 170

原创 《Linux内核设计与实现》读书笔记—中断与系统调用

系统调用简介在Linux中,每个系统调用被赋予一个系统调用号,用户空间的进程执行一个系统调用时,这个系统调用号就用来指明到底是要执行哪个系统调用。 用户空间的程序无法直接执行内核代码,因为内核驻留在受保护的地址空间上。所以,当用户进程执行系统调用时,通过软中断陷入到内核中,内核上该软中断对应的异常处理程序通过读取对应的系统调用号,知道用户进程执行了那种系统调用后,变开始执行对应的系统调用处理程序完成任务。 内核提供了copy_to_user()和copy_from_user()两个函数来分别完成向用

2022-01-09 17:42:27 346

原创 《Linux内核设计与实现》读书笔记—进程调度

进程调度进程调度程序决定将哪个进程投入运行,何时运行以及运行多长时间。进程调度程序可看做在可运行态进城之间分配有限的处理器时间资源的内核子系统。 多任务系统可以划分为两类:非抢占式和抢占式。Linux提供了抢占式的多任务模式,在此模式下,由调度程序来决定什么时候停止一个进程的运行,以便其他进程能够得到执行机会,这个强制的挂起动作就叫做抢占。 当今众多现代操作系统对程序运行都采用了动态时间片计算的方式,并且引入了可配置的计算策略。不过Linux独一无二的"公平"调度程序本身并没有采取时间片来达到公平调

2022-01-09 17:38:36 182

原创 《Linux内核设计与实现》读书笔记—进程管理

进程进程并不仅仅局限于一段可执行程序代码。通常进程还要包含其他资源,像打开的文件,挂起的信号,内核内部数据,处理器状态,一个或多个具有内存映射的内存地址空间,一个或多个执行线程,存放全局变量的数据段。 每个线程都拥有一个独立的线程栈,线程寄存器和程序计数器。一般会在栈顶创建一个结构体struct Thread_Info,该数据结构中保存指向进程描述符task_struct的指针。 内核通过一个唯一的进程标识符PID来 标识每个进程 一个进程必然处于五种进程状态中的一种:TASK_RUNN

2022-01-09 17:35:34 389

原创 程序的链接和装载(3)--目标文件(.o/.obj)

我们经过编译的目标文件,里面到底存放的内容是什么呢?其实,目标文件本身已经是编译后的可执行文件了,只是还没有经过链接,所以内部很多符号还没有分配地址。其实目标文件本身就是按照可执行文件的格式进行存储的,只是目标文件和可执行文件在文件结构上略微有些区别。 1.目标文件的格式 目前主流的pc平台所流行的可执行文件格式主要分为两种,一种是Windows下的PE(Portable Executable),另一种是Linux下的ELF(Executable Linkable Format),它...

2022-01-09 17:27:17 857

原创 《Linux内核设计与实现》读书笔记—内存管理

页页表查询的过程由硬件完成,但是页表的维护需要软件完成,处理器的MMU单元负责把虚拟地址转换成物理地址 当处理器发现虚拟地址无法通过页表映射到对应的物理地址时,就会触发一个缺页异常,挂起出错的进程,操作系统软件需要处理这个缺页异常。 一个页表可以由页缓存使用,可以作为私有数据,也可以作为进程页表中的映射 page结构是和物理页相关联的,而不是和虚拟页相关联的。内核用这一数据结构来知道一个页是否空闲,如果页被分配的话,谁拥有这个页,是用户空间进程、动态分配的内核数据还是静态内核代码或页高速缓存。区

2022-01-09 17:23:08 414

原创 程序的链接和装载(6)--链接过程控制

正常情况下,我们使用链接器的默认规则对目标文件进行链接是没问题的。但是在一些特殊的场景,比如操作系统内核,BIOS,嵌入式软件,BootLoader,内核驱动程序下,因为一些受限制的条件,我们需要显示的指明程序的各个段的起始地址,段的名称,段存放的顺序等等。 而且连接过程中有很多内容需要我们显示的确定,比如该使用哪些目标文件,使用哪些库文件,是否在最终的可执行文件中保留调试信息,输出哪种文件格式(可执行程序还是动态链接库程序)等等。 因此这些场景下我们需要自己控制链接的过程。控制...

2021-10-14 17:11:48 258

原创 程序的链接和装载(5)--静态链接

通过前文我们已经对目标文件和符号有了一个较为清晰的理解,接下来,我们将以下面两个源文件作为一个例子阐述一下静态链接的处理过程。/* a.c */extern int shared;extern void swap(itn *a, int *b);int main(){ int a = 100; swap(&a, &shared); return 0;} /* b.c */int shared = 1;void swap(int *a, ...

2021-10-14 17:07:34 139

原创 程序的链接和装载(4)--符号

正如我们前文所提到的,符号是链接过程的粘合剂,它为众多目标文件提供接口,使得众多目标文件能够正确的链接在一起。因此,本文我们将详细介绍符号表的内容已经符号在链接过程中的作用。 1. ELF符号表结构 目标文件中的符号表其实也是一个段,段名往往叫作“.symtab”,类型为SYMTAB,符号表也是一个结构体数组,每个符号的结构体如下所示,它包含了该符号的符号名,所在段的索引,该符号的值,该符号的长度等等信息。 符号绑定属性分为STB_LOCAL,STB_G...

2021-10-14 17:02:47 262

原创 程序的链接和装载(2)--链接概述

为了能够更好地理解计算机程序中编译和链接的过程中,我们简单地回顾一下计算机程序开发的历史。在最开始的时候,计算机程序的开发并没有如此庞大复杂的自动化编译链接构建工具来帮忙,那个时代的程序员,往往是先把程序写在卡带上,再由计算机读取卡带中的点阵来执行程序。所以当时并没有现如今功能如此强大的编程语言,而是使用机器语言进行编程。 假设我们的计算机,每条指令占1个字节8bit,而有一种跳转指令,高4位为0001,表示该指令为跳转指令。低4位表示指令跳转的绝对地址。那么从如下机器码中我们可知,地址0...

2021-10-14 16:40:11 162

原创 程序的链接和装载(1)--被隐藏的处理

在当今这个时代,我们有着各种各样非常强大的集成开发工具,得益于它们那些强大的诸如符号解析,引用构建,代码补全,一键式编译,类库支持等等功能,我们可以从工程本身的结构中抽身出来,专注于业务和功能。但是,不好的一点在于,对于很多新手来说,IDE便成为了一个夹在源代码和可执行文件中间的黑盒,那些被隐藏的处理一旦出现了错误,他们往往不知道如何去解决这些问题。 以下面这段几乎每个程序员都能闭眼写出的HelloWorld而言,在linux下当我们执行 "gcc Hello.c -o Hello"后,最...

2021-10-14 16:29:03 143

原创 程序的链接和装载(0)--引言

相信绝大多数程序员都有着和我相似的经历:在大一的时候,在一门或者叫做《程序设计基础》或者叫做《C语言》的课程里,写下了人生第一个程序,然后点击着VC6那个经典的运行键,看到屏幕上打出了一行“Hello World”。那个时候并不会想太多,总觉得写好代码,按下运行键,看着屏幕弹出的cmd窗口打印着我写下的逻辑,这一切似乎都是那么理所当然。 后来学习了更多知识,知道了计算机体系结构,知道了操作系统,知道了编译原理,知道了我们的C代码是依靠编译器编译成了二进制的机器码,才能再计算机中运行。...

2021-10-14 15:26:12 117

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除