1.程序员的源码交流平台有哪些?
2.关于Linux内核蓝牙子系统实验,笔者有话要说
3.Linux虚拟网络中的交流macvlan设备源码分析
4.我想加入跟做软件有关的群号
5.详谈实现分页的基本原理以及如何探测物理内存
6.Linux内核黑科技——mmap实现详解
程序员的交流平台有哪些?
GitHub,一个面向开源及私有软件项目的源码托管平台,因其支持Git作为唯一版本库格式而闻名。交流该平台汇集了全球超两千八百万注册用户和七千九百万代码库,源码成为世界最大的交流溯源码服务代码存放网站及开源社区。程序员在这里交流,源码分享代码,交流探寻项目。源码高效使用指南:如何使用GitHub?
Gitee,交流中国版的源码GitHub,提供基于Git的交流代码托管服务。拥有五百万注册开发者和超过一千万代码仓库。源码Gitee提供免费Git仓库、交流代码质量检测、源码项目演示等功能,支持团队协作开发,适用于五人以下小团队,提供项目管理、代码托管、文档管理服务。
Coding,云端开发平台,集代码托管、运行空间、质量控制、项目管理等功能于一体,还包括社会化协作功能和社交元素,方便开发者技术讨论和协作。其代码管理功能与GitHub类似。
掘金,开发者成长社区,内容涵盖前端、后端、Android、iOS、人工智能等,首页文章排名取决于质量与点赞数。掘金还设有各类技术交流群,便于开发者互动。
CSDN,程序员技术博客的发源地,内容限定于计算机领域,汇聚大量技术文章、解决方案、源代码和课程,可学习丰富知识。
博客园,面向开发者的淘宝京东销量源码专业知识分享社区,专注于计算机领域,文章质量上乘,注重首页博文质量,界面简洁,少广告。
知乎,意外的程序员交流平台。作为知识分享社区,知乎集结大量从事互联网行业的用户。知乎对原创知识保护和知识付费的实施,吸引了众多程序员大牛在此开专栏、直播和咨询。
关于Linux内核蓝牙子系统实验,笔者有话要说
FS-MP1A开发板的蓝牙配置涉及AP芯片,通过usart3与SoC进行数据交互。在配置过程中,需要调整设备树与AP_CKKO管脚以适应蓝牙部分的需求。查阅相关文档,如stmmpc-dts.dts,有助于理解配置细节。
若要深入了解,可以加入Linux内核源码交流群(群号:),获取学习资源。群内共享的学习资料包括书籍、视频等,尤其适合希望深入Linux内核学习的读者。前名加入者可额外获得一份价值的内核资料包,包含视频教程、电子书、实战项目及代码。
实验目的是为了熟悉Linux环境下蓝牙设备驱动的移植与配置。实验平台为华清远见开发环境与FS-MP1A平台。具体步骤包括开启.KHz时钟、添加功能管脚配置、以及编译内核和设备树等。
开启.KHz时钟需要修改dts文件,添加对应的RTC节点配置。同时,确保已包含RTC相关头文件,并在dts文件中适当添加或修改配置以适应实际硬件。
在移植过程中,可能需要根据实际情况调整dts文件中的配置,以确保与实际使用的硬件兼容。通过修改或添加配置,确保设备树能正确识别和配置所需硬件。
实验步骤包括:在dts文件中添加或修改配置,编译内核和设备树,然后通过tftp引导内核。悟空打卡的源码在系统启动后,检查/lib/firmware/brcm目录下是否包含BCM.hcd固件。如果未找到此文件,可从特定资源目录拷贝以完成配置。最后,通过命令行开启蓝牙设备,扫描设备以验证配置正确性。
Linux虚拟网络中的macvlan设备源码分析
Linux虚拟网络中的macvlan设备源码分析
macvlan是Linux内核提供的一种新特性,用于在单个物理网卡上创建多个独立的虚拟网卡。支持macvlan的内核版本包括v3.9-3.和4.0+,推荐使用4.0+版本。macvlan通常作为内核模块实现,可通过以下命令检测系统是否支持: 1. modprobe macvlan - 加载模块 2. lsmod | grep macvlan - 确认是否已加载 对于学习和资源分享,可以加入Linux内核源码交流群获取相关学习资料,前名成员可免费领取价值的内核资料包。 macvlan的工作原理与VLAN不同,macvlan子接口拥有独立的MAC地址和IP配置,每个子接口可以视为一个独立的网络环境。通过子接口,macvlan可以实现流量隔离,根据包的目的MAC地址决定转发给哪个虚拟网卡。macvlan的网络模式包括private、vepa、bridge和passthru,分别提供不同的通信和隔离策略。 与传统VLAN相比,macvlan在子接口独立性和广播域共享上有所不同。macvlan的子接口使用独立MAC地址,而VLAN共享主接口的MAC。此外,macvlan可以直接接入到VM或network namespace,而VLAN通常通过bridge连接。 总的来说,macvlan是Linux网络配置中的强大工具,理解其源码有助于深入掌握其内部机制。对于网络配置和性能优化的探讨,可以参考以下文章和视频:Linux内核性能优化实战演练(一)
理解网络数据在内核中流转过程
Linux服务器数据恢复案例分析
虚拟文件系统操作指南
Linux共享内存同步方法
最后,关于macvlan与VLAN的详细对比,以及mactap技术,可以参考相关技术社区和文章,如内核技术中文网。我想加入跟做软件有关的群号
编程技术
源码天空-编程乐园
源码天空-编程乐园二
源码天空-编程乐园三
源码天空-编程乐园四
软件入侵
软件技术
源码天空-兄弟盟
易联网络-网站建设-美工
Delphi技术、控件交流
讨论编程
pb编程,数据库开发,源代码交流
VB编程-技术交流
我是新手请大家多多关照
爱好编程
对DELPHI非常的喜欢,但又不太熟悉,希望能在这里学习
软件交流
源码天空-编程乐园五
感快,名额有限
网站技术
网络的编程笔记源码设置安全需要大家共同的努力……
游戏服务器架设
学习交流
希望对你有帮助 哈哈!
详谈实现分页的基本原理以及如何探测物理内存
分页的基本原理
为了实现对内存的精细化管理,实现分页是关键。这使我们能够管理物理内存和虚拟内存,进而实现多任务并行计算。保护模式下的分页需要分多次描述,此次仅介绍其原理及所需硬件参与情况。
逻辑地址转换为线性地址后,如果没有分页,则直接指向物理地址;若有分页,则需要分页机制进行转换。
转换后的线性地址分为三段:
将线性地址通过分页机制转换为物理地址的流程如下:
文章福利小编推荐自己的Linux内核源码交流群:,整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!前名可进群领取,并额外赠送一份价值的内核资料包(含视频教程、电子书、实战项目及代码)!
学习直通车: Linux内核源码/内存调优/文件系统/进程管理/设备驱动/网络协议栈
以下对上述关键词进行解释:
页框:一个4k字节的连续物理地址的内存单元
页目录表:位页表项列表,大小为4K字节,包含个页目录项
页表:包含个页表项
页表项:用于装载页框,大小4字节,页表项中可能包含页框,也可能不包含。如果页框不存在,则如下所示:
存在位为0,表示无效的页表项。当CPU访问到该页表项时,会触发缺页中断,需要从加载相应的页到这里。
缺页中断需要借助控制寄存器CR2
页框:大小4字节,其中高位为页框地址,低位为页框特性描述字段。
Page Frame Address:页框地址,即物理地址。这个数据结构非常重要,体现了实际的物理地址如何与虚拟地址映射,是实现分页、理解分页的关键。
分页的本质是虚拟化,实现逻辑地址到物理地址的转换,从而能够更灵活、精细地使用内存;通过虚拟化,使进程拥有更大的虚拟内存空间,而在运行时物理内存按需使用。在涉及内存的地方,尽量用自己的理解方式进行讲解,如有不妥之处,精准狙击源码大全敬请谅解。
要启用分页功能,需要以下硬件配合:
以上为实现分页的基本原理,但实现分页并非如此简单。后续章节将讲述如何从代码上实现分页。
后文将分为以下几个步骤分别进行讲解:
探测物理内存
在上文中,我们介绍了保护模式下实现分页的基本原理,现在就看一下在实际中是如何实现的。
具体实现分页,首先需要了解物理内存的大小,然后才能进行分页。
首先,看一下目前的内存视图:
bootloader被BIOS加载到0x7c物理地址处,内核代码被bootloader加载到物理地址0x处,物理内存是在bootloader中利用BIOS的int 中断探测的,然后写入0x物理地址处,然后该数据被内核用来使用,建立物理分页管理系统——页目录表、页表、物理分页分配回收器。
探测物理内存需要借助其他一些东西。
探测物理内存是在内核没有加载之前完成的,内存分页是在加载内核之后完成的,所以这里有个小问题,探测到的物理内存信息在使用时有一点出入,因为探测到的物理内存是有分类的。
在bootloader中,需要借助BIOS的中断功能来实现内存探测。
BIOS是加电后就开始启动的固定在ROM中的一段程序,该程序除了自检功能之外,还带有中断功能。
获取内存是在实模式下,是在bootloader中,所使用的功能是BIOS提供的,提供的方式是通过中断,准确地说,bootloader就是站在BIOS的肩膀上,从这个角度看,操作系统的建设就像一栋大楼,由下而上,在此体现得淋漓尽致。
通过BIOS中断获取内存可调用参数为eh的INT h BIOS中断。BIOS通过系统内存映射地址描述符(Address Range Descriptor)格式来表示系统物理内存布局,具体表示如下:
Values for System Memory Map address type
INTh BIOS中断的详细调用参数:
此中断的返回值为:
通过调用INT h BIOS中断,递增di的值(的倍数),让BIOS帮我们查找出一个一个的内存布局entry,并放入到一个保存地址范围描述符结构的缓冲区中,供后续的内核代码进一步进行物理内存管理
以上内容来源于清华大学实验讲义:
我觉得讲得挺清楚的了
objectkuan.gitbooks.io/...
物理探测代码:
上述代码正常执行完毕后,在0x地址处保存了从BIOS中获得的内存分布信息,此信息按照struct emap的设置来进行填充。这部分信息将在bootloader启动内核后,由内核的page_init函数根据struct emap的memmap(定义了起始地址为0x)来完成对整个机器中物理内存的总体管理。
通过运行代码,我们可以看到实际物理内容的探测如下:
有了物理内存的具体地址,我们就能够对这些内存进行划分,然后进行管理。
如何使用这块信息,实际上在操作系统的代码中,有很多直接操作物理地址或逻辑地址的地方。
其实这个地方是通过将约定好的物理地址信息起始地址强制转换为emap结构体指针类型,然后就可以通过该指针使用物理地址的信息了。
好文推荐:
浅谈ARMLinux内核页表的块映射
内核大神教你从 Linux 进程的角度看 Docker
Linux下CAN总线是如何使用的?
谈谈Linux内存管理的前世今生
深入分析Linux socket 数据发送过程
Linux内核黑科技——mmap实现详解
本文旨在详细阐述 Linux 内核中的 mmap 实现机制。mmap 的全称是 memory map,即内存映射,其功能是将文件内容映射到内存中,允许我们直接对映射的内存区域进行读写操作,效果等同于直接对文件进行读写。 mmap 实现分为两个关键步骤:文件映射和缺页异常处理。首先,使用 mmap() 系统调用时,内核会通过 do_mmap_pgoff() 函数进行处理,这一过程主要是为进程分配虚拟内存空间,并初始化相关数据结构。文件映射则通过 mmmap_region() 函数完成,该函数负责在 vm_area_struct 结构中登记文件信息,以便后续的内存访问操作。 在文件映射阶段,虚拟内存地址会映射到文件的页缓存中。当进程试图访问映射后的虚拟内存地址时,若该地址对应的内容未被加载到物理内存中,则会导致缺页异常。这就是我们接下来要介绍的第二步:缺页异常处理。 当 CPU 触发缺页异常时,内核会调用 do_page_fault() 函数来处理这一异常情况。在这一过程中,文件的页缓存内容会被加载到物理内存中,与虚拟内存地址建立起映射关系。这一机制确保了当进程访问文件内容时,可以无缝地在物理内存和文件之间进行数据交换,从而实现高效的文件读写操作。 综上所述,mmap 通过将文件内容映射到虚拟内存中,允许我们直接对映射区域进行读写操作,而背后的关键在于文件的页缓存与虚拟内存地址之间的动态映射。这一机制是 Linux 内核实现高效文件访问和管理的重要技术之一。 对于需要深入学习 Linux 内核源码、内存调优、文件系统、进程管理、设备驱动、网络协议栈等领域的开发者,推荐加入 Linux 内核源码交流群:,群内提供丰富的学习资源,包括精选书籍、视频资料等,以及价值的内核资料包,包含视频教程、电子书、实战项目及代码。前名加入者还将获得额外赠送的资料。 此外,我们整理了以下精选文章,供对 Linux 内核感兴趣的读者参考:浅谈 ARM Linux 内核页表的块映射
内核大神教你从 Linux 进程的角度看 Docker
Linux 下 CAN 总线是如何使用的?
谈谈 Linux 内存管理的前世今生
深入分析 Linux socket 数据发送过程
盘点那些 Linux 内核调试手段——内核打印
Linux 环境下网络分析和抓包是怎么操作的?
入门篇:进程等待函数wait详解
前言:
编程过程中,有时需要让一个进程等待另一个进程,最常见的是父进程等待自己的子进程,或者父进程回收自己的子进程资源包括僵尸进程。这里简单介绍一下系统调用函数:wait()。
文章福利小编推荐自己的Linux内核源码交流群:整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!!!前名可进群领取,并额外赠送一份价值的内核资料包(含视频教程、电子书、实战项目及代码)!
学习直通车: Linux内核源码/内存调优/文件系统/进程管理/设备驱动/网络协议栈
进程等待的作用:
进程等待的方法(如何让父进程进行进程等待):wait函数和waitpid函数
函数原型:
作用:进程一旦调用了wait,就会立刻阻塞自己,由wait分析当前进程中的某个子进程是否已经退出了,如果让它找到这样一个已经变成僵尸进程的子进程,wait会收集这个子进程的信息,并将它彻底销毁后返回;如果没有找到这样一个子进程,wait会一直阻塞直到有一个出现。参数statloc用来保存被收集进程退出时的一些状态,它是一个指向int型的指针。但如果对这个子进程是如何死掉的不在乎,咱们可以将它设置为NULL:pid = wait(NULL);如果成功,wait会返回被收集的子进程的进程ID,如果调用进程没有子进程,调用会失败,wait返回-1,同时errno会被设置为ECHILD。
运行后:
在第二次打印之前有十秒钟的等待时间,这是我们设置的让子进程睡眠的时间,只有子进程睡眠后醒来,它才能正常退出,也就是能被父进程捕捉到。不管设置多长时间,父进程都会等待下去。
注意:
当父进程忘了用wait()函数等待已终止的子进程时,子进程就会进入一种无父进程的状态,此时子进程就是僵尸进程. wait()要与fork()配套出现,如果在使用fork()之前调用wait(),wait()的返回值则为-1,正常情况下wait()的返回值为子进程的PID. 如果先终止父进程,子进程将继续正常进行,只是它将由init进程(PID 1)继承,当子进程终止时,init进程捕获这个状态. 参数status用来保存被收集进程退出时的一些状态,它是一个指向int类型的指针。但如果我们对这个子进程是如何死掉毫不在意,只想把这个僵尸进程消灭掉,(事实上绝大多数情况下,我们都会这样想),我们就可以设定这个参数为NULL,就像下面这样: pid = wait(NULL); 如果成功,wait会返回被收集的子进程的进程ID,如果调用进程没有子进程,调用就会失败,此时wait返回-1,同时errno被置为ECHILD。 如果参数status的值不是NULL,wait就会把子进程退出时的状态取出并存入其中, 这是一个整数值(int),指出了子进程是正常退出还是被非正常结束的,以及正常结束时的返回值,或被哪一个信号结束的等信息。由于这些信息 被存放在一个整数的不同二进制位中,所以用常规的方法读取会非常麻烦,人们就设计了一套专门的宏(macro)来完成这项工作,下面我们来学习一下其中最常用的两个: 1,WIFEXITED(status) 这个宏用来指出子进程是否为正常退出的,如果是,它会返回一个非零值。 (请注意,虽然名字一样,这里的参数status并不同于wait唯一的参数–指向整数的指针status,而是那个指针所指向的整数,切记不要搞混了。) 2, WEXITSTATUS(status) 当WIFEXITED返回非零值时,我们可以用这个宏来提取子进程的返回值,如果子进程调用exit(5)退出,WEXITSTATUS(status) 就会返回5;如果子进程调用exit(7),WEXITSTATUS(status)就会返回7。请注意,如果进程不是正常退出的,也就是说, WIFEXITED返回0,这个值就毫无意义。
代码示例:wait.c
运行结果:
wait函数:pid_t wait (int* status)
在编码时有一个代码规范:
如果是输入型,参数定义成引用;
如果是输出或者输入输出参数,参数定义成指针;
wait函数的四个特性:
1.输出型参数,与其对应的有:
2.int* status是一个指针类型占四个字节,但是实际中只使用到后两个字节,将这两个字节分为三部分:
退出码:程序正常退出时用到
coredump标志位,退出信号是程序异常退出时用到:
用退出信号判断进程是否正常退出:
产生coredump文件不能判断进程是否正常退出的原因:
1.判断是否有退出信号
2.判断coredump标志位
3.判断退出码
使用wait函数阻止子进程变成僵尸进程
运行情况:
阻塞:
阻塞概念:当调用结果返回之前,当前的执行流会被挂起,并在得到结果之后返回
父进程一直在wait,并没有返回;
对阻塞和非阻塞理解:
1.子进程一种在运行;
2.子进程已退出
对于两种非阻塞的情况,父进程都是直接退出,但是两种情况父进程退出后,一种正常一种不正常
waitpid函数
wait函数的实现是调用waitpid函数实现
我爱内核网 - 构建全国最权威的内核技术交流分享论坛
原文地址: 进程等待函数wait详解 - 进程管理 - 我爱内核网(侵删)
精彩推荐:
如何理解Linux内核下的进程切换
玩转腾讯首发Linux内核源码《嵌入式开发笔记》,也许能帮到你哦
简要分析Linux下多进程的同步和互斥
[实战篇]红黑树在Linux内核中的应用
%Linux使用者都不知道的内存问题
Linux内核映像vmlinux、Image、zImage、uImage区别
vmlinux:Linux内核编译的原始文件,elf格式,未压缩,便于定位内核问题,但不能直接引导系统启动。
Image:在vmlinux基础上,使用objcopy处理后的二进制内核映像,未压缩,直接引导系统启动。
zImage:Image经过gzip压缩,再使用objcopy生成的映像,常见作为uboot的引导文件。
uImage:zImage前面附加字节头信息,描述映像类型、加载位置、大小等,专用于老版本uboot。
zImage与uImage主要区别在于前者是标准的位内核映像,后者为附加额外信息的映像。
Linux映像的生成过程包括从原始vmlinux文件到最终引导映像的转换,过程中涉及文件格式转换和压缩等步骤。
学习资源:参考Linux内核源码地址:ke.qq.com/course/...
群交流:加入Linux内核源码分析交流群(群号:),获取学习资料和书籍,共享在群文件中。
由Docker BUG引起的Linux宕机事故及解决办法
1背景
某运营商业务系统的服务器发生宕机,针对本次宕机事故进行排查。
文章福利小编推荐自己的Linux内核源码交流群: 整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!!!前名可进群领取,并额外赠送一份价值的内核资料包(含视频教程、电子书、实战项目及代码)!
学习直通车: Linux内核源码/内存调优/文件系统/进程管理/设备驱动/网络协议栈
2解决过程
我们都知道kdump是在Linux系统崩溃、死锁、死机的时候用来转储内存运行参数的服务。系统崩溃后内核无法正常工作,这时kdump会产生一个用于capture当前运行信息的内核,将此时的内存中的所有运行状态和数据信息收集到vmcore文件中,收集完成后系统将自动重启。本次使用crash分析linux kdump日志。
进入crash控制台
PANIC为内核崩溃类型,这里是一个BUG,内核无法处理空指针
在crash查看log,发现有很多Out-of-Memory
通过bt查看系统崩溃前内核依次调用的一系列函数,查看内核在何处崩溃。以"# 数字"开头的行为调用堆栈:
通过bt分析,可以定位到崩溃前的一个exception是ip寄存器RIP的异常,使用dis命令来看一下该地址的反汇编结果:
从上面的反汇编结果中,我们看到问题出在ip6mr.c文件行代码,翻开linux源码的相应位置:
撸内核源码 + Google
通过走读Linux源码和Google,发现当系统创建新的namespaces时,会因为ip6mr_sk_done的值为空而引起系统混乱,从而导致内核无法正常分配内存,所以我们在log文件中看到了许多Out-of-Memory。
在Kubernetes环境,提到namespaces就能想到docker,因为namespaces是docker的核心技术之一,容器的资源隔离由namespace来实现。
通过检查docker的网络,发现其中一个子网为空
解决办法
内核配置加入"net.ipv6.conf.all.disable_ipv6 = 1",关闭 IPV6,防止触发 docker BUG;
从内核的层面看,目前该Issue仍然没有close。在开启IPv6的环境,docker为什么会出现这个BUG,后续有空再研究,欢迎大家指正。
3END
Linux 内核虽然号称“不死族”,几乎不会崩溃或死机,但也有特殊情况,设备也有一定的使用周期,系统的高可用还是要的。
虽然你单点运行服务时很帅,但是你处理故障时的样子真的很狼狈。
往期精彩推荐:
最新干货!使用eBPF LSM热修复Linux内核漏洞
盘点那些Linux内核调试手段——内核打印
Linux 环境下网络分析和抓包是怎么操作的?
浅谈ARMLinux内核页表的块映射
Linux性能观测之dstat命令详解