本文是一篇LoRaWAN的科普介绍,你已经在朋友圈看过无数蜻蜓点水的LoRaWAN文章,是时候来一篇真正的技术干货了。 本文先从横向介绍下LoRaWAN的背后势力和网络部署情况,然后纵向讲解了网络架构和具体的协议内容,帮助LoRa从业者系统地了解LoRaWAN协议。
简介
本文介绍一个IPQ4019的MTD分区信息是如何从配置文件一步步传递到linux内核的。 这个过程有几个部分组成,分区信息在编译过程中的传递;升级时写入flash区;设备上电时linux如何得到分区信息。
启动图解如下:linux内核启动完成后,执行的第一个程序中/etc/preinit。此时环境变量PREINIT为空,所以马上执行/sbin/init/sbin/init是由procd/init.c编译而来。主要过程如下: /sbin/kmodloader 加载内核模块 执行一些early cmdline等 ...
在前两篇中我们了解了DTS的背景基础知识以及发挥作用的流程,这篇文章我们以高通的MSM8953平台为例来添加一个基础的i2c设备(包含一个gpio中断)。
Linux DTS(Device Tree Source)设备树详解之二(dts匹配及发挥作用的流程篇)
什么是DTS?为什么要引入DTS?
DTS即Device Tree Source 设备树源码, Device Tree是一种描述硬件的数据结构,它起源于 OpenFirmware (OF)。 在Linux 2.6中,ARM架构的板极硬件细节过多地被硬编码在arch/arm/plat-xxx和arch/arm/mach-xxx,比如板上的platform设备、 resource、i2c_board_info、spi_board_info以及各种硬件的platform_data,这些板级细节代码对内核来讲只不过是垃圾代码。 而采用Device Tree后,许多硬件的细节可以直接透过它传递给Linux,而不再需要在kernel中进行大量的冗余编码。 每次正式的linux kernel release之后都会有两周的merge window,在这个窗口期间,kernel各个部分的维护者都会提交各自的patch, 将自己测试稳定的代码请求并入kernel main line。每到这个时候,Linus就会比较繁忙,他需要从各个内核维护者的分支上取得最新代码 并merge到自己的kernel source tree中。Tony Lindgren,内核OMAP development tree的维护者,发送了一个邮件给Linus, 请求提交OMAP平台代码修改,并给出了一些细节描述:
简介
本文介绍一个IPQ4019的MTD分区信息是如何从配置文件一步步传递到linux内核的。 这个过程有几个部分组成,分区信息在编译过程中的传递;升级时写入flash区;设备上电时linux如何得到分区信息。
asort和asorti
简介
在内存发生panic时,需要把panic的日志保存下来。以方便日后进行分析。 目前有三种记录的方式: kdump; mtdoops; crashlog(这是openwrt特别的功能,正式linux内核中没有) 大家对kdump比较了解。它主要使用于x86系统。因为它使用占用大量内存和硬盘。 mtdoops和crashlog主要用于嵌入式的环境。也只是记录文本日志。
MCS速率计算公式
三 代码基本结构(Code Base Structure)
二 WLAN驱动设计
一 Wireless LAN简介
协议栈数据包走向图
Introduction
为调试Linux机器上的C/C++程序,我们通常使用GDB. 但要调试那些在路由器上跑的C/C++程序, GDB还能胜任么?毕竟,我们又不能直接把源码搁到路由器上编译,在Linux机器上编的话还牵扯到交叉编译(Cross Compiling)。
dnsmasq的简介
Dnsmasq 提供 DNS 缓存和 DHCP 服务功能。作为域名解析服务器(DNS),dnsmasq可以通过缓存 DNS 请求来提高对访问过的网址的连接速度。作为DHCP 服务器,dnsmasq 可以用于为局域网电脑分配内网ip地址和提供路由。 DNS和DHCP两个功能可以同时或分别单独实现。dnsmasq轻量且易配置,适用于个人用户或少于50台主机的网络。此外它还自带了一个 PXE 服务器。。
使用 iptables 封 IP,是一种比较简单的应对网络攻击的方式,也算是比较常见。 有时候可能会封禁成千上万个 IP,如果添加成千上万条规则,在一台注重性能的服务器 或者本身性能就很差的设备上,这就是个问题了。ipset 就是为了避免这个问题而生的。
一、进程调度 调度的发生有两种方式1、主动式在内核中直接调用schedule()。当进程需要等待资源等而暂时停止运行时,会把状态置于挂起(睡眠),并主动请求调度,让出CPU。主动放弃cpu例: current->state = TASK_INTERRUPTIBLE; schedule();2、被动...
作为Linux下的程序开发人员,大家一定都遇到过Makefile, 用make命令来编译自己写的程序确实是很方便。一般情况下,大家都是手工写一个简单Makefile, 如果要想写出一个符合自由软件惯例的Makefile就不那么容易了。
作为Linux下的程序开发人员,大家一定都遇到过Makefile, 用make命令来编译自己写的程序确实是很方便。一般情况下,大家都是手工写一个简单Makefile, 如果要想写出一个符合自由软件惯例的Makefile就不那么容易了。
第 1 部分: Linux 应用层的时间编程
本贴主要讲解 Bootloader 是如何在使用 SPI Flash 的 AR/QCA 的芯片上启动的, 以及 OpenWrt 代码 ar71xx 的 mach 文件中类似于 u8 *art = KSEG1ADDR(0x1fff0000) 中 0x1fff0000 是如何得来的。 楼主之前在 U-Boot 编译教程中进行过简单的描述,但是因为实在是太简略了,所以打算写一个详细版的。
git logA—B—E—F <==(master) -–C—D <==(experimet)两点(..)表示查看experiment上还没有合并到master的commit,换句话说:所有experiment能读取到但master读取不到的commit对象$ git log master..e...
IE802.11简介
TKIP加密过程
介绍WLAN QoS的定义、由来和作用。
当一个程序发生故障时,有时候想通过了解该进程正在执行的系统调用来排查问题。 通常可以用 strace 来跟踪。但是当进程已经处于 D 状态(uninterruptible sleep)时,strace 也帮不上忙。这时候可以通过
我们理解您需要更便捷更高效的工具记录思想,整理笔记、知识, 并将其中承载的价值传播给他人,Cmd Markdown 是我们给出的答案 —— 我们为记录思想和分享知识提供更专业的工具。 您可以使用 Cmd Markdown:
指令 | 功能 | 应用实例 |
---|---|---|
LB | 从存储器中读取一个字节的数据到寄存器中 | LB R1, 0(R2) |
LH | 从存储器中读取半个字的数据到寄存器中 | LH R1, 0(R2) |
LW | 从存储器中读取一个字的数据到寄存器中 | LW R1, 0(R2) |
LD | 从存储器中读取双字的数据到寄存器中 | LD R1, 0(R2) |
L.S | 从存储器中读取单精度浮点数到寄存器中 | L.S R1, 0(R2) |
L.D | 从存储器中读取双精度浮点数到寄存器中 | L.D R1, 0(R2) |
LBU | 功能与LB指令相同,但读出的是不带符号的数据 | LBU R1, 0(R2) |
LHU | 功能与LH指令相同,但读出的是不带符号的数据 | LHU R1, 0(R2) |
LWU | 功能与LW指令相同,但读出的是不带符号的数据 | LWU R1, 0(R2) |
SB | 把一个字节的数据从寄存器存储到存储器中 | SB R1, 0(R2) |
SH | 把半个字节的数据从寄存器存储到存储器中 | SH R1,0(R2) |
SW | 把一个字的数据从寄存器存储到存储器中 | SW R1, 0(R2) |
SD | 把两个字节的数据从寄存器存储到存储器中 | SD R1, 0(R2) |
S.S | 把单精度浮点数从寄存器存储到存储器中 | S.S R1, 0(R2) |
S.D | 把双精度数据从存储器存储到存储器中 | S.D R1, 0(R2) |
DADD | 把两个定点寄存器的内容相加,也就是定点加 | DADD R1,R2,R3 |
DADDI | 把一个寄存器的内容加上一个立即数 | DADDI R1,R2,#3 |
DADDU | 不带符号的加 | DADDU R1,R2,R3 |
DADDIU | 把一个寄存器的内容加上一个无符号的立即数 | DADDIU R1,R2,#3 |
ADD.S | 把一个单精度浮点数加上一个双精度浮点数,结果是单精度浮点数 | ADD.S F0,F1,F2 |
ADD.D | 把一个双精度浮点数加上一个单精度浮点数,结果是双精度浮点数 | ADD.D F0,F1,F2 |
ADD.PS | 两个单精度浮点数相加,结果是单精度浮点数 | ADD.PS F0,F1,F2 |
DSUB | 两个寄存器的内容相减,也就是定点数的减 | DSUB R1,R2,R3 |
DSUBU | 不带符号的减 | DSUBU R1,R2,R3 |
SUB.S | 一个双精度浮点数减去一个单精度浮点数,结果为单精度 | SUB.S F1,F2,F3 |
SUB.D | 一个双精度浮点数减去一个单精度浮点数,结果为双精度浮点数 | SUB.D F1,F2,F3 |
SUB.PS | 两个单精度浮点数相减 | SUB.SP F1,F2,F3 |
DDIV | 两个定点寄存器的内容相除,也就是定点除 | DDIV R1,R2,R3 |
DDIVU | 不带符号的除法运算 | DDIVU R1,R2,R3 |
DIV.S | 一个双精度浮点数除以一个单精度浮点数,结果为单精度浮点数 | DIV.S F1,F2,F3 |
DIV.D | 一个双精度浮点数除以一个单精度浮点数,结果为双精度浮点数 | DIV.D F1,F2,F3 |
DIV.PS | 两个单精度浮点数相除,结果为单精度 | DIV.PS F1,F2,F3 |
DMUL | 两个定点寄存器的内容相乘,也就是定点乘 | DMUL R1,R2,R3 |
DMULU | 不带符号的乘法运算 | DMULU R1,R2,R3 |
MUL.S | 一个双精度浮点数乘以一个单精度浮点数,结果为单精度浮点数 | DMUL.S F1,F2,F3 |
MUL.D | 一个双精度浮点数乘以一个单精度浮点数,结果为双精度浮点数 | DMUL.D F1,F2,F3 |
MUL.PS | 两个单精度浮点数相乘,结果为单精度浮点数 | DMUL.PS F1,F2,F3 |
AND | 与运算,两个寄存器中的内容相与 | ANDR1,R2,R3 |
ANDI | 一个寄存器中的内容与一个立即数相与 | ANDIR1,R2,#3 |
OR | 或运算,两个寄存器中的内容相或 | ORR1,R2,R3 |
ORI | 一个寄存器中的内容与一个立即数相或 | ORIR1,R2,#3 |
XOR | 异或运算,两个寄存器中的内容相异或 | XORR1,R2,R3 |
XORI | 一个寄存器中的内容与一个立即数异或 | XORIR1,R2,#3 |
BEQZ | 条件转移指令,当寄存器中内容为0时转移发生 | BEQZ R1,0 |
BENZ | 条件转移指令,当寄存器中内容不为0时转移发生 | BNEZ R1,0 |
BEQ | 条件转移指令,当两个寄存器内容相等时转移发生 | BEQ R1,R2 |
BNE | 条件转移指令,当两个寄存器中内容不等时转移发生 | BNE R1,R2 |
J | 直接跳转指令,跳转的地址在指令中 | J name |
JR | 使用寄存器的跳转指令,跳转地址在寄存器中 | JR R1 |
JAL | 直接跳转指令,并带有链接功能,指令的跳转地址在指令中,跳转发生时要把返回地址存放到R31这个寄存器中 | JAL R1 name |
JALR | 使用寄存器的跳转指令,并且带有链接功能,指令的跳转地址在寄存器中,跳转发生时指令的放回地址放在R31这个寄存器中 | JALR R1 |
MOV.S | 把一个单精度浮点数从一个浮点寄存器复制到另一个浮点寄存器 | MOV.S F0,F1 |
MOV.D | 把一个双精度浮点数从一个浮点寄存器复制到另一个浮点寄存器 | MOV.D F0,F1 |
MFC0 | 把一个数据从通用寄存器复制到特殊寄存器 | MFC0 R1,R2 |
MTC0 | 把一个数据从特殊寄存器复制到通用寄存器 | MTC0 R1,R2 |
MFC1 | 把一个数据从定点寄存器复制到浮点寄存器 | MFC1 R1,F1 |
MTC1 | 把一个数据从浮点寄存器复制到定点寄存器 | MTC1 R1,F1 |
LUI | 把一个16位的立即数填入到寄存器的高16位,低16位补零 | LUI R1,#42 |
DSLL | 双字逻辑左移 | DSLL R1,R2,#2 |
DSRL | 双字逻辑右移 | DSRL R1,R2,#2 |
DSRA | 双字算术右移 | DSRA R1,R2,#2 |
DSLLV | 可变的双字逻辑左移 | DSLLV R1,R2,#2 |
DSRLV | 可变的双字罗伊右移 | DSRLV R1,R2,#2 |
DSRAV | 可变的双字算术右移 | DSRAV R1,R2,#2 |
SLT | 如果R2的值小于R3,那么设置R1的值为1,否则设置R1的值为0 | SLT R1,R2,R3 |
SLTI | 如果寄存器R2的值小于立即数,那么设置R1的值为1,否则设置寄存器R1的值为0 | SLTI R1,R2,#23 |
SLTU | 功能与SLT一致,但是带符号的 | SLTU R1,R2,R3 |
SLTUI | 功能与SLT一致,但不带符号 | SLTUI R1,R2,R3 |
MOVN | 如果第三个寄存器的内容为负,那么复制一个寄存器的内容到另外一个寄存器 | MOVN R1,R2,R3 |
MOVZ | 如果第三个寄存器的内容为0,那么复制一个寄存器的内容到另外一个寄存器 | MOVZ R1,R2,R3 |
TRAP | 根据地址向量转入管态 | |
ERET | 从异常中返回到用户态 | |
MADD.S | 一个双精度浮点数与单精度浮点数相乘加,结果为单精度 | |
MADD.D | 一个双精度浮点数与单精度浮点数相乘加,结果为双精度 | |
MADD.PS | 两个单精度浮点数相乘加,结果为单精度 |
Makefile调试
iperf 是一个网络性能测试工具,做服务开发或者测试的同学,接触的可能比较多。 因为最近有用到这个工具,并且这个工具做的非常不错,这里记录一下工具的使用方法。iperf 是个开源并且跨平台的软件, 代码托管在 GitHub 上,可以从 Releases 找到各个发行版本, 也可以去 官网 下载各个平台的版本。 使用 iperf 时, 需要分别运行服务端和客户端,在测试是最好保证两个端的软件版本一致,这样会免去一些没必要的麻烦。
上一篇文章 介绍了ubus的组件和实现原理,本文通过代码实例介绍使用ubus进行进程间通信的三种方式。
ubus为openwrt平台开发中的进程间通信提供了一个通用的框架。 它让进程间通信的实现变得非常简单,并且ubus具有很强的可移植性,可以很方便的移植到其他linux平台上使用。 本文描述了ubus的实现原理和整体框架。
Netifd是OpenWrt中用于进行网络配置的守护进程, 基本上所有网络接口设置以及内核的netlink事件都可以由netifd来处理完成。 在启动netifd之前用户需要将所需的配置写入uci配置文件/etc/config/network中, 以告知netifd如何设置这些网络接口,如IP地址、上网类型等。如果在netifd运行过程中需要修改配置, 则只需更新并保存/etc/config/network,执行/etc/init.d/network reload, netifd便可根据配置文件差异快速地完成网络接口的更新。
Introduction
为调试Linux机器上的C/C++程序,我们通常使用GDB. 但要调试那些在路由器上 跑的C/C++程序,GDB还能胜任么?毕竟,我们又不能直接把源码搁到路由器上编译,在Linux机器上编的话还 牵扯到交叉编译(Cross Compiling)。
各种网站阮一峰的网络日志酷 壳 – COOLSHELLLinux Kernel Exploration十三larmbr老徐的私房菜Rock3的Linux博客啊哈磊泰晓科技Gmd20张连聘的博客生于忧患,死于安乐Start-up朝闻道http://lzz5235.github.io/viewsky11的专栏http...
``` cmake_minimum_required(VERSION 2.8)
中断(Interrupt)包括中断和异常两种类型,异常通常由CPU上执行的指令直接触发, 而中断是由外设发出的电信号触发的,但是那么是否所有的外设都直接接在CPU的中断PIN脚上触发中断? CPU有多少负责中断的PIN脚?CPU如何区别可屏蔽中断和非可屏蔽中断?CPU如何区别Faults、Traps、Aborts? 本篇文章主要来搞懂这些问题。
在《Linux Kernel中断机制1——中断概念》一节中描述了中断的基本概念, 其中professional linux kernel architecture中提到中断可以有异常(exception)和错误(error)产生, 本节研究中断的分类和硬件相关的部分。本节主要来源于Understanding the Linux Kernel 3rd.
和Linux内核打交道,中断是绕不开的概念。
和Linux内核打交道,中断是绕不开的概念。
mac80211是linux kernel中的一个子系统,它为无线设备soft-MAC/half-MAC提供 了分享实施方案,包含MLME和另外一些代码。
今天遇到个问题,某人的代码有断错误,导致我的工作无法展开, 抱怨的就不多说了,正好让我解决了一个gdb的操作问题! 现在说下gdb+coredump的调试流程
数值比较数字比较 比较 描述 n1 -eq n2 n1是否与n2相等 n1 -ge n2 ...
SSH是每一台Linux电脑的标准配置。 随着Linux设备从电脑逐渐扩展到手机、外设和家用电器,SSH的使用范围也越来越广。 不仅程序员离不开它,很多普通用户也每天使用。
内核的很多子系统之间具有很强的相互依赖关系,其中一个子系统发现的或产生的事件, 其他子系统可能都有兴趣。为了实现这种交互需求,Linux使用了通知链(Notification Chain)机制。
本文主要从进程栈空间的层面复习一下C语言中函数调用的具体过程,以加深对一些基础知识的理解。
mmap基础概念
pktgen是linux内核自带的发包工具,省却了用户态socket的参与, 纯粹在内核构造skb送netdev的txqueue上,可以达到极高pps。pktgen只有UDP协议,适合做吞吐量测试
开发和维护内核是一件很繁杂的工作,因此,只有那些最重要或者与系统性能息息相关 的代码才将其安排在内核中。其它程序,比如GUI,管理以及控制部分的代码,一般都会作为用户态程序。 在linux系统中,把系统的某个特性分割成在内核中和在用户空间中分别实现一部分的做法是很常见的(比如linux 系统的防火墙就分成了内核态的Netfilter和用户态的iptables)。然而,内核程序与用户态的程序又是怎样行通讯的呢?
Alan Cox在内核1.3版本的开发阶段最先引入了Netlink,刚开始时Netlink是以 字符驱动接口的方式提供内核与用户空间的双向数据通信;随后,在2.1内核开发过程中,Alexey Kuznetsov将 Netlink改写成一个更加灵活、且易于扩展的基于消息通信接口,并将其应用到高级路由子系统的基础框架里。 自那时起,Netlink就成了Linux内核子系统和用户态的应用程序通信的主要手段之一。
4.3 数据接收流程图
Markdown是什么
Markdown是一种轻量级标记语言,它允许人们“使用易读易写的纯文本格式编写文档, 然后转换成有效的XHTML(或者HTML)文档”。
MIPS有32个通用寄存器($0-$31),各寄存器的功能及汇编程序中使用约定如下:
如果你问我,哪一种算法最重要? 我可能会回答公钥加密算法。 因为它是计算机通信安全的基石,保证了加密数据不会被破解。你可以想象一下,信用卡交易被破解的后果。进入正题之前,我先简单介绍一下,什么是”公钥加密算法”。一、一点历史 1976年以前,所有的加密方法都是同一种模式: 甲方选择某一...
- ${parameter} 取parameter的值
- ${parameter:-word} 如果parameter为空,则用word的值做parameter的缺省值
- ${parameter:=word} 在2的基础上,把word的值赋给parameter
- ${parameter?=word} 如果parameter为空,word作为错误信息输出。
- ${parameter+=word} 在parameter不为空的情况下,输出word的值。
- ${parameter:offset} parameter的从第offset个字符开始的substring
死锁就是多个进程(线程)因为等待别的进程已占有的自己所需要的资源而陷入阻塞的一种状态, 死锁状态一旦形成,进程本身是解决不了的,需要外在的推动,才能解决,最重要的是死锁不仅仅影响进程业务, 而且还会占用系统资源,影响其他进程。所以内核中设计了内核死锁检测机制,一旦发现死锁进程,就重启OS, 快刀斩乱麻解决问题。之所以使用重启招数,还是在于分布式系统中可以容忍单点崩溃,不能容忍单点进程计算异常, 否则进行死锁检测重启OS就得不偿失了。
前一篇博文介绍了内核监测D状态死锁的hung task机制,本文介绍另一种死锁状态的 监测手段——R状态死锁监测。R状态死锁指的是某一任务一直处于TASK_RUNNING态且一直占用着CPU, 从而导致其他进程得不到调度而饿死的情况。一般情况下,R状态死锁较可能是由于程序出现死循环导致的, 可以出现在内核态的进程上下文中(内核配置为非抢占式,soft lockup),也可以出现在中断上下文中的 中断处理程序中(hard lockup)。异常的程序一直运行,CPU无法调度到其他的任务运行,对于单CPU的设备, 则直接的表现就是“死机”。这种死锁现象较难定位,内核也同样提供了一种检测手段来检测这种死锁并向用户发出 告警——LOCKUP_DETECTOR,它可支持监测进程上下文和中断上下文中的R状态死锁(SOFTLOCKUP_DETECTOR和HARDLOCKUP_DETECTOR), 由于HARDLOCKUP_DETECTOR需要nmi中断的支持且目前的arm32环境并不支持,本文仅分析其中SOFTLOCKUP_DETECTOR中的 原理及实现方式,并给出一个示例。
Linux的进程存在多种状态,如TASK_RUNNING的运行态、EXIT_DEAD的停止态和 TASK_INTERRUPTIBLE的接收信号的等待状态等等(可在include/linux/sched.h中查看)。其中有一种状态等待为 TASK_UNINTERRUPTIBLE,称为D状态,该种状态下进程不接收信号,只能通过wake_up唤醒。 处于这种状态的情况有很多,例如mutex锁就可能会设置进程于该状态,有时候进程在等待某种IO资源就绪时 (wait_event机制)会设置进程进入该状态。一般情况下,进程处于该状态的时间不会太久,但若IO设备出现故障 或者出现进程死锁等情况,进程就可能长期处于该状态而无法再返回到TASK_RUNNING态。因此,内核为了便于发现 这类情况设计出了hung task机制专门用于检测长期处于D状态的进程并发出告警。 本文分析内核hung task机制的源码并给出一个示例演示。
最近调试程序学到的几个挺有用的函数,分享一下,希望对用C/C++的朋友有所帮助!
/proc/sys/net目录
connect()函数调用过程connect(fd, servaddr, addrlen);-> SYSCALL_DEFINE3()-> sock->ops->connect() == inet_stream_connect (sock->ops即inet_stream_op...
基于 kernel 3.10内核源码分析
启动GDB开始调试
我们深谙信息交流的价值,那网络中进程之间如何通信, 如我们每天打开浏览器浏览网页时,浏览器的进程怎么与web服务器通信的?当你用QQ聊天时, QQ进程怎么与服务器或你好友所在的QQ进程通信? 这些都得靠socket?那什么是socket?socket的类型有哪些?还有socket的基本函数,这些都是本文想介绍的
net\mac80211\mlme.c MAC层管理实体。
Linux内核中查找伙伴的算法由十分简单的代码构成。
本文基于内核4.2
main.c中start_kernel的初始化流程,不同内核版本函数顺序会有所差别,但总体功能差异性不大。
本文为本人笔记图,描述汇编start到start_kernel简要过程。
写在最前面:在开始本文之前,笔者认为先有必要介绍一下linux下的man, 如果读者手头用linux系统,直接在终端输入man man便可以看到详细的说明,我在这里简单的总结一下, man命令是用来查看linux下各种命令、工具等的用户手册(manual)的。一种比较常用的用法是”man n field”, 这里的n是要查找的手册了类型,field是关键字。在这里介绍一下n:
/proc目录
Linux
内核提供了一种通过 /proc 文件系统,在运行时访问内核内部数据结构、
改变内核设置的机制。proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。
它以文件系统的方式为访问系统内核数据的操作提供接口。
在32位MIPS体系结构下,最多可寻址4GB地址空间。这4GB空间的分配是怎样的呢?让我们看下面这张图:
1. 系统要求
笔者使用的环境为CentOS-7-x86_64, 用来为i9100编译CM 13, 之所以选择最新版的CM是发现编译CM 9.1.0时遇到了无法解决的问题 需要说明的是必须使用64的系统, 而且配置越高越好
概述
ARM Device Tree起源于OpenFirmware (OF),在过去的Linux中,arch/arm/plat-xxx和arch/arm/mach-xxx中充斥着大量的垃圾代码,相当多数的代码只是在描述板级细节,而这些板级细节对于内核来讲,不过是垃圾,如板上的platform设备、resource、i2c_board_info、spi_board_info以及各种硬件的platform_data。为了改变这种局面,Linux社区的大牛们参考了PowerPC等体系架构中使用的Flattened Device Tree(FDT),也采用了Device Tree结构,许多硬件的细节可以直接透过它传递给Linux,而不再需要在kernel中进行大量的冗余编码。
安装quilt 是用来管理代码树中的 patch 的, 嵌入式内核开发利器!请通过软件包管理器安装 quilt. 然后写入以下配置文件到 ~/.quiltrcQUILT\_DIFF_ARGS="--no-timestamps --no-index -pab --color=auto"QUILT\_REFRESH_...
有几个概念玩嵌入式的同志经常搞混。也不怨谁,现在的卖家为了一点可怜的销量都在故意混淆串口的概念。 如果你发现本文有哪里含糊,或者任何一点有可能影响理解的地方,请留言,我会修正以便帮助后来的朋友。
内核编译完成后会生成zImage内核镜像文件。关于bootloader加载zImage到内核,并且跳转到zImage开始地址运行zImage的过程,相信大家都很容易理解。但对于zImage是如何解压的过程,就不是那么好理解了。本文将结合部分关键代码,讲解zImage的解压过程。 先看看zImage的组成吧。在内核编译完成后会在arch/arm/boot/下生成zImage。
所有的__init函数在区段.initcall.init中还保存了一份函数指针,在初始化时内核会通过这些函数指针调用这些__init函数指针,并在整个初始化完成后,释放整个init区段(包括.init.text,.initcall.init等)。 注意 这些函数在内核初始化过程中的调用顺序只和这里的函数指针的顺序有关,和1)中所述的这些函数本身在.init.text区段中的顺序无关。在2.4内核中,这些函数指针的顺序也是和链接的顺序有关的,是不确定的。在2.6内核中,initcall.init区段又分成7个子区段,分别是
第 2 部分:可延迟函数、内核微线程以及工作队列
第 3 部分: 2.6 内核中的计时器和列表
flock和fcntl都有锁的功能,但他们还有一点小小的区别:
Linux 内核提供了两个注册中断处理函数的接口:setup_irq和request_irq。这两个函数都定义在kernel/irq/manage.c里。 这两个函数有什么样的区别呢?
系统初始化时kernel_init在内核态创建和运行应用程序以完成系统初始化. 内核刚刚启动时,只有内核态的代码,后来在init过程中,在内核态运行了一些初始化系统的程序,才产生了工作在用户空间的进程。
本文详细的介绍了Linux内核中的同步机制:原子操作、信号量、读写信号量和自旋锁的API,使用要求以及一些典型示例
unsigned long hash_long(unsigned long val, unsigned int bits)
{
unsigned long hash=val *0x9e370001UL;
return hash>>(32-bits);
}
GNU C的一大特色(却不被初学者所知)就是__attribute__机制。attribute__是用来设置函数属性(Function Attribute)、变量属性(Variable Attribute)和类型属性(Type Attribute)。 __attribute__书写特征是:__attribute__前后都有两个下划线,并切后面会紧跟一对原括弧,括弧里面是相应的__attribute__参数。 __attribute__语法格式为: __attribute ((attribute-list)) 其位置约束为:放于声明的尾部“;”之前。
1 相关数据结构
内核的dma一般在平台初始化的时候已经分配好了。但是对于一些有内部dma的硬件ip,比如usb ip、video加速ip,他们可能由ip厂商封装好的,没办法绑定到cpu端,这时候在内核使用dma就要注意了,因为dma只认识物理地址哦。
Epoll实验总结
1. 概要编译,就是将高级语言转换成机器语言。譬如,通过gcc将C语言编译成可以运行的二进制;通过javac将Java语言编译成可以在Java虚拟机上可以运行的字节码。对于简单的项目,源文件数量较少,通常只需要几条命令,组织一下源文件,调用一下编译器,生成一个可以运行的文件,就算是一个“编译系统”; 但对于大型的...
1. 概要Android Debug Bridge(adb)是一个Android的命令行工具,可以用来连接模拟器或实际的移动设备。做过Android开发的朋友一定对adb logcat, adb shell命令不陌生,Dalvik Debug Monitor Server(DDMS)后台也是运行的adb来实现监控...
阅读本文之前,需要对git有一定的了解。1. 概要repo是Android为了方便管理多个git库而开发的Python脚本。repo的出现,并非为了取代git,而是为了让Android开发者更为有效的利用git。Android源码包含数百个git库,仅仅是下载这么多git库就是一项繁重的任务,所以在下载源码时,A...
25个 Git 进阶技巧
linux中软件包管理命令 rpm 用法
linux中软件包管理命令 rpm 用法
Android Repo的manifest XML文件格式
第 2 部分: procfs、seq_file、debugfs和relayfs”
Linux检查信号是否发生的时间点:
第 1 部分: 内核启动参数、模块参数与sysfs、sysctl、系统调用和netlink”
Linux下无论如何都是要用到shell命令的,在Shell的实际使用中,有编程经验的很容易上手,但稍微有难度的是shell里面的那些个符号,各种特殊的符号在我们编写Shell脚本的时候如果能够用的好,往往能给我们起到事半功倍的效果,为此,特地将Shell里面的一些符号说明罗列成对照表的形式,以便快速的查找。看看你知道下表中哦你的哪些Shell符号呢?
Git是目前最流行的版本管理系统,学会Git几乎成了开发者的必备技能。 Git有很多优势,其中之一就是远程操作非常简便。本文详细介绍5个Git命令,它们的概念和用法,理解了这些内容,你就会完全掌握Git远程操作。 git clone git remote git fetch git pull git push 本文针对初级用户,从最简单的讲起,但是需要读者对Git的基本用法有所了解。同时,本文覆盖了上面5个命令的几乎所有的常用用法,所以对于熟练用户也有参考价值。
作为Linux下的程序开发人员,大家一定都遇到过Makefile, 用make命令来编译自己写的程序确实是很方便。一般情况下,大家都是手工写一个简单Makefile, 如果要想写出一个符合自由软件惯例的Makefile就不那么容易了。
作为Linux下的程序开发人员,大家一定都遇到过Makefile, 用make命令来编译自己写的程序确实是很方便。一般情况下,大家都是手工写一个简单Makefile, 如果要想写出一个符合自由软件惯例的Makefile就不那么容易了。
git logA—B—E—F <==(master) -–C—D <==(experimet)两点(..)表示查看experiment上还没有合并到master的commit,换句话说:所有experiment能读取到但master读取不到的commit对象$ git log master..e...
Makefile调试
iperf 是一个网络性能测试工具,做服务开发或者测试的同学,接触的可能比较多。 因为最近有用到这个工具,并且这个工具做的非常不错,这里记录一下工具的使用方法。iperf 是个开源并且跨平台的软件, 代码托管在 GitHub 上,可以从 Releases 找到各个发行版本, 也可以去 官网 下载各个平台的版本。 使用 iperf 时, 需要分别运行服务端和客户端,在测试是最好保证两个端的软件版本一致,这样会免去一些没必要的麻烦。
启动GDB开始调试
阅读本文之前,需要对git有一定的了解。1. 概要repo是Android为了方便管理多个git库而开发的Python脚本。repo的出现,并非为了取代git,而是为了让Android开发者更为有效的利用git。Android源码包含数百个git库,仅仅是下载这么多git库就是一项繁重的任务,所以在下载源码时,A...
25个 Git 进阶技巧
Android Repo的manifest XML文件格式
Git是目前最流行的版本管理系统,学会Git几乎成了开发者的必备技能。 Git有很多优势,其中之一就是远程操作非常简便。本文详细介绍5个Git命令,它们的概念和用法,理解了这些内容,你就会完全掌握Git远程操作。 git clone git remote git fetch git pull git push 本文针对初级用户,从最简单的讲起,但是需要读者对Git的基本用法有所了解。同时,本文覆盖了上面5个命令的几乎所有的常用用法,所以对于熟练用户也有参考价值。
在前两篇中我们了解了DTS的背景基础知识以及发挥作用的流程,这篇文章我们以高通的MSM8953平台为例来添加一个基础的i2c设备(包含一个gpio中断)。
Linux DTS(Device Tree Source)设备树详解之二(dts匹配及发挥作用的流程篇)
什么是DTS?为什么要引入DTS?
DTS即Device Tree Source 设备树源码, Device Tree是一种描述硬件的数据结构,它起源于 OpenFirmware (OF)。 在Linux 2.6中,ARM架构的板极硬件细节过多地被硬编码在arch/arm/plat-xxx和arch/arm/mach-xxx,比如板上的platform设备、 resource、i2c_board_info、spi_board_info以及各种硬件的platform_data,这些板级细节代码对内核来讲只不过是垃圾代码。 而采用Device Tree后,许多硬件的细节可以直接透过它传递给Linux,而不再需要在kernel中进行大量的冗余编码。 每次正式的linux kernel release之后都会有两周的merge window,在这个窗口期间,kernel各个部分的维护者都会提交各自的patch, 将自己测试稳定的代码请求并入kernel main line。每到这个时候,Linus就会比较繁忙,他需要从各个内核维护者的分支上取得最新代码 并merge到自己的kernel source tree中。Tony Lindgren,内核OMAP development tree的维护者,发送了一个邮件给Linus, 请求提交OMAP平台代码修改,并给出了一些细节描述:
简介
本文介绍一个IPQ4019的MTD分区信息是如何从配置文件一步步传递到linux内核的。 这个过程有几个部分组成,分区信息在编译过程中的传递;升级时写入flash区;设备上电时linux如何得到分区信息。
asort和asorti
简介
在内存发生panic时,需要把panic的日志保存下来。以方便日后进行分析。 目前有三种记录的方式: kdump; mtdoops; crashlog(这是openwrt特别的功能,正式linux内核中没有) 大家对kdump比较了解。它主要使用于x86系统。因为它使用占用大量内存和硬盘。 mtdoops和crashlog主要用于嵌入式的环境。也只是记录文本日志。
Introduction
为调试Linux机器上的C/C++程序,我们通常使用GDB. 但要调试那些在路由器上跑的C/C++程序, GDB还能胜任么?毕竟,我们又不能直接把源码搁到路由器上编译,在Linux机器上编的话还牵扯到交叉编译(Cross Compiling)。
dnsmasq的简介
Dnsmasq 提供 DNS 缓存和 DHCP 服务功能。作为域名解析服务器(DNS),dnsmasq可以通过缓存 DNS 请求来提高对访问过的网址的连接速度。作为DHCP 服务器,dnsmasq 可以用于为局域网电脑分配内网ip地址和提供路由。 DNS和DHCP两个功能可以同时或分别单独实现。dnsmasq轻量且易配置,适用于个人用户或少于50台主机的网络。此外它还自带了一个 PXE 服务器。。
一、进程调度 调度的发生有两种方式1、主动式在内核中直接调用schedule()。当进程需要等待资源等而暂时停止运行时,会把状态置于挂起(睡眠),并主动请求调度,让出CPU。主动放弃cpu例: current->state = TASK_INTERRUPTIBLE; schedule();2、被动...
第 1 部分: Linux 应用层的时间编程
本贴主要讲解 Bootloader 是如何在使用 SPI Flash 的 AR/QCA 的芯片上启动的, 以及 OpenWrt 代码 ar71xx 的 mach 文件中类似于 u8 *art = KSEG1ADDR(0x1fff0000) 中 0x1fff0000 是如何得来的。 楼主之前在 U-Boot 编译教程中进行过简单的描述,但是因为实在是太简略了,所以打算写一个详细版的。
当一个程序发生故障时,有时候想通过了解该进程正在执行的系统调用来排查问题。 通常可以用 strace 来跟踪。但是当进程已经处于 D 状态(uninterruptible sleep)时,strace 也帮不上忙。这时候可以通过
我们理解您需要更便捷更高效的工具记录思想,整理笔记、知识, 并将其中承载的价值传播给他人,Cmd Markdown 是我们给出的答案 —— 我们为记录思想和分享知识提供更专业的工具。 您可以使用 Cmd Markdown:
指令 | 功能 | 应用实例 |
---|---|---|
LB | 从存储器中读取一个字节的数据到寄存器中 | LB R1, 0(R2) |
LH | 从存储器中读取半个字的数据到寄存器中 | LH R1, 0(R2) |
LW | 从存储器中读取一个字的数据到寄存器中 | LW R1, 0(R2) |
LD | 从存储器中读取双字的数据到寄存器中 | LD R1, 0(R2) |
L.S | 从存储器中读取单精度浮点数到寄存器中 | L.S R1, 0(R2) |
L.D | 从存储器中读取双精度浮点数到寄存器中 | L.D R1, 0(R2) |
LBU | 功能与LB指令相同,但读出的是不带符号的数据 | LBU R1, 0(R2) |
LHU | 功能与LH指令相同,但读出的是不带符号的数据 | LHU R1, 0(R2) |
LWU | 功能与LW指令相同,但读出的是不带符号的数据 | LWU R1, 0(R2) |
SB | 把一个字节的数据从寄存器存储到存储器中 | SB R1, 0(R2) |
SH | 把半个字节的数据从寄存器存储到存储器中 | SH R1,0(R2) |
SW | 把一个字的数据从寄存器存储到存储器中 | SW R1, 0(R2) |
SD | 把两个字节的数据从寄存器存储到存储器中 | SD R1, 0(R2) |
S.S | 把单精度浮点数从寄存器存储到存储器中 | S.S R1, 0(R2) |
S.D | 把双精度数据从存储器存储到存储器中 | S.D R1, 0(R2) |
DADD | 把两个定点寄存器的内容相加,也就是定点加 | DADD R1,R2,R3 |
DADDI | 把一个寄存器的内容加上一个立即数 | DADDI R1,R2,#3 |
DADDU | 不带符号的加 | DADDU R1,R2,R3 |
DADDIU | 把一个寄存器的内容加上一个无符号的立即数 | DADDIU R1,R2,#3 |
ADD.S | 把一个单精度浮点数加上一个双精度浮点数,结果是单精度浮点数 | ADD.S F0,F1,F2 |
ADD.D | 把一个双精度浮点数加上一个单精度浮点数,结果是双精度浮点数 | ADD.D F0,F1,F2 |
ADD.PS | 两个单精度浮点数相加,结果是单精度浮点数 | ADD.PS F0,F1,F2 |
DSUB | 两个寄存器的内容相减,也就是定点数的减 | DSUB R1,R2,R3 |
DSUBU | 不带符号的减 | DSUBU R1,R2,R3 |
SUB.S | 一个双精度浮点数减去一个单精度浮点数,结果为单精度 | SUB.S F1,F2,F3 |
SUB.D | 一个双精度浮点数减去一个单精度浮点数,结果为双精度浮点数 | SUB.D F1,F2,F3 |
SUB.PS | 两个单精度浮点数相减 | SUB.SP F1,F2,F3 |
DDIV | 两个定点寄存器的内容相除,也就是定点除 | DDIV R1,R2,R3 |
DDIVU | 不带符号的除法运算 | DDIVU R1,R2,R3 |
DIV.S | 一个双精度浮点数除以一个单精度浮点数,结果为单精度浮点数 | DIV.S F1,F2,F3 |
DIV.D | 一个双精度浮点数除以一个单精度浮点数,结果为双精度浮点数 | DIV.D F1,F2,F3 |
DIV.PS | 两个单精度浮点数相除,结果为单精度 | DIV.PS F1,F2,F3 |
DMUL | 两个定点寄存器的内容相乘,也就是定点乘 | DMUL R1,R2,R3 |
DMULU | 不带符号的乘法运算 | DMULU R1,R2,R3 |
MUL.S | 一个双精度浮点数乘以一个单精度浮点数,结果为单精度浮点数 | DMUL.S F1,F2,F3 |
MUL.D | 一个双精度浮点数乘以一个单精度浮点数,结果为双精度浮点数 | DMUL.D F1,F2,F3 |
MUL.PS | 两个单精度浮点数相乘,结果为单精度浮点数 | DMUL.PS F1,F2,F3 |
AND | 与运算,两个寄存器中的内容相与 | ANDR1,R2,R3 |
ANDI | 一个寄存器中的内容与一个立即数相与 | ANDIR1,R2,#3 |
OR | 或运算,两个寄存器中的内容相或 | ORR1,R2,R3 |
ORI | 一个寄存器中的内容与一个立即数相或 | ORIR1,R2,#3 |
XOR | 异或运算,两个寄存器中的内容相异或 | XORR1,R2,R3 |
XORI | 一个寄存器中的内容与一个立即数异或 | XORIR1,R2,#3 |
BEQZ | 条件转移指令,当寄存器中内容为0时转移发生 | BEQZ R1,0 |
BENZ | 条件转移指令,当寄存器中内容不为0时转移发生 | BNEZ R1,0 |
BEQ | 条件转移指令,当两个寄存器内容相等时转移发生 | BEQ R1,R2 |
BNE | 条件转移指令,当两个寄存器中内容不等时转移发生 | BNE R1,R2 |
J | 直接跳转指令,跳转的地址在指令中 | J name |
JR | 使用寄存器的跳转指令,跳转地址在寄存器中 | JR R1 |
JAL | 直接跳转指令,并带有链接功能,指令的跳转地址在指令中,跳转发生时要把返回地址存放到R31这个寄存器中 | JAL R1 name |
JALR | 使用寄存器的跳转指令,并且带有链接功能,指令的跳转地址在寄存器中,跳转发生时指令的放回地址放在R31这个寄存器中 | JALR R1 |
MOV.S | 把一个单精度浮点数从一个浮点寄存器复制到另一个浮点寄存器 | MOV.S F0,F1 |
MOV.D | 把一个双精度浮点数从一个浮点寄存器复制到另一个浮点寄存器 | MOV.D F0,F1 |
MFC0 | 把一个数据从通用寄存器复制到特殊寄存器 | MFC0 R1,R2 |
MTC0 | 把一个数据从特殊寄存器复制到通用寄存器 | MTC0 R1,R2 |
MFC1 | 把一个数据从定点寄存器复制到浮点寄存器 | MFC1 R1,F1 |
MTC1 | 把一个数据从浮点寄存器复制到定点寄存器 | MTC1 R1,F1 |
LUI | 把一个16位的立即数填入到寄存器的高16位,低16位补零 | LUI R1,#42 |
DSLL | 双字逻辑左移 | DSLL R1,R2,#2 |
DSRL | 双字逻辑右移 | DSRL R1,R2,#2 |
DSRA | 双字算术右移 | DSRA R1,R2,#2 |
DSLLV | 可变的双字逻辑左移 | DSLLV R1,R2,#2 |
DSRLV | 可变的双字罗伊右移 | DSRLV R1,R2,#2 |
DSRAV | 可变的双字算术右移 | DSRAV R1,R2,#2 |
SLT | 如果R2的值小于R3,那么设置R1的值为1,否则设置R1的值为0 | SLT R1,R2,R3 |
SLTI | 如果寄存器R2的值小于立即数,那么设置R1的值为1,否则设置寄存器R1的值为0 | SLTI R1,R2,#23 |
SLTU | 功能与SLT一致,但是带符号的 | SLTU R1,R2,R3 |
SLTUI | 功能与SLT一致,但不带符号 | SLTUI R1,R2,R3 |
MOVN | 如果第三个寄存器的内容为负,那么复制一个寄存器的内容到另外一个寄存器 | MOVN R1,R2,R3 |
MOVZ | 如果第三个寄存器的内容为0,那么复制一个寄存器的内容到另外一个寄存器 | MOVZ R1,R2,R3 |
TRAP | 根据地址向量转入管态 | |
ERET | 从异常中返回到用户态 | |
MADD.S | 一个双精度浮点数与单精度浮点数相乘加,结果为单精度 | |
MADD.D | 一个双精度浮点数与单精度浮点数相乘加,结果为双精度 | |
MADD.PS | 两个单精度浮点数相乘加,结果为单精度 |
上一篇文章 介绍了ubus的组件和实现原理,本文通过代码实例介绍使用ubus进行进程间通信的三种方式。
ubus为openwrt平台开发中的进程间通信提供了一个通用的框架。 它让进程间通信的实现变得非常简单,并且ubus具有很强的可移植性,可以很方便的移植到其他linux平台上使用。 本文描述了ubus的实现原理和整体框架。
Netifd是OpenWrt中用于进行网络配置的守护进程, 基本上所有网络接口设置以及内核的netlink事件都可以由netifd来处理完成。 在启动netifd之前用户需要将所需的配置写入uci配置文件/etc/config/network中, 以告知netifd如何设置这些网络接口,如IP地址、上网类型等。如果在netifd运行过程中需要修改配置, 则只需更新并保存/etc/config/network,执行/etc/init.d/network reload, netifd便可根据配置文件差异快速地完成网络接口的更新。
Introduction
为调试Linux机器上的C/C++程序,我们通常使用GDB. 但要调试那些在路由器上 跑的C/C++程序,GDB还能胜任么?毕竟,我们又不能直接把源码搁到路由器上编译,在Linux机器上编的话还 牵扯到交叉编译(Cross Compiling)。
中断(Interrupt)包括中断和异常两种类型,异常通常由CPU上执行的指令直接触发, 而中断是由外设发出的电信号触发的,但是那么是否所有的外设都直接接在CPU的中断PIN脚上触发中断? CPU有多少负责中断的PIN脚?CPU如何区别可屏蔽中断和非可屏蔽中断?CPU如何区别Faults、Traps、Aborts? 本篇文章主要来搞懂这些问题。
在《Linux Kernel中断机制1——中断概念》一节中描述了中断的基本概念, 其中professional linux kernel architecture中提到中断可以有异常(exception)和错误(error)产生, 本节研究中断的分类和硬件相关的部分。本节主要来源于Understanding the Linux Kernel 3rd.
和Linux内核打交道,中断是绕不开的概念。
和Linux内核打交道,中断是绕不开的概念。
mac80211是linux kernel中的一个子系统,它为无线设备soft-MAC/half-MAC提供 了分享实施方案,包含MLME和另外一些代码。
今天遇到个问题,某人的代码有断错误,导致我的工作无法展开, 抱怨的就不多说了,正好让我解决了一个gdb的操作问题! 现在说下gdb+coredump的调试流程
数值比较数字比较 比较 描述 n1 -eq n2 n1是否与n2相等 n1 -ge n2 ...
SSH是每一台Linux电脑的标准配置。 随着Linux设备从电脑逐渐扩展到手机、外设和家用电器,SSH的使用范围也越来越广。 不仅程序员离不开它,很多普通用户也每天使用。
内核的很多子系统之间具有很强的相互依赖关系,其中一个子系统发现的或产生的事件, 其他子系统可能都有兴趣。为了实现这种交互需求,Linux使用了通知链(Notification Chain)机制。
mmap基础概念
Markdown是什么
Markdown是一种轻量级标记语言,它允许人们“使用易读易写的纯文本格式编写文档, 然后转换成有效的XHTML(或者HTML)文档”。
- ${parameter} 取parameter的值
- ${parameter:-word} 如果parameter为空,则用word的值做parameter的缺省值
- ${parameter:=word} 在2的基础上,把word的值赋给parameter
- ${parameter?=word} 如果parameter为空,word作为错误信息输出。
- ${parameter+=word} 在parameter不为空的情况下,输出word的值。
- ${parameter:offset} parameter的从第offset个字符开始的substring
死锁就是多个进程(线程)因为等待别的进程已占有的自己所需要的资源而陷入阻塞的一种状态, 死锁状态一旦形成,进程本身是解决不了的,需要外在的推动,才能解决,最重要的是死锁不仅仅影响进程业务, 而且还会占用系统资源,影响其他进程。所以内核中设计了内核死锁检测机制,一旦发现死锁进程,就重启OS, 快刀斩乱麻解决问题。之所以使用重启招数,还是在于分布式系统中可以容忍单点崩溃,不能容忍单点进程计算异常, 否则进行死锁检测重启OS就得不偿失了。
前一篇博文介绍了内核监测D状态死锁的hung task机制,本文介绍另一种死锁状态的 监测手段——R状态死锁监测。R状态死锁指的是某一任务一直处于TASK_RUNNING态且一直占用着CPU, 从而导致其他进程得不到调度而饿死的情况。一般情况下,R状态死锁较可能是由于程序出现死循环导致的, 可以出现在内核态的进程上下文中(内核配置为非抢占式,soft lockup),也可以出现在中断上下文中的 中断处理程序中(hard lockup)。异常的程序一直运行,CPU无法调度到其他的任务运行,对于单CPU的设备, 则直接的表现就是“死机”。这种死锁现象较难定位,内核也同样提供了一种检测手段来检测这种死锁并向用户发出 告警——LOCKUP_DETECTOR,它可支持监测进程上下文和中断上下文中的R状态死锁(SOFTLOCKUP_DETECTOR和HARDLOCKUP_DETECTOR), 由于HARDLOCKUP_DETECTOR需要nmi中断的支持且目前的arm32环境并不支持,本文仅分析其中SOFTLOCKUP_DETECTOR中的 原理及实现方式,并给出一个示例。
Linux的进程存在多种状态,如TASK_RUNNING的运行态、EXIT_DEAD的停止态和 TASK_INTERRUPTIBLE的接收信号的等待状态等等(可在include/linux/sched.h中查看)。其中有一种状态等待为 TASK_UNINTERRUPTIBLE,称为D状态,该种状态下进程不接收信号,只能通过wake_up唤醒。 处于这种状态的情况有很多,例如mutex锁就可能会设置进程于该状态,有时候进程在等待某种IO资源就绪时 (wait_event机制)会设置进程进入该状态。一般情况下,进程处于该状态的时间不会太久,但若IO设备出现故障 或者出现进程死锁等情况,进程就可能长期处于该状态而无法再返回到TASK_RUNNING态。因此,内核为了便于发现 这类情况设计出了hung task机制专门用于检测长期处于D状态的进程并发出告警。 本文分析内核hung task机制的源码并给出一个示例演示。
基于 kernel 3.10内核源码分析
net\mac80211\mlme.c MAC层管理实体。
Linux内核中查找伙伴的算法由十分简单的代码构成。
本文基于内核4.2
main.c中start_kernel的初始化流程,不同内核版本函数顺序会有所差别,但总体功能差异性不大。
本文为本人笔记图,描述汇编start到start_kernel简要过程。
写在最前面:在开始本文之前,笔者认为先有必要介绍一下linux下的man, 如果读者手头用linux系统,直接在终端输入man man便可以看到详细的说明,我在这里简单的总结一下, man命令是用来查看linux下各种命令、工具等的用户手册(manual)的。一种比较常用的用法是”man n field”, 这里的n是要查找的手册了类型,field是关键字。在这里介绍一下n:
/proc目录
Linux
内核提供了一种通过 /proc 文件系统,在运行时访问内核内部数据结构、
改变内核设置的机制。proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。
它以文件系统的方式为访问系统内核数据的操作提供接口。
在32位MIPS体系结构下,最多可寻址4GB地址空间。这4GB空间的分配是怎样的呢?让我们看下面这张图:
概述
ARM Device Tree起源于OpenFirmware (OF),在过去的Linux中,arch/arm/plat-xxx和arch/arm/mach-xxx中充斥着大量的垃圾代码,相当多数的代码只是在描述板级细节,而这些板级细节对于内核来讲,不过是垃圾,如板上的platform设备、resource、i2c_board_info、spi_board_info以及各种硬件的platform_data。为了改变这种局面,Linux社区的大牛们参考了PowerPC等体系架构中使用的Flattened Device Tree(FDT),也采用了Device Tree结构,许多硬件的细节可以直接透过它传递给Linux,而不再需要在kernel中进行大量的冗余编码。
安装quilt 是用来管理代码树中的 patch 的, 嵌入式内核开发利器!请通过软件包管理器安装 quilt. 然后写入以下配置文件到 ~/.quiltrcQUILT\_DIFF_ARGS="--no-timestamps --no-index -pab --color=auto"QUILT\_REFRESH_...
内核编译完成后会生成zImage内核镜像文件。关于bootloader加载zImage到内核,并且跳转到zImage开始地址运行zImage的过程,相信大家都很容易理解。但对于zImage是如何解压的过程,就不是那么好理解了。本文将结合部分关键代码,讲解zImage的解压过程。 先看看zImage的组成吧。在内核编译完成后会在arch/arm/boot/下生成zImage。
所有的__init函数在区段.initcall.init中还保存了一份函数指针,在初始化时内核会通过这些函数指针调用这些__init函数指针,并在整个初始化完成后,释放整个init区段(包括.init.text,.initcall.init等)。 注意 这些函数在内核初始化过程中的调用顺序只和这里的函数指针的顺序有关,和1)中所述的这些函数本身在.init.text区段中的顺序无关。在2.4内核中,这些函数指针的顺序也是和链接的顺序有关的,是不确定的。在2.6内核中,initcall.init区段又分成7个子区段,分别是
第 2 部分:可延迟函数、内核微线程以及工作队列
第 3 部分: 2.6 内核中的计时器和列表
Linux 内核提供了两个注册中断处理函数的接口:setup_irq和request_irq。这两个函数都定义在kernel/irq/manage.c里。 这两个函数有什么样的区别呢?
系统初始化时kernel_init在内核态创建和运行应用程序以完成系统初始化. 内核刚刚启动时,只有内核态的代码,后来在init过程中,在内核态运行了一些初始化系统的程序,才产生了工作在用户空间的进程。
本文详细的介绍了Linux内核中的同步机制:原子操作、信号量、读写信号量和自旋锁的API,使用要求以及一些典型示例
unsigned long hash_long(unsigned long val, unsigned int bits)
{
unsigned long hash=val *0x9e370001UL;
return hash>>(32-bits);
}
1 相关数据结构
内核的dma一般在平台初始化的时候已经分配好了。但是对于一些有内部dma的硬件ip,比如usb ip、video加速ip,他们可能由ip厂商封装好的,没办法绑定到cpu端,这时候在内核使用dma就要注意了,因为dma只认识物理地址哦。
linux中软件包管理命令 rpm 用法
linux中软件包管理命令 rpm 用法
第 2 部分: procfs、seq_file、debugfs和relayfs”
Linux检查信号是否发生的时间点:
第 1 部分: 内核启动参数、模块参数与sysfs、sysctl、系统调用和netlink”
Linux下无论如何都是要用到shell命令的,在Shell的实际使用中,有编程经验的很容易上手,但稍微有难度的是shell里面的那些个符号,各种特殊的符号在我们编写Shell脚本的时候如果能够用的好,往往能给我们起到事半功倍的效果,为此,特地将Shell里面的一些符号说明罗列成对照表的形式,以便快速的查找。看看你知道下表中哦你的哪些Shell符号呢?
MCS速率计算公式
三 代码基本结构(Code Base Structure)
二 WLAN驱动设计
一 Wireless LAN简介
协议栈数据包走向图
使用 iptables 封 IP,是一种比较简单的应对网络攻击的方式,也算是比较常见。 有时候可能会封禁成千上万个 IP,如果添加成千上万条规则,在一台注重性能的服务器 或者本身性能就很差的设备上,这就是个问题了。ipset 就是为了避免这个问题而生的。
IE802.11简介
TKIP加密过程
介绍WLAN QoS的定义、由来和作用。
mac80211是linux kernel中的一个子系统,它为无线设备soft-MAC/half-MAC提供 了分享实施方案,包含MLME和另外一些代码。
pktgen是linux内核自带的发包工具,省却了用户态socket的参与, 纯粹在内核构造skb送netdev的txqueue上,可以达到极高pps。pktgen只有UDP协议,适合做吞吐量测试
开发和维护内核是一件很繁杂的工作,因此,只有那些最重要或者与系统性能息息相关 的代码才将其安排在内核中。其它程序,比如GUI,管理以及控制部分的代码,一般都会作为用户态程序。 在linux系统中,把系统的某个特性分割成在内核中和在用户空间中分别实现一部分的做法是很常见的(比如linux 系统的防火墙就分成了内核态的Netfilter和用户态的iptables)。然而,内核程序与用户态的程序又是怎样行通讯的呢?
Alan Cox在内核1.3版本的开发阶段最先引入了Netlink,刚开始时Netlink是以 字符驱动接口的方式提供内核与用户空间的双向数据通信;随后,在2.1内核开发过程中,Alexey Kuznetsov将 Netlink改写成一个更加灵活、且易于扩展的基于消息通信接口,并将其应用到高级路由子系统的基础框架里。 自那时起,Netlink就成了Linux内核子系统和用户态的应用程序通信的主要手段之一。
4.3 数据接收流程图
/proc/sys/net目录
connect()函数调用过程connect(fd, servaddr, addrlen);-> SYSCALL_DEFINE3()-> sock->ops->connect() == inet_stream_connect (sock->ops即inet_stream_op...
我们深谙信息交流的价值,那网络中进程之间如何通信, 如我们每天打开浏览器浏览网页时,浏览器的进程怎么与web服务器通信的?当你用QQ聊天时, QQ进程怎么与服务器或你好友所在的QQ进程通信? 这些都得靠socket?那什么是socket?socket的类型有哪些?还有socket的基本函数,这些都是本文想介绍的
net\mac80211\mlme.c MAC层管理实体。
1. 系统要求
笔者使用的环境为CentOS-7-x86_64, 用来为i9100编译CM 13, 之所以选择最新版的CM是发现编译CM 9.1.0时遇到了无法解决的问题 需要说明的是必须使用64的系统, 而且配置越高越好
1. 概要编译,就是将高级语言转换成机器语言。譬如,通过gcc将C语言编译成可以运行的二进制;通过javac将Java语言编译成可以在Java虚拟机上可以运行的字节码。对于简单的项目,源文件数量较少,通常只需要几条命令,组织一下源文件,调用一下编译器,生成一个可以运行的文件,就算是一个“编译系统”; 但对于大型的...
1. 概要Android Debug Bridge(adb)是一个Android的命令行工具,可以用来连接模拟器或实际的移动设备。做过Android开发的朋友一定对adb logcat, adb shell命令不陌生,Dalvik Debug Monitor Server(DDMS)后台也是运行的adb来实现监控...
本文主要从进程栈空间的层面复习一下C语言中函数调用的具体过程,以加深对一些基础知识的理解。
最近调试程序学到的几个挺有用的函数,分享一下,希望对用C/C++的朋友有所帮助!
flock和fcntl都有锁的功能,但他们还有一点小小的区别:
GNU C的一大特色(却不被初学者所知)就是__attribute__机制。attribute__是用来设置函数属性(Function Attribute)、变量属性(Variable Attribute)和类型属性(Type Attribute)。 __attribute__书写特征是:__attribute__前后都有两个下划线,并切后面会紧跟一对原括弧,括弧里面是相应的__attribute__参数。 __attribute__语法格式为: __attribute ((attribute-list)) 其位置约束为:放于声明的尾部“;”之前。
Epoll实验总结
本文是一篇LoRaWAN的科普介绍,你已经在朋友圈看过无数蜻蜓点水的LoRaWAN文章,是时候来一篇真正的技术干货了。 本文先从横向介绍下LoRaWAN的背后势力和网络部署情况,然后纵向讲解了网络架构和具体的协议内容,帮助LoRa从业者系统地了解LoRaWAN协议。
简介
本文介绍一个IPQ4019的MTD分区信息是如何从配置文件一步步传递到linux内核的。 这个过程有几个部分组成,分区信息在编译过程中的传递;升级时写入flash区;设备上电时linux如何得到分区信息。
启动图解如下:linux内核启动完成后,执行的第一个程序中/etc/preinit。此时环境变量PREINIT为空,所以马上执行/sbin/init/sbin/init是由procd/init.c编译而来。主要过程如下: /sbin/kmodloader 加载内核模块 执行一些early cmdline等 ...
各种网站阮一峰的网络日志酷 壳 – COOLSHELLLinux Kernel Exploration十三larmbr老徐的私房菜Rock3的Linux博客啊哈磊泰晓科技Gmd20张连聘的博客生于忧患,死于安乐Start-up朝闻道http://lzz5235.github.io/viewsky11的专栏http...
MIPS有32个通用寄存器($0-$31),各寄存器的功能及汇编程序中使用约定如下:
如果你问我,哪一种算法最重要? 我可能会回答公钥加密算法。 因为它是计算机通信安全的基石,保证了加密数据不会被破解。你可以想象一下,信用卡交易被破解的后果。进入正题之前,我先简单介绍一下,什么是”公钥加密算法”。一、一点历史 1976年以前,所有的加密方法都是同一种模式: 甲方选择某一...
有几个概念玩嵌入式的同志经常搞混。也不怨谁,现在的卖家为了一点可怜的销量都在故意混淆串口的概念。 如果你发现本文有哪里含糊,或者任何一点有可能影响理解的地方,请留言,我会修正以便帮助后来的朋友。