0%

看Linux驱动相关的代码, 却没有一个好的调试环境可以跟踪内核相关的调用流程。于是,想着用QEMU虚拟机来搭建一个Linux系统。花了大半天时间,终于能够启动一个简单的Linux系统了。中间踩了不少坑,找了不少资料,这里简单总结下整个过程。

以下操作都是基于Ubuntu 18.04 x86_64平台

最开始参考了如何使用QEMU跑内核,使用系统自带的QEMU工具,结果提示如下错误:

1
2
3

qemu-system-aarch64 rom check and register reset failed

怀疑是QEMU的版本太低导致,于是只好又重新编译QEMU源码,最后总算大功告成。总的说来,大致要做的事情有这么几个:

  • 编译Linux内核,利用busybox来生成一个小的rootfs(关于什么是rootfs,可以参考The rootfs FS)
  • 编译QEMU,确保正常配置ARM64架构的虚拟环境
  • 一切就绪,通过qemu-system-aarch64跑起来虚拟机来
阅读全文 »

在前面的一篇文章Linux网络优化之链路层优化中,我们已经看到,随着网卡速率超过1Gbps,增加到10Gbps/100Gbps时,CPU已经很难处理如此大量的数据包了。总结来说,主要有如下瓶颈:

  • 内核协议栈处理在L3(IP)/L4(TCP)的数据处理上,消耗了比较多的时间,会导致网络延迟与传输受限
  • 高速网卡会在短时间内产生大量中断,导致CPU频繁发生上下文切换,性能收到影响,进而影响网络吞吐

针对10Gbps/100Gbps等高速网卡中存在的延迟与带宽受限问题,Intel在2010年提出了DPDK(Data Plane Development Kit)基于用户空间的解决方案,并开源了实现方案, 目前DPDK支持包括Intel/ARM等多个芯片架构的指令集; 同样是Intel的工程师在2018年提出了XDP(eXpress Data Path),与DPDK不一样的是,XDP基于现有内核socket接口,与eBPF相结合实现网卡与用户空间的数据传输,从而避免了内核协议栈的处理延迟。

阅读全文 »

TCP(Transmision Control Protocol)即传输控制协议, 位于TCP/IP协议栈的第三层(L3), 是一种提供了可靠连接的字节流协议; TCP是目前使用最为广泛的协议之一, HTTP/MQTT/FTP等诸多应用层协议都是基于TCP实现的, 更多关于TCP协议相关的具体内容可以参考标准文档RFC793以及早前写的一篇聊一聊TCP协议.

在上一篇文章中讲到了高速以太网如1Gbps/10Gpbs中Linux网络L2(链路层)的一些优化方法, 包括了offload(卸荷)以及scaling(缩放)两种技术. 随着高速网络的不断普及, 1Gbps/10Gpbs以太网已经被广泛使用, 40Gbps/100Gbps也已经制定标准, TCP也在随着网络带宽的提升而不断进化.这篇文章我们就来看下如何在高速以太网下对TCP相关的参数的进行调优.

阅读全文 »

现在车内网络都开始内卷到1Gbps了, 有同学给我反馈说以太网的吞吐量上不来, 跟理论带宽差距很大, 之前虽然优化了一波TCP相关的参数, 但估计不能解决全部问题. 遂决定重新学习下网络优化, 从底层链路对开发平台上的网络进行改善. 趁着这个机会, 索性写一个系列文章-Linux网络优化, 用来总结下Linux网络优化的一些方法与技术, 目前计划从如下几篇文章展开(希望不要放飞了):

  • Linux网络优化之数据链路层优化: 数据链路层L2的优化, 如何从收发两个方面优化网卡吞吐量
  • Linux网络优化之TCP优化: 以TCP协议为例, 说明L3协议栈优化
  • Linux网络优化之高速网络优化: 基于DPDK/XDP解决高速网络传输延迟问题
  • Linux网络优化之AVB: 介绍以太网中用于音视频传输的低时延TSN/AVB协议

这篇文章主要讲第一个话题: Linux是如何在数据链路层L2对网络数据的接收与发送进行优化的.

阅读全文 »

断断续续看了Bjarne Stroustrup的’C++之旅(a tour of C++)’, 作者把很多原本看起来复杂的概念模型都讲的比较清晰, 也有不少好的代码示例, 有种拨云见雾的感觉. 于是想着写一篇文章来总结重新学习C++的一些经验, 主要阐述下现代C++(>=C++11)中那些容易让人混淆而觉得陌生的技术.

了解C++历史的人都知道, Bjarne Stroustrup是在Bell实验室(就是Unix操作系统与C语言诞生的地方)发明了C++, 初衷是在C中加入类(class)的概念, 增强C语言在系统编程上的效率与灵活性, 也正式因为这个原因, C++在1979年最初的名字是带类的C(c with class), 直到1984年才改名为C++. 到今天, C++的发展历经了快40年历史, 但真正一次大的标准修改是在2011年, 这个版本也称为C++11, 也是目前很多公司在使用的版本.接下来我们就来一起来回顾下现代C++中那些曾经让人头疼的技术吧.

阅读全文 »

在优化网络性能时, 不可避免要对网络的带宽进行测试. 通常大家可能都会使用iperf来执行网络链路的吞吐量测试, 但iperf只能测试TCP/IP协议层的速度, 这个带宽数据跟TCP/UDP协议的参数配置以及应用层缓冲区的大小都有关系. 有时, 我们希望直接测试网卡本身的实际吞吐量, 看看网卡实际的发包能力. Linux内核提供了pktgen工具用以产生数据包, 向网卡注入TCP/UDP数据. 这里, 我们就来看下具体如何通过pktgen来测试网卡性能.

阅读全文 »

最近因为公司安全的需求, 要修改openssh的源码, 将其移植到一个ARM的嵌入式系统上, 替换原有的预编译的版本. 参考了网上的一些移植openssh的资料, 如openssl官网编译安装说明; 移植openssh到arm-linux, 但是由于目标平台不一样, 实践起来并不能完全参考, 会有细微的差异. 这里把整个流程写下来, 总结一下, 方便后面移植相关开发工具.

阅读全文 »

深度学习(Deep Learning)是近年来人工智能的热门研究领域, 广泛地应用在工业与商业领域, 如计算机视觉(Computer Vision), 语音识别(Speech Recognition), 自然语言处理(Natural Language Processing), 机器翻译(Machine Translation), 以及医学图像分析, 药物发现等领域都采用了深度学习方法. 从本质上来说, 深度学习属于机器学习(Machine Learning)的一个分支, 是一种从大规模数据进行学习然后能在新数据集进行推理泛化的数学模型.

相比人工智能, 深度学习只是最近十来年才出现的概念, 但为何会在在最近几年(2010开始)内出现井喷式的增长, 成为人工智能领域炙手可热的研究方向了? 总结来说主要有如下几个原因:

阅读全文 »

Android从9.0版本开始全面支持eBPF(extended Berkeley Packet Filters), 其主要用在流量统计上, 也可以用来监控CPU/IO/内存等模块的状态.简单来说, eBPF可以与内核的kprobe/tracepoints/skfilter等模块相结合, 将eBPF的函数hook到内核事件从而监控相应的系统状态.

Android为eBPF提供了许多封装的库, 并提供了eBPF加载器bpfloader:

  • bpfloader: 位于/system/bpf/bpfloader, 系统启动时负责加载位于/system/etc/bpf 中的eBPF目标文件
  • libbpf_android: 位于/system/bpf/libbpf_android提供创建bpf容器/加载bpf目标文件的接口
  • libbpf: 位于/external/bcc, 封装了bpf的系统调用, 提供如attach/deattach程序的接口
  • libnetdbpf: 位于/system/netd/libnetdbpf, 实现了netd流量统计功能的函数

目前在Android(Q)上有两处eBPF的代码: 一个是/system/netd/bpf_progs/netd.c, 主要是用于流量统计;一个是/system/bpfprogs/time_in_state.c用于监控CPU运行频率以及上下文切换的耗时.

接下来我们就从三个部分来深入理解下Android是如何利用eBPF的:

  • eBPF程序与目标文件格式
  • Android eBPF加载与执行流程
  • Android如何基于eBPF实现流量统计
阅读全文 »