使用minicom也有很长时间了,只用minicom抓过uart log,但是从来没有去保存过这个log,也不知道有这个功能。后来在超级终端中发现有这个功能(传送->捕获文字),想想minicom应该也有这个功能才对,后来搜索找到怎么用了,方法如下:
分类: Linux
Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。它能运行主要的UNIX工具软件、应用程序和网络协议。它支持32位和64位硬件。Linux继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。它主要用于基于Intel x86系列CPU的计算机上。这个系统是由全世界各地的成千上万的程序员设计和实现的。其目的是建立不受任何商品化软件的版权制约的、全世界都能自由使用的Unix兼容产品。
hosts.allow、hosts.deny配置不生效的解决方法
通过配置hosts.allow、hosts.deny,控制SSH限制固定IP登陆
按照以往的方法,分别在hosts.allow、hosts.deny加入以下配置
1 2 3 4 5 6 7 |
# more /etc/hosts.allow sshd:192.168.x.x # more /etc/hosts.deny sshd:all |
保存后测试,发现配置无效,其他IP还是可以登陆成功。
解决方法如下:
hosts.allow和hosts.deny属于tcp_Wrappers防火墙的配置文件,而用tcp_Wrappers防火墙控制某一服务访问策略的前提是,该服务支持tcp_Wrappers防火墙,即该服务应用了libwrapped库文件。
查看某服务(如ssh)是否应用了libwrapped库文件的方法是:
1 |
$ ldd /usr/sbin/sshd |grep libwrap.so.0 |
没有显示,表示此服务器上安装的SSH没有应用libwrapped库文件,也就不能用tcp_Wrappers防火墙控制访问策略。(一般情况下服务器默认安装的SSH都是支持libwrapped库文件,这台服务器不清楚为什么不支持)
最终解决方法是重新安装SSH。
1 2 3 4 5 |
$ yum -y remove openssh $ yum -y install openssh $ yum -y install openssh-server |
安装完成后再次查看是否应用了libwrapped库文件,显示支持。
1 2 |
$ ldd /usr/sbin/sshd |grep libwrap.so.0 libwrap.so.0 => /lib/x86_64-linux-gnu/libwrap.so.0 (0x00007f195feb4000) |
再测试SSH登陆,配置生效。
参考链接
ubuntu 16.04删除被denyhosts阻止的IP地址
参照 ubuntu 16.04防止SSH暴力登录攻击 安装denyhosts
之后,由于某些莫名的操作导致自己的一个登录地址被加入了阻止列表,尝试很多次之后,都没有办法恢复。于是找到如下脚本来进行删除操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#!/bin/bash IP=$1 if [ -n "$IP" ];then if [[ $IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]];then service denyhosts stop sed -i "/$IP/d" /etc/hosts.deny sed -i "/$IP/d" /var/lib/denyhosts/hosts-valid sed -i "/$IP/d" /var/lib/denyhosts/users-hosts sed -i "/$IP/d" /var/lib/denyhosts/hosts sed -i "/$IP/d" /var/lib/denyhosts/hosts-root sed -i "/$IP/d" /var/lib/denyhosts/hosts-restricted iptables -D INPUT -s $IP -j DROP echo $IP remove from Denyhosts service denyhosts start else echo "This is not IP" fi else echo "IP is empty" fi |
生成脚本后,如下方式执行:
1 |
$ sudo bash denyhosts_unban.sh 42.120.74.106 |
参考链接
int在32/64位系统中的字节数
Data model | short (integer) | int | long (integer) | long long | pointers, size_t |
Sample operating systems |
---|---|---|---|---|---|---|
SILP64 | 64 | 64 | 64 | 64 | 64 | Classic UNICOS[41] (versus UNICOS/mp, etc.) |
ILP64 | 16 | 64 | 64 | 64 | 64 | HAL Computer Systems port of Solaris to the SPARC64 |
LLP64, IL32P64 |
16 | 32 | 32 | 64 | 64 | Microsoft Windows (x86-64 and IA-64) using Visual C++; and MinGW |
LP64, I32LP64 |
16 | 32 | 64 | 64 | 64 | Most Unix and Unix-like systems, e.g., Solaris, Linux, BSD, macOS. Windows when using Cygwin; z/OS |
参考链接
32位和64位系统区别及int字节数
64-Bit Programming Models: Why LP64?
64-bit computing
What decides the sizeof an integer?
ubuntu 16.04低延迟内核
在某些特殊环境中,比如音视频实时处理(比如MIDI),无线电数据的编解码(比如 OpenAirInterface 明确要求使用低延时内核)等情况下,我们希望系统尽可能的实时,同时又不会降低太多的性能(实时性越高,性能,功耗等的损失越大)。这种情况下,我们可以尝试使用低延时内核。
Linux
提供了五种内核类型,对于内核类型的选择,可以参考如下的解释:
*******************************************
- If you do not require low latency for your system then please use the -generic kernel.
- If you need a low latency system (e.g. for recording audio) then please use the -preempt kernel as a fist choice. This reduces latency but doesn't sacrifice power saving features. It is available only for 64 bit systems (also called amd64).
- If the -preempt kernel does not provide enough low latency for your needs (or you have an 32 bit system) then you should try the -lowlatency kernel.
- If the -lowlatency kernel isn't enough then you should try the -rt kernel
- If the -rt kernel isn't enough stable for you then you should try the -realtime kernel
*******************************************
目前(2018.02)为止,ubuntu
官方库中提供前四种内核,我们一般建议使用lowlatency
版本。可以使用如下命令安装:
1 2 3 4 5 6 7 8 |
$ sudo apt-get install linux-lowlatency $ sudo apt-get install linux-image-`uname -r | cut -d- -f1-2`-lowlatency $ sudo apt-get install linux-headers-`uname -r | cut -d- -f1-2`-lowlatency # 重启加载新内核 $ sudo reboot |
目前,如果机器上使用了nvidia
显卡,并且使用nvidia
的闭源驱动的情况下,重启机器会无法进入图形界面,查看系统日志,出现如下错误信息:
1 2 |
$ cat /var/log/syslog | grep dkms Feb 28 16:23:01 xx-System-Product-Name gpu-manager[831]: Error: can't open /lib/modules/4.13.0-36-lowlatency/updates/dkms |
解决方法如下:
1 2 3 |
#目前最新版本驱动是384版本,如果使用的其他版本,请配置使用的版本 $ sudo dpkg-reconfigure nvidia-384 |
注意,使用sudo apt-get dist-upgrade
升级内核的时候,内核会被替换成generic
版本,低延时内核需要手工重新安装一遍。
参考链接
- linux kernel 的不同类型在设计上有何差别?
- Ingo Molnar 的实时补丁
- Low-Latency Kernel? WTF?!?!
- difference between boot options Lowlatency and Generic?
- 在Linux环境下玩转MIDI
- Nvidia not working on Ubuntu 17.10 on Xorg
- Why choose a low latency kernel over a generic or realtime one?
- UbuntuStudio/RealTimeKernel
- Side-effect on upgrading kernel from generic to low-latency? [duplicate]
linux如何查看已加载的动态库
首先用ps
命令找到进程的pid
。
然后执行如下命令中的任意一个即可:
1 |
$ cat /proc/$PID/maps |
1 |
$ lsof -p $PID | grep .so |
1 |
$ pmap $PID |
参考链接
PTP简介
在通信网络中,许多业务的正常运行都要求网络时钟同步,即整个网络各设备之间的时间或频率差保持在合理的误差水平内。网络时钟同步包括以下两个概念:
时间同步:也叫相位同步(Phase synchronization),是指信号之间的频率和相位都保持一致,即信号之间的相位差恒为零。
频率同步(Frequency synchronization):也叫时钟同步,是指信号之间在频率或相位上保持某种严格的特定关系,信号在其对应的有效瞬间以同一平均速率出现,以保证通信网络中的所有设备都以相同的速率运行,即信号之间保持恒定的相位差。
网络时钟同步协议-- NTP, PTP
这篇文章介绍一下两个时钟同步的网络协议:NTP和PTP。
这里不涉及协议的原理和具体实现(想了解的可自行Google),重点是如何搭建起这两个服务。
1. NTP及PTP简介
NTP(Network Time Protocol)是用于不同计算机之间同步时钟的网络协议。
它的设计目标是使所有的互连的机器之间的时钟与UTC时间只相差若干毫秒。
目前NTP协议已经是有第4版了,如果不需要了解NTP太多细节的话,看看这个wiki页面应该就足够了。需要注意的就是它有clock strata的概念。
PTP(Precision Time Protocol)看名字就知道是一个比NTP更精确的时钟同步协议了,PTP的设计目标是使机器之间的时钟偏差在sub-microsecond范围—这是wiki页面上提到的,有其他的地方说的是偏差若干微秒,本文搭建的环境中测量到的偏差也在微秒级别,没有到sub-microsecond级别。在使用PTP协议时,需要了解的主要概念点就是它的master/slave机制。
接下来我们就介绍我搭建NTP和PTP环境的过程,所用到的操作系统是CentOS6.5,内核版本是3.10。其他软件的版本会在用到时提及。
2. 搭建NTP服务
配置环境:两台服务器,一台做NTP服务器,一台做NTP的客户端。同时这两台机器都未联网。
NTP服务器地址:192.168.0.11
NTP客户端地址:192.168.0.22
A. 在192.168.0.11中启动NTP服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$ service iptables stop // 首先把防火墙关了 $ yum list |grep ntp // 看下yum源中是否有ntp软件 $ yum install -y ntp $ ntpd --version ntpd 4.2.6p5 $ vim /etc/ntp.conf // 修改配置文件 restrict 192.168.0.11 mask 255.255.255.0 nomodify nostrap // 限制作为局域网NTP服务器 // 下面两句很关键。含义是如果这台NTP服务器的server地址无法访问, // 则将本地时间作为NTP服务时间,这个IP地址也是固定的,不要修改 server 127.127.1.0 fudge 127.127.1.0 stratum 10 $ ntpd -p /var/run/ntpd.pid // 启动ntpd $ service ntpd start // 第二种启动ntpd服务的方法 // 等待5分钟 $ ntpstat // 从这条命令应该能看到NTP时钟同步好了,正常的显示结果应该与下面类似 synchronised to local net at stratum 11 time correct to within 11 ms polling server every 64 s |
B. 在192.168.0.22上启动NTP服务,选择192.168.0.11为NTP服务器
1 2 3 4 5 6 |
$ service iptables stop $ yum install -y ntp $ vim /etc/ntp.conf // 添加下面这个server地址,把其他的都注释掉 server 192.168.0.11 $ service ntpd start $ netstat // 等待若干时间应该就能够显示同步成功了 |
我的这两台实验机器是在同一个Rack的,结果显示差不多同步的偏差在30ms左右。
每个版本的ntpd配置文件可能有少许的差别,不过好在注释都做的不错,所以别的细节就不啰嗦了。
3. 搭建PTP服务
从List of PTP implementations可以看到PTP的实现有很多很多种,可以是硬件实现的,可以是软件实现的也可以是软硬件结合实现的。本文中搭建的PTP服务是基于软件PTPd。如果没有特殊的硬件的话,这算是一种非常方便的方法了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
$ service iptables stop // 关掉防火墙 $ yum list |grep ptp // 检查yum源 $ yum install -y ptpd $ ptpd2 --version ptpd2 version 2.3.0 // 弄一个管理脚本,从serverfault找来的 :) // http://serverfault.com/questions/329127/ptp-time-synchronization-on-centos6-rhel $ vim ptpd.sh // 将PTPADRGS 改为 PTPD_EXTRA_OPTIONS $ chmod +x ptpd.sh $ vim /etc/ptpd2.conf // 修改配置文件 ptpengine:preset=masterslave // 对于master主机,不要选masteronly,具体原因请查看help ptpengine:preset=slaveonly // 对于slave主机 // 其他选项也可以根据需要进行调整,比如log是否开启,是否绑定CPU。这些看配置文件的注释就好了 $ vim /etc/sysconfig/ptpd2 // 修改启动命令,主要就是指定PTPD的配置文件 PTPD_EXTRA_OPTIONS="-c /etc/ptpd2.conf" // 现在就可以使用下面三个命令来启动,查看和关闭ptpd服务了 $ ./ptpd.sh start $ ./ptpd.sh status $ ./ptpd.sh stop |
如果遇到任何问题,首先一定要看看help,使用-H选项的话还能看到非常详细的配置(虽然大多我可看不懂,不过不能不看,理解的越多,遇到的问题就会越少)。
如果log里面的信息看不懂,可以把代码下下来,一个grep搞定。
经测试,在我的机器上使用PTPD软件搭建的服务,时钟偏移的平均值能够达到5us左右。这个粒度基本能满足我们的需求了。
参考链接
Linux中的时钟准确度
本文来自戴尔软件开发高级工程师Stuart Hayes
一个关于计时的问题最近引起了我的关注。 有用户在 Dell 服务器上运行 Linux,并且发现时钟时间(Linux 所报告的)每天误差五秒以上,偏差比较明显。
我们首先想到的也许是运行 NTP,定期与真实世界同步操作系统的时钟。
但是这样的误差最初是如何产生的?
在Linux运行时,Linux 系统未使用实时时钟(real time clock - RTC) 硬件来计时。 Linux 通常在启动时从RTC 读取时间,然后从该点开始,Linux 使用另一个时钟来源(系统中的另一个计时器/计数器)来计时。
自第 2.6.18 版起,Linux 的内核就使用 CPU 时间戳计数器 (TSC) 作为首选的时钟来源(假设 TSC 以恒定频率运行,以新款的 Intel 服务器 CPU为例)。 但是,尽管读取速度很快且解析度很高,TSC 却不是一个已知的频率。 当内核使启动时,它需要使用频率已知的另一个计时器,对其进行校准。 这样的校准并非天衣无缝(即使用于校准的计时器也是如此),因此把 TSC 作为时钟来源会造成时间误差。
如果减少时间误差对您非常重要,而非若干微秒的调度延迟,则最好使用频率已知的计时器,如大多数 x86 服务器上提供的 HPET(高精度事件计时器)。 借助新内核上的参数"clocksource=hpet
"可实现这一目标。 HPET 计时器以已知、固定的频率运行,Linux 内核可直接从计时器读取时间。
话说回来,尽管 HPET 的精度高于 TSC,运行 NTP 以在 Linux 中实现长期的时钟精度始终是很好的想法。
上述讨论仅适用于运行于裸机的 Linux。 在虚拟机中的问题略微复杂。
原文链接
Linux时钟精度:毫秒?微妙?纳秒?
最近被内核时钟精度弄的很是郁闷。具体情况如下:
扫盲:1秒=1000毫秒=1000000微妙=1000000000纳秒
首先:linux有一个很重要的概念——节拍,它的单位是(次/秒)。2.6内核这个值是1000,系统中用一个HZ的宏表征这个值。同时有全局的jiffies变量,表征从开机以来经过的节拍次数(这里面还有故事,后面说,先记住这个)。当然还有wall_jiffies的墙上jiffies来表示从 07-01-1970 到现在的节拍数。每个节拍里面执行一次时钟中断。就是说,它的精度是毫秒。
接着:内核中还有一个变量xtime表征系统的实际时间(墙上时间),定义如下。其中xtime.tv_sec以秒为单位,存放从Unix祖宗定的纪元时间(19700701)到现在的秒数。xtime.tv_nsec以纳秒为单位,记录从上一秒开始经过的纳秒数。就是说,它的精度是纳秒。
1 2 3 4 5 6 |
struct timespec xtime; struct timespec{ time_t tv_sec; //秒 long tv_nsec; //纳秒 }; |
最后:linux提供一个gettimeofday的系统调用,它会返回一个timeval的结构体,定义如下。解释同上,tv_sec代表墙上时间的秒,tv_usec表示从上一秒到现在经过的微秒数。就是说,它的精度是微妙。
1 2 3 4 |
struct timeval{ long tv_sec; //秒 long tv_usec; //微妙 }; |
精彩的来了:
1. 内核中的xtime会在每个时钟中断的时候被更新一次,也就是每个节拍更新一次。你妹!!每毫秒更新一次怎么能冒出来纳秒的精度??而且,内核还有可能丢失节拍。怎么能是纳秒??
2. 各种书上说,gettimeofday系统调用是读取的xtime的值。日,为啥读出来之后精度丢了?变成微妙了?
寻寻觅觅终于理清了故事:
针对问题1:在linux启动的时候,一个节拍的时间长度还会以纳秒为单位初始化到tick_nsec中,初始化值为999848ns,坑爹啊!不到一毫秒!节拍大约为1000.15Hz。靠!实际的节拍竟然不是准确的1000!所以在每个时钟中断通过wall_jiffies去更新xtime的时候得到的就是一个以纳秒为最小单位的的值。所以!xtime的粒度应该是不到1毫秒,也就是精度是不到1毫秒。
针对问题2:gettimeday系统调用的读xtime代码部分如下:
1 2 3 4 5 6 7 8 9 10 11 12 |
do{ unsigned long lost; seq = read_seqbegin(&xtime_lock); usec = timer->get_offset(); //在计时器中取从上一次时钟中断到现在的微秒数 lost = jiffies - wall_jiffies; if(lost) usec += lost*(1000000/HZ); //HZ是节拍宏,值1000 sec = xtime.tv_sec; usec += (xtime.tv_nsec/1000); //由纳秒转为微妙 }while(read_seqretry(&xtime_lock, seq)) |
while部分使用了seg锁,只看中间的就好了。加了注释之后就很清晰了。由于节拍可能会丢失,所以lost是丢失的节拍数(不会很多)。至于计时器就比较麻烦了,timer可能有下面四种情况。
a. 如果cur_timer指向timer_hpet对象,该方法使用HPET定时器——Inter与Microsoft开发的高精度定时器频率至少10MHz,也就是说此时可提供真正的微妙级精度。
b. 如果cur_timer指向timer_pmtmr对象,该方法使用ACPI PMT计时器(电源管理定时器)平率大约3.58MHz,也就是说也可以提供真正的微妙级精度。
c. 如果cur_timer指向timer_tsc对象,该方法使用时间戳计数器,内置在所有8086处理器,每个CPU时钟,计数器增加一次,频率就是CPU频率,所以timer精度最高。完全可以胜任微妙级的精度。
d. 如果cur_timer指向timer_pit对象,该方法使用PIT计数器,也即是最开始提到的节拍计数,频率大概是1000Hz,此时显然不能提供精度达到微妙的时间。所以只有这种情况是假毫秒精度!
综上:如果使用gettimeofday系统调用,只要不要使用节拍计数器就可以保证达到微妙精度的时间(刨除进程上下文时间误差)。至于网上说的可以拿到纳秒精度的时间,看起来都是错的。除非通过修改内核,使用时间戳计数器实现。Over!
最后最后说一个事情:jiffies的定义的是4字节,你可能猜想它初始值是0。实际上,事实并非如此!linux中jiffies被初始化为0xfffb6c20,它是一个32位有符号数,正好等于-300 000。因此,计数器会在系统启动5分钟内溢出。这是为了使对jiffies溢出处理有缺陷的内核代码在开发阶段被发现,避免此类问题出现在稳定版本中。
参考《深入理解linux内核》