mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-01-28 23:20:10 +08:00
commit
5c969599b8
@ -0,0 +1,339 @@
|
||||
如何搜索一个包是否在你的 Linux 发行版中
|
||||
======
|
||||
|
||||
如果你知道包名称,那么你可以直接安装所需的包。
|
||||
|
||||
在某些情况下,如果你不知道确切的包名称或者你想搜索某些包,那么你可以在发行版的包管理器的帮助下轻松搜索该包。搜索会自动包括已安装和可用的包。结果的格式取决于选项。如果你的查询没有输出任何信息,那么意味着没有匹配条件的包。这可以通过发行版的包管理器的各种选项来完成。我已经在本文中添加了所有可能的选项,你可以选择最好的和最合适你的选项。
|
||||
|
||||
或者,我们可以通过 `whohas` 命令实现这一点。它会从所有的主流发行版(例如 Debian、Ubuntu、 Fedora 等)中搜索,而不仅仅是你自己的系统发行版。
|
||||
|
||||
建议阅读:
|
||||
|
||||
- [适用于 Linux 的命令行包管理器列表以及用法][1]
|
||||
- [Linux 包管理器的图形前端工具][2]
|
||||
|
||||
### 如何在 Debian/Ubuntu 中搜索一个包
|
||||
|
||||
我们可以使用 `apt`、`apt-cache` 和 `aptitude` 包管理器在基于 Debian 的发行版上查找给定的包。我为这个包管理器中包括了大量的选项。
|
||||
|
||||
我们可以在基于 Debian 的系统中使用三种方式完成此操作。
|
||||
|
||||
* `apt` 命令
|
||||
* `apt-cache` 命令
|
||||
* `aptitude` 命令
|
||||
|
||||
#### 如何使用 apt 命令搜索一个包
|
||||
|
||||
APT 代表<ruby>高级包管理工具<rt>Advanced Packaging Tool</rt></ruby>(APT),它取代了 `apt-get`。它有功能丰富的命令行工具,包括所有功能包含在一个命令(`apt`)里,包括 `apt-cache`、`apt-search`、`dpkg`、`apt-cdrom`、`apt-config`、`apt-key` 等,还有其他几个独特的功能。
|
||||
|
||||
APT 是一个强大的命令行工具,它可以访问 libapt-pkg 底层库的所有特性,它可以用于安装、下载、删除、搜索和管理以及查询包的信息,另外它还包含一些较少使用的与包管理相关的命令行实用程序。
|
||||
|
||||
```
|
||||
$ apt -q list nano vlc
|
||||
Listing...
|
||||
nano/artful,now 2.8.6-3 amd64 [installed]
|
||||
vlc/artful 2.2.6-6 amd64
|
||||
```
|
||||
|
||||
或者,我们可以使用以下格式搜索指定的包。
|
||||
|
||||
```
|
||||
$ apt search ^vlc
|
||||
Sorting... Done
|
||||
Full Text Search... Done
|
||||
vlc/artful 2.2.6-6 amd64
|
||||
multimedia player and streamer
|
||||
|
||||
vlc-bin/artful 2.2.6-6 amd64
|
||||
binaries from VLC
|
||||
|
||||
vlc-data/artful,artful 2.2.6-6 all
|
||||
Common data for VLC
|
||||
|
||||
vlc-l10n/artful,artful 2.2.6-6 all
|
||||
Translations for VLC
|
||||
|
||||
vlc-plugin-access-extra/artful 2.2.6-6 amd64
|
||||
multimedia player and streamer (extra access plugins)
|
||||
|
||||
vlc-plugin-base/artful 2.2.6-6 amd64
|
||||
multimedia player and streamer (base plugins)
|
||||
```
|
||||
|
||||
#### 如何使用 apt-cache 命令搜索一个包
|
||||
|
||||
`apt-cache` 会在 APT 的包缓存上执行各种操作。它会显示有关指定包的信息。`apt-cache` 不会改变系统的状态,但提供了从包的元数据中搜索和生成有趣输出的操作。
|
||||
|
||||
```
|
||||
$ apt-cache search nano | grep ^nano
|
||||
nano - small, friendly text editor inspired by Pico
|
||||
nano-tiny - small, friendly text editor inspired by Pico - tiny build
|
||||
nanoblogger - Small weblog engine for the command line
|
||||
nanoblogger-extra - Nanoblogger plugins
|
||||
nanoc - static site generator written in Ruby
|
||||
nanoc-doc - static site generator written in Ruby - documentation
|
||||
nanomsg-utils - nanomsg utilities
|
||||
nanopolish - consensus caller for nanopore sequencing data
|
||||
```
|
||||
|
||||
或者,我们可以使用以下格式搜索指定的包。
|
||||
|
||||
```
|
||||
$ apt-cache policy vlc
|
||||
vlc:
|
||||
Installed: (none)
|
||||
Candidate: 2.2.6-6
|
||||
Version table:
|
||||
2.2.6-6 500
|
||||
500 http://in.archive.ubuntu.com/ubuntu artful/universe amd64 Packages
|
||||
```
|
||||
|
||||
或者,我们可以使用以下格式搜索给定的包。
|
||||
|
||||
```
|
||||
$ apt-cache pkgnames vlc
|
||||
vlc-bin
|
||||
vlc-plugin-video-output
|
||||
vlc-plugin-sdl
|
||||
vlc-plugin-svg
|
||||
vlc-plugin-samba
|
||||
vlc-plugin-fluidsynth
|
||||
vlc-plugin-qt
|
||||
vlc-plugin-skins2
|
||||
vlc-plugin-visualization
|
||||
vlc-l10n
|
||||
vlc-plugin-notify
|
||||
vlc-plugin-zvbi
|
||||
vlc-plugin-vlsub
|
||||
vlc-plugin-jack
|
||||
vlc-plugin-access-extra
|
||||
vlc
|
||||
vlc-data
|
||||
vlc-plugin-video-splitter
|
||||
vlc-plugin-base
|
||||
```
|
||||
|
||||
#### 如何使用 aptitude 命令搜索一个包
|
||||
|
||||
`aptitude` 是一个基于文本的 Debian GNU/Linux 软件包系统的命令行界面。它允许用户查看包列表,并执行包管理任务,例如安装、升级和删除包,它可以从可视化界面或命令行执行操作。
|
||||
|
||||
```
|
||||
$ aptitude search ^vlc
|
||||
p vlc - multimedia player and streamer
|
||||
p vlc:i386 - multimedia player and streamer
|
||||
p vlc-bin - binaries from VLC
|
||||
p vlc-bin:i386 - binaries from VLC
|
||||
p vlc-data - Common data for VLC
|
||||
v vlc-data:i386 -
|
||||
p vlc-l10n - Translations for VLC
|
||||
v vlc-l10n:i386 -
|
||||
p vlc-plugin-access-extra - multimedia player and streamer (extra access plugins)
|
||||
p vlc-plugin-access-extra:i386 - multimedia player and streamer (extra access plugins)
|
||||
p vlc-plugin-base - multimedia player and streamer (base plugins)
|
||||
p vlc-plugin-base:i386 - multimedia player and streamer (base plugins)
|
||||
p vlc-plugin-fluidsynth - FluidSynth plugin for VLC
|
||||
p vlc-plugin-fluidsynth:i386 - FluidSynth plugin for VLC
|
||||
p vlc-plugin-jack - Jack audio plugins for VLC
|
||||
p vlc-plugin-jack:i386 - Jack audio plugins for VLC
|
||||
p vlc-plugin-notify - LibNotify plugin for VLC
|
||||
p vlc-plugin-notify:i386 - LibNotify plugin for VLC
|
||||
p vlc-plugin-qt - multimedia player and streamer (Qt plugin)
|
||||
p vlc-plugin-qt:i386 - multimedia player and streamer (Qt plugin)
|
||||
p vlc-plugin-samba - Samba plugin for VLC
|
||||
p vlc-plugin-samba:i386 - Samba plugin for VLC
|
||||
p vlc-plugin-sdl - SDL video and audio output plugin for VLC
|
||||
p vlc-plugin-sdl:i386 - SDL video and audio output plugin for VLC
|
||||
p vlc-plugin-skins2 - multimedia player and streamer (Skins2 plugin)
|
||||
p vlc-plugin-skins2:i386 - multimedia player and streamer (Skins2 plugin)
|
||||
p vlc-plugin-svg - SVG plugin for VLC
|
||||
p vlc-plugin-svg:i386 - SVG plugin for VLC
|
||||
p vlc-plugin-video-output - multimedia player and streamer (video output plugins)
|
||||
p vlc-plugin-video-output:i386 - multimedia player and streamer (video output plugins)
|
||||
p vlc-plugin-video-splitter - multimedia player and streamer (video splitter plugins)
|
||||
p vlc-plugin-video-splitter:i386 - multimedia player and streamer (video splitter plugins)
|
||||
p vlc-plugin-visualization - multimedia player and streamer (visualization plugins)
|
||||
p vlc-plugin-visualization:i386 - multimedia player and streamer (visualization plugins)
|
||||
p vlc-plugin-vlsub - VLC extension to download subtitles from opensubtitles.org
|
||||
p vlc-plugin-zvbi - VBI teletext plugin for VLC
|
||||
p vlc-plugin-zvbi:i386
|
||||
```
|
||||
|
||||
### 如何在 RHEL/CentOS 中搜索一个包
|
||||
|
||||
Yum(Yellowdog Updater Modified)是 Linux 操作系统中的包管理器实用程序之一。Yum 命令用于在一些基于 RedHat 的 Linux 发行版上,它用来安装、更新、搜索和删除软件包。
|
||||
|
||||
```
|
||||
# yum search ftpd
|
||||
Loaded plugins: fastestmirror, refresh-packagekit, security
|
||||
Loading mirror speeds from cached hostfile
|
||||
* base: centos.hyve.com
|
||||
* epel: mirrors.coreix.net
|
||||
* extras: centos.hyve.com
|
||||
* rpmforge: www.mirrorservice.org
|
||||
* updates: mirror.sov.uk.goscomb.net
|
||||
============================================================== N/S Matched: ftpd ===============================================================
|
||||
nordugrid-arc-gridftpd.x86_64 : ARC gridftp server
|
||||
pure-ftpd.x86_64 : Lightweight, fast and secure FTP server
|
||||
vsftpd.x86_64 : Very Secure Ftp Daemon
|
||||
|
||||
Name and summary matches only, use "search all" for everything.
|
||||
```
|
||||
|
||||
或者,我们可以使用以下命令搜索相同内容。
|
||||
|
||||
```
|
||||
# yum list ftpd
|
||||
```
|
||||
|
||||
### 如何在 Fedora 中搜索一个包
|
||||
|
||||
DNF 代表 Dandified yum。我们可以说 DNF 是下一代 yum 包管理器(Yum 的衍生品),它使用 hawkey/libsolv 库作为底层。Aleš Kozumplík 从 Fedora 18 开始开发 DNF,最终在 Fedora 22 中发布。
|
||||
|
||||
```
|
||||
# dnf search ftpd
|
||||
Last metadata expiration check performed 0:42:28 ago on Tue Jun 9 22:52:44 2018.
|
||||
============================== N/S Matched: ftpd ===============================
|
||||
proftpd-utils.x86_64 : ProFTPD - Additional utilities
|
||||
pure-ftpd-selinux.x86_64 : SELinux support for Pure-FTPD
|
||||
proftpd-devel.i686 : ProFTPD - Tools and header files for developers
|
||||
proftpd-devel.x86_64 : ProFTPD - Tools and header files for developers
|
||||
proftpd-ldap.x86_64 : Module to add LDAP support to the ProFTPD FTP server
|
||||
proftpd-mysql.x86_64 : Module to add MySQL support to the ProFTPD FTP server
|
||||
proftpd-postgresql.x86_64 : Module to add PostgreSQL support to the ProFTPD FTP
|
||||
: server
|
||||
vsftpd.x86_64 : Very Secure Ftp Daemon
|
||||
proftpd.x86_64 : Flexible, stable and highly-configurable FTP server
|
||||
owfs-ftpd.x86_64 : FTP daemon providing access to 1-Wire networks
|
||||
perl-ftpd.noarch : Secure, extensible and configurable Perl FTP server
|
||||
pure-ftpd.x86_64 : Lightweight, fast and secure FTP server
|
||||
pyftpdlib.noarch : Python FTP server library
|
||||
nordugrid-arc-gridftpd.x86_64 : ARC gridftp server
|
||||
```
|
||||
|
||||
或者,我们可以使用以下命令搜索相同的内容。
|
||||
|
||||
```
|
||||
# dnf list proftpd
|
||||
Failed to synchronize cache for repo 'heikoada-terminix', disabling.
|
||||
Last metadata expiration check: 0:08:02 ago on Tue 26 Jun 2018 04:30:05 PM IST.
|
||||
Available Packages
|
||||
proftpd.x86_64
|
||||
```
|
||||
|
||||
### 如何在 Arch Linux 中搜索一个包
|
||||
|
||||
pacman 代表包管理实用程序(pacman)。它是一个用于安装、构建、删除和管理 Arch Linux 软件包的命令行实用程序。pacman 使用 libalpm(Arch Linux Package Management(ALPM)库)作为底层来执行所有操作。
|
||||
|
||||
在本例中,我将要搜索 chromium 包。
|
||||
|
||||
```
|
||||
# pacman -Ss chromium
|
||||
extra/chromium 48.0.2564.116-1
|
||||
The open-source project behind Google Chrome, an attempt at creating a safer, faster, and more stable browser
|
||||
extra/qt5-webengine 5.5.1-9 (qt qt5)
|
||||
Provides support for web applications using the Chromium browser project
|
||||
community/chromium-bsu 0.9.15.1-2
|
||||
A fast paced top scrolling shooter
|
||||
community/chromium-chromevox latest-1
|
||||
Causes the Chromium web browser to automatically install and update the ChromeVox screen reader extention. Note: This
|
||||
package does not contain the extension code.
|
||||
community/fcitx-mozc 2.17.2313.102-1
|
||||
Fcitx Module of A Japanese Input Method for Chromium OS, Windows, Mac and Linux (the Open Source Edition of Google Japanese
|
||||
Input)
|
||||
```
|
||||
|
||||
默认情况下,`-s` 选项内置 ERE(扩展正则表达式)会导致很多不需要的结果。使用以下格式会仅匹配包名称。
|
||||
|
||||
```
|
||||
# pacman -Ss '^chromium-'
|
||||
```
|
||||
|
||||
`pkgfile` 是一个用于在 Arch Linux 官方仓库的包中搜索文件的工具。
|
||||
|
||||
```
|
||||
# pkgfile chromium
|
||||
```
|
||||
|
||||
### 如何在 openSUSE 中搜索一个包
|
||||
|
||||
Zypper 是 SUSE 和 openSUSE 发行版的命令行包管理器。它用于安装、更新、搜索和删除包以及管理仓库,执行各种查询等。Zypper 命令行对接到 ZYpp 系统管理库(libzypp)。
|
||||
|
||||
```
|
||||
# zypper search ftp
|
||||
or
|
||||
# zypper se ftp
|
||||
Loading repository data...
|
||||
Reading installed packages...
|
||||
S | Name | Summary | Type
|
||||
--+----------------+-----------------------------------------+--------
|
||||
| proftpd | Highly configurable GPL-licensed FTP -> | package
|
||||
| proftpd-devel | Development files for ProFTPD | package
|
||||
| proftpd-doc | Documentation for ProFTPD | package
|
||||
| proftpd-lang | Languages for package proftpd | package
|
||||
| proftpd-ldap | LDAP Module for ProFTPD | package
|
||||
| proftpd-mysql | MySQL Module for ProFTPD | package
|
||||
| proftpd-pgsql | PostgreSQL Module for ProFTPD | package
|
||||
| proftpd-radius | Radius Module for ProFTPD | package
|
||||
| proftpd-sqlite | SQLite Module for ProFTPD | package
|
||||
| pure-ftpd | A Lightweight, Fast, and Secure FTP S-> | package
|
||||
| vsftpd | Very Secure FTP Daemon - Written from-> | package
|
||||
```
|
||||
|
||||
### 如何使用 whohas 命令搜索一个包
|
||||
|
||||
`whohas` 命令是一个智能工具,从所有主流发行版中搜索指定包,如 Debian、Ubuntu、Gentoo、Arch、AUR、Mandriva、Fedora、Fink、FreeBSD 和 NetBSD。
|
||||
|
||||
```
|
||||
$ whohas nano
|
||||
Mandriva nano-debug 2.3.1-1mdv2010.2.x http://sophie.zarb.org/rpms/0b33dc73bca710749ad14bbc3a67e15a
|
||||
Mandriva nano-debug 2.2.4-1mdv2010.1.i http://sophie.zarb.org/rpms/d9dfb2567681e09287b27e7ac6cdbc05
|
||||
Mandriva nano-debug 2.2.4-1mdv2010.1.x http://sophie.zarb.org/rpms/3299516dbc1538cd27a876895f45aee4
|
||||
Mandriva nano 2.3.1-1mdv2010.2.x http://sophie.zarb.org/rpms/98421c894ee30a27d9bd578264625220
|
||||
Mandriva nano 2.3.1-1mdv2010.2.i http://sophie.zarb.org/rpms/cea07b5ef9aa05bac262fc7844dbd223
|
||||
Mandriva nano 2.2.4-1mdv2010.1.s http://sophie.zarb.org/rpms/d61f9341b8981e80424c39c3951067fa
|
||||
Mandriva spring-mod-nanoblobs 0.65-2mdv2010.0.sr http://sophie.zarb.org/rpms/74bb369d4cbb4c8cfe6f6028e8562460
|
||||
Mandriva nanoxml-lite 2.2.3-4.1.4mdv2010 http://sophie.zarb.org/rpms/287a4c37bc2a39c0f277b0020df47502
|
||||
Mandriva nanoxml-manual-lite 2.2.3-4.1.4mdv2010 http://sophie.zarb.org/rpms/17dc4f638e5e9964038d4d26c53cc9c6
|
||||
Mandriva nanoxml-manual 2.2.3-4.1.4mdv2010 http://sophie.zarb.org/rpms/a1b5092cd01fc8bb78a0f3ca9b90370b
|
||||
Gentoo nano 9999 http://packages.gentoo.org/package/app-editors/nano
|
||||
Gentoo nano 9999 http://packages.gentoo.org/package/app-editors/nano
|
||||
Gentoo nano 2.9.8 http://packages.gentoo.org/package/app-editors/nano
|
||||
Gentoo nano 2.9.7
|
||||
```
|
||||
|
||||
如果你希望只从当前发行版仓库中搜索指定包,使用以下格式:
|
||||
|
||||
```
|
||||
$ whohas -d Ubuntu vlc
|
||||
Ubuntu vlc 2.1.6-0ubuntu14.04 1M all http://packages.ubuntu.com/trusty/vlc
|
||||
Ubuntu vlc 2.1.6-0ubuntu14.04 1M all http://packages.ubuntu.com/trusty-updates/vlc
|
||||
Ubuntu vlc 2.2.2-5ubuntu0.16. 1M all http://packages.ubuntu.com/xenial/vlc
|
||||
Ubuntu vlc 2.2.2-5ubuntu0.16. 1M all http://packages.ubuntu.com/xenial-updates/vlc
|
||||
Ubuntu vlc 2.2.6-6 40K all http://packages.ubuntu.com/artful/vlc
|
||||
Ubuntu vlc 3.0.1-3build1 32K all http://packages.ubuntu.com/bionic/vlc
|
||||
Ubuntu vlc 3.0.2-0ubuntu0.1 32K all http://packages.ubuntu.com/bionic-updates/vlc
|
||||
Ubuntu vlc 3.0.3-1 33K all http://packages.ubuntu.com/cosmic/vlc
|
||||
Ubuntu browser-plugin-vlc 2.0.6-2 55K all http://packages.ubuntu.com/trusty/browser-plugin-vlc
|
||||
Ubuntu browser-plugin-vlc 2.0.6-4 47K all http://packages.ubuntu.com/xenial/browser-plugin-vlc
|
||||
Ubuntu browser-plugin-vlc 2.0.6-4 47K all http://packages.ubuntu.com/artful/browser-plugin-vlc
|
||||
Ubuntu browser-plugin-vlc 2.0.6-4 47K all http://packages.ubuntu.com/bionic/browser-plugin-vlc
|
||||
Ubuntu browser-plugin-vlc 2.0.6-4 47K all http://packages.ubuntu.com/cosmic/browser-plugin-vlc
|
||||
Ubuntu libvlc-bin 2.2.6-6 27K all http://packages.ubuntu.com/artful/libvlc-bin
|
||||
Ubuntu libvlc-bin 3.0.1-3build1 17K all http://packages.ubuntu.com/bionic/libvlc-bin
|
||||
Ubuntu libvlc-bin 3.0.2-0ubuntu0.1 17K all
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/how-to-search-if-a-package-is-available-on-your-linux-distribution-or-not/
|
||||
|
||||
作者:[Prakash Subramanian][a]
|
||||
选题:[lujun9972](https://github.com/lujun9972)
|
||||
译者:[MjSeven](https://github.com/MjSeven)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.2daygeek.com/author/prakash/
|
||||
[1]:https://www.2daygeek.com/list-of-command-line-package-manager-for-linux/
|
||||
[2]:https://www.2daygeek.com/list-of-graphical-frontend-tool-for-linux-package-manager/
|
@ -1,77 +1,65 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10503-1.html)
|
||||
[#]: subject: (Hegemon – A Modular System And Hardware Monitoring Tool For Linux)
|
||||
[#]: via: (https://www.2daygeek.com/hegemon-a-modular-system-and-hardware-monitoring-tool-for-linux/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
Hegemon - 一个 Linux 中的模块化系统和硬件监控工具
|
||||
Hegemon:一个 Linux 的模块化系统和硬件监控工具
|
||||
======
|
||||
|
||||
我知道每个人都更喜欢使用 **[top 命令][1]**来监控系统利用率。
|
||||
我知道每个人都更喜欢使用 [top 命令][1]来监控系统利用率。这是被 Linux 系统管理员大量使用的原生命令之一。
|
||||
|
||||
这是被 Linux 系统管理员大量使用的原生命令之一。
|
||||
在 Linux 中,每个包都有一个替代品。Linux 中有许多可用于此的工具,我更喜欢 [htop 命令][2]。
|
||||
|
||||
在 Linux 中,每个包都有一个替代品。
|
||||
如果你想了解其他替代方案,我建议你浏览每个链接了解更多信息。它们有 htop、CorFreq、glances、atop、Dstat、Gtop、Linux Dash、Netdata、Monit 等。
|
||||
|
||||
Linux 中有许多可用于此的工具,我更喜欢 **[htop 命令][2]**。
|
||||
所有这些只允许我们监控系统利用率而不能监控系统硬件。但是 Hegemon 允许我们在单个仪表板中监控两者。
|
||||
|
||||
如果你想了解其他替代方案,我建议你浏览每个链接了解更多信息。
|
||||
|
||||
它们有 htop、CorFreq、glances、atop、Dstat、Gtop、Linux Dash、Netdata、Monit 等。
|
||||
|
||||
所有这些只允许我们监控系统利用率而不能监控系统硬件。
|
||||
|
||||
但是 Hegemon 允许我们在单个仪表板中监控两者。
|
||||
|
||||
如果你正在寻找系统硬件监控软件,那么我建议你看下 **[lm_sensors][3]** 和 **[s-tui 压力终端 UI][4]**。
|
||||
如果你正在寻找系统硬件监控软件,那么我建议你看下 [lm_sensors][3] 和 [s-tui 压力终端 UI][4]。
|
||||
|
||||
### Hegemon 是什么?
|
||||
|
||||
Hegemon 是一个正在开发中的模块化系统监视器, 以安全的 Rust 编写。
|
||||
Hegemon 是一个正在开发中的模块化系统监视器,以安全的 Rust 编写。
|
||||
|
||||
它允许用户在单个仪表板中监控两种使用情况。分别是系统利用率和硬件温度。
|
||||
|
||||
### Hegemon 目前的特性
|
||||
|
||||
* 监控 CPU 和内存使用情况、温度和风扇速度
|
||||
* 展开任何数据流以显示更详细的图表和其他信息
|
||||
* 可调整的更新间隔
|
||||
* 干净的 MVC 架构,具有良好的代码质量
|
||||
* 单元测试
|
||||
|
||||
|
||||
* 展开任何数据流以显示更详细的图表和其他信息
|
||||
* 可调整的更新间隔
|
||||
* 干净的 MVC 架构,具有良好的代码质量
|
||||
* 单元测试
|
||||
|
||||
### 计划的特性包括
|
||||
|
||||
* macOS 和 BSD 支持(目前仅支持 Linux)
|
||||
* 监控磁盘和网络 I/O、GPU使用情况(可能)等
|
||||
* 监控磁盘和网络 I/O、GPU 使用情况(可能)等
|
||||
* 选择并重新排序数据流
|
||||
* 鼠标控制
|
||||
|
||||
|
||||
|
||||
### 如何在 Linux 中安装 Hegemon?
|
||||
|
||||
Hegemon 需要 Rust 1.26 或更高版本以及 libsensors 的开发文件。因此,请确保在安装 Hegemon 之前安装了这些软件包。
|
||||
|
||||
libsensors 库在大多数发行版官方仓库中都有,因此,使用以下命令进行安装。
|
||||
|
||||
对于 **`Debian/Ubuntu`** 系统,使用 **[apt-get 命令][5]** 或 **[apt 命令][6]** 在你的系统上安装 libsensors。
|
||||
对于 Debian/Ubuntu 系统,使用 [apt-get 命令][5] 或 [apt 命令][6] 在你的系统上安装 libsensors。
|
||||
|
||||
```
|
||||
# apt install lm_sensors-devel
|
||||
```
|
||||
|
||||
对于 **`Fedora`** 系统,使用 **[dnf 包管理器][7]**在你的系统上安装 libsensors。
|
||||
对于 Fedora 系统,使用 [dnf 包管理器][7]在你的系统上安装 libsensors。
|
||||
|
||||
```
|
||||
# dnf install libsensors4-dev
|
||||
```
|
||||
|
||||
运行以下命令安装 Rust 语言,并按照指示来做。如果你想要看 **[Rust 安装][8]**的方便教程,请进入这个 URL。
|
||||
运行以下命令安装 Rust 语言,并按照指示来做。如果你想要看 [Rust 安装][8]的方便教程,请进入该 URL。
|
||||
|
||||
```
|
||||
$ curl https://sh.rustup.rs -sSf | sh
|
||||
@ -93,7 +81,7 @@ $ hegemon
|
||||
|
||||
![][10]
|
||||
|
||||
由于 libsensors.so.4 库的问题,我在启动 “Hegemon” 时遇到了一个问题。
|
||||
由于 libsensors.so.4 库的问题,我在启动 Hegemon 时遇到了一个问题。
|
||||
|
||||
```
|
||||
$ hegemon
|
||||
@ -107,9 +95,11 @@ $ sudo ln -s /usr/lib/libsensors.so /usr/lib/libsensors.so.4
|
||||
```
|
||||
|
||||
这是从我的 Lenovo-Y700 笔记本中截取的示例 gif。
|
||||
|
||||
![][11]
|
||||
|
||||
默认它仅显示总体摘要,如果你想查看详细输出,则需要展开每个部分。使用 Hegemon 查看展开内容。
|
||||
默认它仅显示总体摘要,如果你想查看详细输出,则需要展开每个部分。如下是 Hegemon 的展开视图。
|
||||
|
||||
![][12]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@ -119,7 +109,7 @@ via: https://www.2daygeek.com/hegemon-a-modular-system-and-hardware-monitoring-t
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -1,3 +1,4 @@
|
||||
tomjlw is translating
|
||||
Building Slack for the Linux community and adopting snaps
|
||||
======
|
||||
![][1]
|
||||
@ -63,7 +64,7 @@ We are taking it step by step currently – first get people on the snap, and bu
|
||||
via: https://insights.ubuntu.com/2018/02/06/building-slack-for-the-linux-community-and-adopting-snaps/
|
||||
|
||||
作者:[Sarah][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
译者:[译者ID](https://github.com/tomjlw)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: translator: (HankChow)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
@ -1,383 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (qhwdw)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Computer Laboratory – Raspberry Pi: Lesson 3 OK03)
|
||||
[#]: via: (https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok03.html)
|
||||
[#]: author: (Robert Mullins http://www.cl.cam.ac.uk/~rdm34)
|
||||
|
||||
Computer Laboratory – Raspberry Pi: Lesson 3 OK03
|
||||
======
|
||||
|
||||
The OK03 lesson builds on OK02 by teaching how to use functions in assembly to make more reusable and rereadable code. It is assumed you have the code for the [Lesson 2: OK02][1] operating system as a basis.
|
||||
|
||||
### 1 Reusable Code
|
||||
|
||||
So far we've made code for our operating system by typing the things we want to happen in order. This is fine for such tiny programs, but if we wrote the whole system like this, the code would be completely unreadable. Instead we use functions.
|
||||
|
||||
```
|
||||
A function is a piece of code that can be reused to compute a certain kind of answer, or perform a certain action. You may also hear them called procedures, routines or subroutines. Although these are all different, people rarely use the correct term.
|
||||
|
||||
You should already be happy with the concept of a function from mathematics. For example the cosine function applied to a number gives another number between -1 and 1 which is the cosine of the angle. Notationally we write cos(x) to be the cosine function applied to the value x.
|
||||
|
||||
In code, functions can take multiple inputs (including none), give multiple outputs (including none), and may cause side effects. For example a function might create a file on the file system, named after the first input, with length based on the second.
|
||||
```
|
||||
|
||||
![Function as black boxes][2]
|
||||
|
||||
```
|
||||
Functions are said to be 'black boxes'. We put inputs in, and outputs come out, but we don't need to know how they work.
|
||||
```
|
||||
|
||||
In higher level code such as C or C++, functions are part of the language itself. In assembly code, functions are just ideas we have.
|
||||
|
||||
Ideally we want to be able to set our registers to some input values, branch to an address, and expect that at some point the code will branch back to our code having set the registers to output values. This is what a function is in assembly code. The difficulty comes in what system we use for setting the registers. If we just used any system we felt like, each programmer may use a different system, and would find other programmers' work hard to understand. Further, compilers would not be able to work with assembly code as easily, as they would not know how to use the functions. To prevent confusion, a standard called the Application Binary Interface (ABI) was devised for each assembly language which is an agreement on how functions should be run. If everyone makes functions in the same way, then everyone will be able to use each others' functions. I will teach that standard here, and from now on I will code all of my functions to meet the standard.
|
||||
|
||||
The standard says that r0,r1,r2 and r3 will be used as inputs to a function in order. If a function needs no inputs, then it doesn't matter what value it takes. If it needs only one it always goes in r0, if it needs two, the first goes in r0, and the second goes on r1, and so on. The output will always be in r0. If a function has no output, it doesn't matter what value r0 takes.
|
||||
|
||||
Further, it also requires that after a function is run, r4 to r12 must have the same values as they had when the function started. This means that when you call a function, you can be sure the r4 to r12 will not change value, but you cannot be so sure about r0 to r3.
|
||||
|
||||
When a function completes it has to branch back to the code that started it. This means it must know the address of the code that started it. To facilitate this, there is a special register called lr (link register) which always holds the address of the instruction after the one that called this function.
|
||||
|
||||
Table 1.1 ARM ABI register usage
|
||||
| Register | Brief | Preserved | Rules |
|
||||
| -------- | ------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| r0 | Argument and result | No | r0 and r1 are used for passing the first two arguments to functions, and returning the results of functions. If a function does not use them for a return value, they can take any value after a function. |
|
||||
| r1 | Argument and result | No | |
|
||||
| r2 | Argument | No | r2 and r3 are used for passing the second two arguments to functions. There values after a function is called can be anything. |
|
||||
| r3 | Argument | No | |
|
||||
| r4 | General purpose | Yes | r4 to r12 are used for working values, and their value after a function is called must be the same as before. |
|
||||
| r5 | General purpose | Yes | |
|
||||
| r6 | General purpose | Yes | |
|
||||
| r7 | General purpose | Yes | |
|
||||
| r8 | General purpose | Yes | |
|
||||
| r9 | General purpose | Yes | |
|
||||
| r10 | General purpose | Yes | |
|
||||
| r11 | General purpose | Yes | |
|
||||
| r12 | General purpose | Yes | |
|
||||
| lr | Return address | No | lr is the address to branch back to when a function is finished, but this does have to contain the same address after the function has finished. |
|
||||
| sp | Stack pointer | Yes | sp is the stack pointer, described below. Its value must be the same after the function has finished. |
|
||||
|
||||
Often functions need to use more registers than just r0 to r3. But, since r4 to r12 must stay the same after the method has run, they must be saved somewhere. We save them on something called the stack.
|
||||
|
||||
|
||||
![Stack diagram][3]
|
||||
```
|
||||
A stack is a metaphor we use in computing for a method of storing values. Just like in a stack of plates, you can only remove items from the top of a stack, and only add items to the top of the stack.
|
||||
|
||||
The stack is a brilliant idea for storing registers on when functions are running. For example if I have a function which needs to use registers r4 and r5, it could place the current values of those registers on a stack. At the end of the method it could take them back off again. What is most clever is that if my function had to run another function in order to complete and that function needed to save some registers, it could put those on the top of the stack while it ran, and then take them off again at the end. That wouldn't affect the values of r4 and r5 that my method had to save, as they would be added to the top of the stack, and then taken off again.
|
||||
|
||||
The terminology we used to refer to the values put on the stack by a particular method is that methods 'stack frame'. Not every method needs a stack frame, some don't need to store values.
|
||||
```
|
||||
|
||||
Because the stack is so useful, it has been implemented in the ARMv6 instruction set directly. A special register called sp (stack pointer) holds the address of the stack. When items are added to the stack, the sp register updates so that it always holds the address of the first item on the stack. push {r4,r5} would put the values in r4 and r5 onto the top of the stack and pop {r4,r5} would take them back off again (in the correct order).
|
||||
|
||||
### 2 Our First Function
|
||||
|
||||
Now that we have some idea about how functions work, let's try to make one. For a basic first example, we are going to make a function that takes no input, and gives an output of the GPIO address. In the last lesson, we just wrote in this value, but it would be better as a function, since it is something we might need to do often in a real operating system, and we might not always remember the address.
|
||||
|
||||
Copy the following code into a new file called 'gpio.s'. Just make the new file in the 'source' directory with 'main.s'. We're going to put all functions related to the GPIO controller in one file to make them easier to find.
|
||||
|
||||
```
|
||||
.globl GetGpioAddress
|
||||
GetGpioAddress:
|
||||
ldr r0,=0x20200000
|
||||
mov pc,lr
|
||||
```
|
||||
|
||||
```
|
||||
.globl lbl makes the label lbl accessible from other files.
|
||||
|
||||
mov reg1,reg2 copies the value in reg2 into reg1.
|
||||
```
|
||||
|
||||
This is a very simple complete function. The .globl GetGpioAddress command is a message to the assembler to make the label GetGpioAddress accessible to all files. This means that in our main.s file we can branch to the label GetGpioAddress even though it is not defined in that file.
|
||||
|
||||
You should recognise the ldr r0,=0x20200000 command, which stores the GPIO controller address in r0. Since this is a function, we have to give the output in r0, so we are not as free to use any register as we once were.
|
||||
|
||||
mov pc,lr copies the value in lr to pc. As mentioned earlier lr always contains the address of the code that we have to go back to when a method finishes. pc is a special register which always contains the address of the next instruction to be run. A normal branch command just changes the value of this register. By copying the value in lr to pc we just change the next line to be run to be the one we were told to go back to.
|
||||
|
||||
A reasonable question would now be, how would we actually run this code? A special type of branch bl does what we need. It branches to a label like a normal branch, but before it does it updates lr to contain the address of the line after the branch. That means that when the function finishes, the line it will go back to will be the one after the bl command. This makes a function running just look like any other command, it simply runs, does whatever it needs to do, and then carries on to the next line. This is a really useful way of thinking about functions. We treat them as 'black boxes' in that when we use them, we don't need to think about how they work, we just need to know what inputs they need, and what outputs they give.
|
||||
|
||||
For now, don't worry about using the function, we will use it in the next section.
|
||||
|
||||
### 3 A Big Function
|
||||
|
||||
Now we're going to implement a bigger function. Our first job was to enable output on GPIO pin 16. It would be nice if this was a function. We could simply specify a pin and a function as the input, and the function would set the function of that pin to that value. That way, we could use the code to control any GPIO pin, not just the LED.
|
||||
|
||||
Copy the following commands below the GetGpioAddress function in gpio.s.
|
||||
|
||||
```
|
||||
.globl SetGpioFunction
|
||||
SetGpioFunction:
|
||||
cmp r0,#53
|
||||
cmpls r1,#7
|
||||
movhi pc,lr
|
||||
```
|
||||
|
||||
```
|
||||
Suffix ls causes the command to be executed only if the last comparison determined that the first number was less than or the same as the second. Unsigned.
|
||||
|
||||
Suffix hi causes the command to be executed only if the last comparison determined that the first number was higher than the second. Unsigned.
|
||||
```
|
||||
|
||||
One of the first things we should always think about when writing functions is our inputs. What do we do if they are wrong? In this function, we have one input which is a GPIO pin number, and so must be a number between 0 and 53, since there are 54 pins. Each pin has 8 functions, numbered 0 to 7 and so the function code must be too. We could just assume that the inputs will be correct, but this is very dangerous when working with hardware, as incorrect values could cause very bad side effects. Therefore, in this case, we wish to make sure the inputs are in the right ranges.
|
||||
|
||||
To do this we need to check that r0 <= 53 and r1 <= 7. First of all, we can use the comparison we've seen before to compare the value of r0 with 53. The next instruction, cmpls is a normal comparison instruction that will only be run if r0 was lower than or the same as 53. If that was the case, it compares r1 with 7, otherwise the result of the comparison is the same as before. Finally we go back to the code that ran the function if the result of the last comparison was that the register was higher than the number.
|
||||
|
||||
The effect of this is exactly what we want. If r0 was bigger than 53, then the cmpls command doesn't run, but the movhi does. If r0 is <= 53, then the cmpls command does run, and so r1 is compared with 7, and then if it is higher than 7, movhi is run, and the function ends, otherwise movhi does not run, and we know for sure that r0 <= 53 and r1 <= 7.
|
||||
|
||||
There is a subtle difference between the ls (lower or same) and le (less or equal) as well as between hi (higher) and gt (greater) suffixes, but I will cover this later.
|
||||
|
||||
Copy these commands below the above.
|
||||
|
||||
```
|
||||
push {lr}
|
||||
mov r2,r0
|
||||
bl GetGpioAddress
|
||||
```
|
||||
|
||||
```
|
||||
push {reg1,reg2,...} copies the registers in the list reg1,reg2,... onto the top of the stack. Only general purpose registers and lr can be pushed.
|
||||
|
||||
bl lbl sets lr to the address of the next instruction and then branches to the label lbl.
|
||||
```
|
||||
|
||||
These next three commands are focused on calling our first method. The push {lr} command copies the value in lr onto the top of the stack, so that we can retrieve it later. We must do this because when we call GetGpioAddress, we will need to use lr to store the address to come back to in our function.
|
||||
|
||||
If we did not know anything about the GetGpioAddress function, we would have to assume it changes r0,r1,r2 and r3, and would have to move our values to r4 and r5 to keep them the same after it finishes. Fortunately, we do know about GetGpioAddress, and we know it only changes r0 to the address, it doesn't affect r1,r2 or r3. Thus, we only have to move the GPIO pin number out of r0 so it doesn't get overwritten, but we know we can safely move it to r2, as GetGpioAddress doesn't change r2.
|
||||
|
||||
Finally we use the bl instruction to run GetGpioAddress. Normally we use the term 'call' for running a function, and I will from now. As discussed earlier bl calls a function by updating the lr to the next instruction's address, and then branching to the function.
|
||||
|
||||
When a function ends we say it has 'returned'. When the call to GetGpioAddress returns, we now know that r0 contains the GPIO address, r1 contains the function code and r2 contains the GPIO pin number. I mentioned earlier that the GPIO functions are stored in blocks of 10, so first we need to determine which block of ten our pin number is in. This sounds like a job we would use a division for, but divisions are very slow indeed, so it is better for such small numbers to do repeated subtraction.
|
||||
|
||||
Copy the following code below the above.
|
||||
|
||||
```
|
||||
functionLoop$:
|
||||
|
||||
cmp r2,#9
|
||||
subhi r2,#10
|
||||
addhi r0,#4
|
||||
bhi functionLoop$
|
||||
```
|
||||
|
||||
```
|
||||
add reg,#val adds the number val to the contents of the register reg.
|
||||
```
|
||||
|
||||
This simple loop code compares the pin number to 9. If it is higher than 9, it subtracts 10 from the pin number, and adds 4 to the GPIO Controller address then runs the check again.
|
||||
|
||||
The effect of this is that r2 will now contain a number from 0 to 9 which represents the remainder of dividing the pin number by 10. r0 will now contain the address in the GPIO controller of this pin's function settings. This would be the same as GPIO Controller Address + 4 × (GPIO Pin Number ÷ 10).
|
||||
|
||||
Finally, copy the following code below the above.
|
||||
|
||||
```
|
||||
add r2, r2,lsl #1
|
||||
lsl r1,r2
|
||||
str r1,[r0]
|
||||
pop {pc}
|
||||
```
|
||||
|
||||
```
|
||||
Argument shift reg,lsl #val shifts the binary representation of the number in reg left by val before using it in the operation before.
|
||||
|
||||
lsl reg,amt shifts the binary representation of the number in reg left by the number in amt.
|
||||
|
||||
str reg,[dst] is the same as str reg,[dst,#0].
|
||||
|
||||
pop {reg1,reg2,...} copies the values from the top of the stack into the register list reg1,reg2,.... Only general purpose registers and pc can be popped.
|
||||
```
|
||||
|
||||
This code finishes off the method. The first line is actually a multiplication by 3 in disguise. Multiplication is a big and slow instruction in assembly code, as the circuit can take a long time to come up with the answer. It is much faster sometimes to use some instructions which can get the answer quicker. In this case, I know that r2 × 3 is the same as r2 × 2 + r2. It is very easy to multiply a register by 2 as this is conveniently the same as shifting the binary representation of the number left by one place.
|
||||
|
||||
One of the very useful features of the ARMv6 assembly code language is the ability to shift an argument before using it. In this case, I add r2 to the result of shifting the binary representation of r2 to the left by one place. In assembly code, you often use tricks such as this to compute answers more easily, but if you're uncomfortable with this, you could also write something like mov r3,r2; add r2,r3; add r2,r3.
|
||||
|
||||
Now we shift the function value left by a number of places equal to r2. Most instructions such as add and sub have a variant which uses a register rather than a number for the amount. We perform this shift because we want to set the bits that correspond to our pin number, and there are three bits per pin.
|
||||
|
||||
We then store the the computed function value at the address in the GPIO controller. We already worked out the address in the loop, so we don't need to store it at an offset like we did in OK01 and OK02.
|
||||
|
||||
Finally, we can return from this method call. Since we pushed lr onto the stack, if we pop pc, it will copy the value that was in lr at the time we pushed it into pc. This would be the same as having used mov pc,lr and so the function call will return when this line is run.
|
||||
|
||||
The very keen may notice that this function doesn't actually work correctly. Although it sets the function of the GPIO pin to the requested value, it causes all the pins in the same block of 10's functions to go back to 0! This would likely be quite annoying in a system which made heavy use of the GPIO pins. I leave it as a challenge to the interested to fix this function so that it does not overwrite other pins values by ensuring that all bits other than the 3 that must be set remain the same. A solution to this can be found on the downloads page for this lesson. Functions that you may find useful are and which computes the Boolean and function of two registers, mvns which computes the Boolean not and orr which computes the Boolean or.
|
||||
|
||||
### 4 Another Function
|
||||
|
||||
So, we now have a function which takes care of the GPIO pin function setting. We now need to make a function to turn a GPIO pin on or off. Rather than having one function for off and one function for on, it would be handy to have a single function which does either.
|
||||
|
||||
We will make a function called SetGpio which takes a GPIO pin number as its first input in r0, and a value as its second in r1. If the value is 0 we will turn the pin off, and if it is not zero we will turn it on.
|
||||
|
||||
Copy and paste the following code at the end of 'gpio.s'.
|
||||
|
||||
```
|
||||
.globl SetGpio
|
||||
SetGpio:
|
||||
pinNum .req r0
|
||||
pinVal .req r1
|
||||
```
|
||||
|
||||
```
|
||||
alias .req reg sets alias to mean the register reg.
|
||||
```
|
||||
|
||||
Once again we need the .globl command and the label to make the function accessible from other files. This time we're going to use register aliases. Register aliases allow us to use a name other than just r0 or r1 for registers. This may not be so important now, but it will prove invaluable when writing big methods later, and you should try to use aliases from now on. pinNum .req r0 means that pinNum now means r0 when used in instructions.
|
||||
|
||||
Copy and paste the following code after the above.
|
||||
|
||||
```
|
||||
cmp pinNum,#53
|
||||
movhi pc,lr
|
||||
push {lr}
|
||||
mov r2,pinNum
|
||||
.unreq pinNum
|
||||
pinNum .req r2
|
||||
bl GetGpioAddress
|
||||
gpioAddr .req r0
|
||||
```
|
||||
|
||||
```
|
||||
.unreq alias removes the alias alias.
|
||||
```
|
||||
|
||||
Like in SetGpioFunction the first thing we must do is check that we were actually given a valid pin number. We do this in exactly the same way by comparing pinNum (r0) with 53, and returning immediately if it is higher. Once again we wish to call GetGpioAddress, so we have to preserve lr by pushing it onto the stack, and to move pinNum to r2. We then use the .unreq statement to remove our alias from r0. Since the pin number is now stored in r2 we want our alias to reflect this, so we remove the alias from r0 and remake it on r2. You should always .unreq every alias as soon as it is done with, so that you cannot make the mistake of using it further down the code when it no longer exists.
|
||||
|
||||
We then call GetGpioAddress, and we create an alias for r0 to reflect this.
|
||||
|
||||
Copy and paste the following code after the above.
|
||||
|
||||
```
|
||||
pinBank .req r3
|
||||
lsr pinBank,pinNum,#5
|
||||
lsl pinBank,#2
|
||||
add gpioAddr,pinBank
|
||||
.unreq pinBank
|
||||
```
|
||||
|
||||
```
|
||||
lsr dst,src,#val shifts the binary representation of the number in src right by val, but stores the result in dst.
|
||||
```
|
||||
|
||||
The GPIO controller has two sets of 4 bytes each for turning pins on and off. The first set in each case controls the first 32 pins, and the second set controls the remaining 22. In order to determine which set it is in, we need to divide the pin number by 32. Fortunately this is very easy, at is the same as shifting the binary representation of the pin number right by 5 places. Hence, in this case I've named r3 as pinBank and then computed pinNum ÷ 32. Since it is a set of 4 bytes, we then need to multiply the result of this by 4. This is the same as shifting the binary representation left by 2 places, which is the command that follows. You may wonder if we could just shift it right by 3 places, as we went right then left. This won't work however, as some of the answer may have been rounded away when we did ÷ 32 which may not be if we just ÷ 8.
|
||||
|
||||
The result of this is that gpioAddr now contains either 2020000016 if the pin number is 0-31, and 2020000416 if the pin number is 32-53. This means if we add 2810 we get the address for turning the pin on, and if we add 4010 we get the address for turning the pin off. Since we are done with pinBank, I use .unreq immediately afterwards.
|
||||
|
||||
Copy and paste the following code after the above.
|
||||
|
||||
```
|
||||
and pinNum,#31
|
||||
setBit .req r3
|
||||
mov setBit,#1
|
||||
lsl setBit,pinNum
|
||||
.unreq pinNum
|
||||
```
|
||||
|
||||
```
|
||||
and reg,#val computes the Boolean and function of the number in reg with val.
|
||||
```
|
||||
|
||||
This next part of the function is for generating a number with the correct bit set. For the GPIO controller to turn a pin on or off, we give it a number with a bit set in the place of the remainder of that pin's number divided by 32. For example, to set pin 16, we need a number with the 16th bit a 1. To set pin 45 we would need a number with the 13th bit 1 as 45 ÷ 32 = 1 remainder 13.
|
||||
|
||||
The and command computes the remainder we need. How it does this is that the result of an and operation is a number with 1s in all binary digits which had 1s in both of the inputs, and 0s elsewhere. This is a fundamental binary operation, and is very quick. We have given it inputs of pinNum and 3110 = 111112. This means that the answer can only have 1 bits in the last 5 places, and so is definitely between 0 and 31. Specifically it only has 1s where there were 1s in pinNum's last 5 places. This is the same as the remainder of a division by 32. It is no coincidence that 31 = 32 - 1.
|
||||
|
||||
![binary division example][4]
|
||||
|
||||
The rest of this code simply uses this value to shift the number 1 left. This has the effect of creating the binary number we need.
|
||||
|
||||
Copy and paste the following code after the above.
|
||||
|
||||
```
|
||||
teq pinVal,#0
|
||||
.unreq pinVal
|
||||
streq setBit,[gpioAddr,#40]
|
||||
strne setBit,[gpioAddr,#28]
|
||||
.unreq setBit
|
||||
.unreq gpioAddr
|
||||
pop {pc}
|
||||
```
|
||||
|
||||
```
|
||||
teq reg,#val checks if the number in reg is equal to val.
|
||||
```
|
||||
|
||||
This code ends the method. As stated before, we turn the pin off if pinVal is zero, and on otherwise. teq (test equal) is another comparison operation that can only be used to test for equality. It is similar to cmp but it does not work out which number is bigger. If all you wish to do is test if to numbers are the same, you can use teq.
|
||||
|
||||
If pinVal is zero, we store the setBit at 40 away from the GPIO address, which we already know turns the pin off. Otherwise we store it at 28, which turns the pin on. Finally, we return by popping the pc, which sets it to the value that we stored when we pushed the link register.
|
||||
|
||||
### 5 A New Beginning
|
||||
|
||||
Finally, after all that work we have our GPIO functions. We now need to alter 'main.s' to use them. Since 'main.s' is now getting a lot bigger and more complicated, it is better design to split it into two sections. The '.init' we've been using so far is best kept as small as possible. We can change the code to reflect this easily.
|
||||
|
||||
Insert the following just after _start: in main.s:
|
||||
|
||||
```
|
||||
b main
|
||||
|
||||
.section .text
|
||||
main:
|
||||
mov sp,#0x8000
|
||||
```
|
||||
|
||||
The key change we have made here is to introduce the .text section. I have designed the makefile and linker scripts such that code in the .text section (which is the default section) is placed after the .init section which is placed at address 800016. This is the default load address and gives us some space to store the stack. As the stack exists in memory, it has to have an address. The stack grows down memory, so that each new value is at a lower address, thus making the 'top' of the stack, the lowest address.
|
||||
|
||||
```
|
||||
The 'ATAGs' section in the diagram is a place where information about the Raspberry Pi is stored such as how much memory it has, and what its default screen resolution is.
|
||||
```
|
||||
|
||||
![Layout diagram of operating system][5]
|
||||
|
||||
Replace all the code that set the function of the GPIO pin with the following:
|
||||
|
||||
```
|
||||
pinNum .req r0
|
||||
pinFunc .req r1
|
||||
mov pinNum,#16
|
||||
mov pinFunc,#1
|
||||
bl SetGpioFunction
|
||||
.unreq pinNum
|
||||
.unreq pinFunc
|
||||
```
|
||||
|
||||
This code calls SetGpioFunction with the pin number 16 and the pin function code 1. This has the effect of enabling output to the OK LED.
|
||||
|
||||
Replace any code which turns the OK LED on with the following:
|
||||
|
||||
```
|
||||
pinNum .req r0
|
||||
pinVal .req r1
|
||||
mov pinNum,#16
|
||||
mov pinVal,#0
|
||||
bl SetGpio
|
||||
.unreq pinNum
|
||||
.unreq pinVal
|
||||
```
|
||||
|
||||
This code uses SetGpio to turn off GPIO pin 16, thus turning on the OK LED. If we instead used mov pinVal,#1, it would turn the LED off. Replace your old code to turn the LED off with that.
|
||||
|
||||
### 6 Onwards
|
||||
|
||||
Hopefully now, you should be able to test what you have made on the Raspberry Pi. We've done a large amount of code this time, so there is a lot that can go wrong. If it does, head to the troubleshooting page.
|
||||
|
||||
When you get it working, congratulations. Although our operating system does nothing more than it did in [Lesson 2: OK02][1], we've learned a lot about functions and formatting, and we can now code new features much more quickly. It would be very simple now to make an Operating System that alters any GPIO register, which could be used to control hardware!
|
||||
|
||||
In [Lesson 4: OK04][6], we will address our wait function, which is currently imprecise, so that we can gain better control over our LED, and ultimately over all of the GPIO pins.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok03.html
|
||||
|
||||
作者:[Robert Mullins][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://www.cl.cam.ac.uk/~rdm34
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok02.html
|
||||
[2]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/images/functions.png
|
||||
[3]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/images/stack.png
|
||||
[4]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/images/binary3.png
|
||||
[5]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/images/osLayout.png
|
||||
[6]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok04.html
|
@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: translator: (wyxplus)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
@ -1,146 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (HankChow)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Comparing 3 open source databases: PostgreSQL, MariaDB, and SQLite)
|
||||
[#]: via: (https://opensource.com/article/19/1/open-source-databases)
|
||||
[#]: author: (Sam Bocetta https://opensource.com/users/sambocetta)
|
||||
|
||||
Comparing 3 open source databases: PostgreSQL, MariaDB, and SQLite
|
||||
======
|
||||
Find out how to choose the best open source database for your needs.
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/data_container_block.png?itok=S8MbXEYw)
|
||||
|
||||
In the world of modern enterprise technologies, open source software has firmly established itself as one of the biggest forces to reckon with. After all, some of the biggest technology developments have emerged because of the [open source movement][1].
|
||||
|
||||
It's not difficult to see why: even though Linux-based open source network standards may not be as popular as proprietary options, they are the reason smart devices from different manufacturers can communicate with each other. In addition, many argue that open source development produces applications that are superior to their proprietary counterparts. This is one reason why the chances are good that your favorite tools (whether open source or proprietary) were developed using open source databases.
|
||||
|
||||
Like any other category of software, the functionality and features of open source database management systems can differ quite significantly. To put that in plainer terms, [not all open source database management systems are equal][2]. If you are choosing an open source database for your organization, it's important to choose one that is user-friendly, can grow with your organization, and offers more-than-adequate security features.
|
||||
|
||||
With that in mind, we've compiled this overview of open source databases and their respective advantages and disadvantages. Sadly, we had to leave out some of the most used databases. Notably, MongoDB has recently changed its licensing model, so it is no longer truly open source. This decision probably made sense from a business perspective, since MongoDB has become the de facto solution for database hosting [with nearly 27,000 companies][3] using it, but it also means MongoDB can no longer be considered a truly open source system.
|
||||
|
||||
In addition, since it acquired MySQL, Oracle has all but killed the open source nature of that project, which was arguably the go-to open source database for decades. However, this has opened space for other truly open source database solutions to challenge it. Here are three of them to consider.
|
||||
|
||||
### PostgreSQL
|
||||
|
||||
No list of open source databases would be complete without [PostgreSQL][4], which has long been the preferred solution for businesses of all sizes. Oracle's acquisition of MySQL might have made good business sense at the time, but the rise of cloud storage has meant that the database [has gradually fallen out of favor with developers][5].
|
||||
|
||||
Although PostgreSQL has been around for a while, the relative [decline of MySQL][6] has made it a serious contender for the title of most used open source database. Since it works very similarly to MySQL, developers who prefer open source software are converting in droves.
|
||||
|
||||
#### Advantages
|
||||
|
||||
* By far, PostgreSQL's most mentioned advantage is the efficiency of its central algorithm, which means it outperforms many databases that are advertised as more advanced. This is especially useful if you are working with large datasets, for which I/O processes can otherwise become a bottleneck.
|
||||
|
||||
* It is also one of the most flexible open source databases around; you can write functions in a wide range of server-side languages: Python, Perl, Java, Ruby, C, and R.
|
||||
|
||||
* As one of the most commonly used open source databases, PostgreSQL's community support is some of the best around.
|
||||
|
||||
|
||||
|
||||
|
||||
#### Disadvantages
|
||||
|
||||
* PostgreSQL's efficiency with large datasets is well known, but there are quicker tools available for smaller databases.
|
||||
|
||||
* While its community support is very good, PostgreSQL's core documentation could be improved.
|
||||
|
||||
* If you are used to advanced tools like parallelization and clustering, be aware that these require third-party plugins in PostgreSQL. There are plans to gradually add these features to the main release, but it will likely be a few years before they are offered as standard.
|
||||
|
||||
|
||||
|
||||
|
||||
### MariaDB
|
||||
|
||||
[MariaDB][7] is a truly open source distribution of MySQL (released under the [GNU GPLv2][8]). It was [created after Oracle's acquisition][9] of MySQL, when some of MySQL's core developers were concerned that Oracle would undermine its open source philosophy.
|
||||
|
||||
MariaDB was developed to be as compatible with MySQL as possible while replacing several key components. It uses a storage engine, Aria, that functions as both a transactional and non-transactional engine. [Some even speculated][10] Aria would become the standard engine for MySQL in future releases, before MariaDB diverged.
|
||||
|
||||
#### Advantages
|
||||
|
||||
* Many users choose MariaDB over MySQL due to MariaDB's [frequent security releases][11]. While this does not necessarily mean MariaDB is more secure, it does indicate the development community takes security seriously.
|
||||
|
||||
* Others say MariaDB's major advantages are that it will almost definitely remain open source and highly compatible with MySQL. This means migrating from one system to the other is extremely fast.
|
||||
|
||||
* Because of this compatibility, MariaDB also plays well with many other languages that are commonly used with MySQL. This means less time is spent learning and debugging code.
|
||||
|
||||
* You can [install and run][12] WordPress with MariaDB instead of MySQL for better performance and a richer feature set. WordPress is the [most popular CMS by marketshare][13]—powering nearly half the internet—and has an active open source developer community. Third-party themes and plugins work as intended when WordPress is installed with MariaDB.
|
||||
|
||||
|
||||
|
||||
|
||||
#### Disadvantages
|
||||
|
||||
* MariaDB is somewhat liable to bloating. Its central IDX log file, in particular, tends to become very large after protracted use, ultimately slowing performance.
|
||||
|
||||
* Caching is another area where MariaDB could use work—it is not as fast as it could be, which can be frustrating.
|
||||
|
||||
* Despite all the initial promises, MariaDB is no longer completely compatible with MySQL. If you are migrating from MySQL, you will have some re-coding to do.
|
||||
|
||||
|
||||
|
||||
|
||||
### SQLite
|
||||
|
||||
[SQLite][14] is arguably the most implemented database engine in the world, thanks to its adoption by many popular web browsers, operating systems, and mobile phones. Originally developed as a lightweight fork of MySQL, unlike many other databases it is not a client-server engine; rather, the full software is embedded into each implementation.
|
||||
|
||||
This creates SQLite's major advantage: on embedded or distributed systems, each machine carries an entire implementation of the database. This can greatly speed up the performance of databases because it reduces the need for inter-system calls.
|
||||
|
||||
#### Advantages
|
||||
|
||||
* If you are looking to build and implement a small database, SQLite is [arguably the best way to go][15]. It is extremely small, so it can be implemented across a wide range of embedded systems without time-consuming workarounds.
|
||||
|
||||
* Its small size makes the system extremely fast. While some more advanced databases use complex ways of producing efficiency savings, SQLite takes a much simpler approach: By reducing the size of your database and its associated processing software, there is simply less data to work with.
|
||||
|
||||
* Its widespread adoption also means SQLite is probably the most compatible database out there. This is particularly important if you need or plan to integrate your system with smartphones: the system has been native on iOS for as long as there have been third-party apps and works flawlessly in a wide range of environments.
|
||||
|
||||
|
||||
|
||||
|
||||
#### Disadvantages
|
||||
|
||||
* SQLite's tiny size means it lacks some features found in larger databases. It lacks built-in data encryption, for example, something that has become standard to prevent the [most common online hacker attacks][16].
|
||||
|
||||
* While the wide adoption and publicly available code makes SQLite easy to work with, it also increases its attack surface area. This is its most commonly cited disadvantage. New critical vulnerabilities are frequently discovered in SQLite, such as the recent remote attack vector called [Magellan][17].
|
||||
|
||||
* Although SQLite's single-file approach creates speed advantages, there is no easy way to implement a multi-user environment using the system.
|
||||
|
||||
|
||||
|
||||
|
||||
### Which open source database is best?
|
||||
|
||||
Ultimately, your choice of open source database will depend on your business needs and particularly on the size of your system. For small databases or those with limited use, go for a lightweight solution: not only will it speed up implementation but a less-complex system means you will spend less time debugging.
|
||||
|
||||
For larger systems, especially in growing businesses, invest the time to implement a more complex database like PostgreSQL. This will save you time—eventually—by removing the need to re-code your databases as your business grows.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/1/open-source-databases
|
||||
|
||||
作者:[Sam Bocetta][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/sambocetta
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/article/18/2/pivotal-moments-history-open-source
|
||||
[2]: https://blog.capterra.com/free-database-software/
|
||||
[3]: https://idatalabs.com/tech/products/mongodb
|
||||
[4]: https://www.postgresql.org/
|
||||
[5]: https://www.theregister.co.uk/2018/05/31/rise_of_the_open_source_data_strategies/
|
||||
[6]: https://www.itworld.com/article/2721995/big-data/signs-of-mysql-decline-on-horizon.html
|
||||
[7]: https://mariadb.org/
|
||||
[8]: https://github.com/MariaDB/server/blob/10.4/COPYING
|
||||
[9]: https://mariadb.com/about-us/
|
||||
[10]: http://kb.askmonty.org/en/aria-faq
|
||||
[11]: https://mariadb.org/tag/security/
|
||||
[12]: https://mariadb.com/resources/blog/how-to-install-and-run-wordpress-with-mariadb/
|
||||
[13]: https://websitesetup.org/popular-cms/
|
||||
[14]: https://www.sqlite.org/index.html
|
||||
[15]: https://www.sqlite.org/aff_short.html
|
||||
[16]: https://hostingcanada.org/most-common-website-vulnerabilities/
|
||||
[17]: https://www.securitynewspaper.com/2018/12/18/critical-vulnerability-in-sqlite-you-should-update-now/
|
@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
@ -1,90 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Get started with Roland, a random selection tool for the command line)
|
||||
[#]: via: (https://opensource.com/article/19/1/productivity-tools-roland)
|
||||
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney (Kevin Sonney))
|
||||
|
||||
Get started with Roland, a random selection tool for the command line
|
||||
======
|
||||
|
||||
Get help making hard choices with Roland, the seventh in our series on open source tools that will make you more productive in 2019.
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/dice_tabletop_board_gaming_game.jpg?itok=y93eW7HN)
|
||||
|
||||
There seems to be a mad rush at the beginning of every year to find ways to be more productive. New Year's resolutions, the itch to start the year off right, and of course, an "out with the old, in with the new" attitude all contribute to this. And the usual round of recommendations is heavily biased towards closed source and proprietary software. It doesn't have to be that way.
|
||||
|
||||
Here's the seventh of my picks for 19 new (or new-to-you) open source tools to help you be more productive in 2019.
|
||||
|
||||
### Roland
|
||||
|
||||
By the time the workday has ended, often the only thing I want to think about is hitting the couch and playing the video game of the week. But even though my professional obligations stop at the end of the workday, I still have to manage my household. Laundry, pet care, making sure my teenager has what he needs, and most important: deciding what to make for dinner.
|
||||
|
||||
Like many people, I often suffer from [decision fatigue][1], and I make less-than-healthy choices for dinner based on speed, ease of preparation, and (quite frankly) whatever causes me the least stress.
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/roland-1.png)
|
||||
|
||||
[Roland][2] makes planning my meals much easier. Roland is a Perl application designed for tabletop role-playing games. It picks randomly from a list of items, such as monsters and hirelings. In essence, Roland does the same thing at the command line that a game master does when rolling physical dice to look up things in a table from the Game Master's Big Book of Bad Things to Do to Players.
|
||||
|
||||
With minor modifications, Roland can do so much more. For example, just by adding a table, I can enable Roland to help me choose what to cook for dinner.
|
||||
|
||||
The first step is installing Roland and all its dependencies.
|
||||
|
||||
```
|
||||
git clone git@github.com:rjbs/Roland.git
|
||||
cpan install Getopt::Long::Descriptive Moose \
|
||||
namespace::autoclean List:AllUtils Games::Dice \
|
||||
Sort::ByExample Data::Bucketeer Text::Autoformat \
|
||||
YAML::XS
|
||||
cd oland
|
||||
```
|
||||
|
||||
Next, I create a YAML document named **dinner** and enter all our meal options.
|
||||
|
||||
```
|
||||
type: list
|
||||
pick: 1
|
||||
items:
|
||||
- "frozen pizza"
|
||||
- "chipotle black beans"
|
||||
- "huevos rancheros"
|
||||
- "nachos"
|
||||
- "pork roast"
|
||||
- "15 bean soup"
|
||||
- "roast chicken"
|
||||
- "pot roast"
|
||||
- "grilled cheese sandwiches"
|
||||
```
|
||||
|
||||
Running the command **bin/roland dinner** will read the file and pick one of the options.
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/roland-2.png)
|
||||
|
||||
I like to plan for the week ahead so I can shop for all my ingredients in advance. The **pick** command determines how many items from the list to chose, and right now, the **pick** option is set to 1. If I want to plan a full week's dinner menu, I can just change **pick: 1** to **pick: 7** and it will give me a week's worth of dinners. You can also use the **-m** command line option to manually enter the choices.
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/roland-3.png)
|
||||
|
||||
You can also do fun things with Roland, like adding a file named **8ball** with some classic phrases.
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/roland-4.png)
|
||||
|
||||
You can create all kinds of files to help with common decisions that seem so stressful after a long day of work. And even if you don't use it for that, you can still use it to decide which devious trap to set up for tonight's game.
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/1/productivity-tools-roland
|
||||
|
||||
作者:[Kevin Sonney][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ksonney (Kevin Sonney)
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://en.wikipedia.org/wiki/Decision_fatigue
|
||||
[2]: https://github.com/rjbs/Roland
|
@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: translator: (dianbanjiu )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
@ -0,0 +1,383 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (qhwdw)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Computer Laboratory – Raspberry Pi: Lesson 3 OK03)
|
||||
[#]: via: (https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok03.html)
|
||||
[#]: author: (Robert Mullins http://www.cl.cam.ac.uk/~rdm34)
|
||||
|
||||
计算机实验室 – 树莓派:课程 3 OK03
|
||||
======
|
||||
|
||||
OK03 课程基于 OK02 课程来构建,它教你在汇编中如何使用函数让代码可复用和可读性更好。假设你已经有了 [课程 2:OK02][1] 的操作系统,我们将以它为基础。
|
||||
|
||||
### 1、可复用的代码
|
||||
|
||||
到目前为止,我们所写的代码都是以我们希望发生的事为顺序来输入的。对于非常小的程序来说,这种做法很好,但是如果我们以这种方式去写一个完整的系统,所写的代码可读性将非常差。我们应该去使用函数。
|
||||
|
||||
```
|
||||
一个函数是一段可复用的代码片断,可以用于去计算某些答案,或执行某些动作。你也可以称它们为程序、整套动作或子动作。虽然它们都是不同的,但人们几乎都没有正确地使用这个术语。
|
||||
|
||||
你应该在数学上遇到了函数的概念。例如,余弦函数应用于一个给定的数时,会得到介于 -1 到 1 之间的另一个数,这个数就是角的余弦。一般我们写成 cos(x) 来表示应用到一个值 x 上的余弦函数。
|
||||
|
||||
在代码中,函数可以有多个输入(也可以没有输入),然后函数给出多个输出(也可以没有输出),并可能导致负面效应。例如一个函数可以在一个文件系统上创建一个文件,第一个输入是它的名字,第二个输入是文件的长度。
|
||||
```
|
||||
|
||||
![Function as black boxes][2]
|
||||
|
||||
```
|
||||
函数可以认为是一个“黑匣子”。我们给它输入,然后它给我们输出,而我们不需要知道它是如何工作的。
|
||||
```
|
||||
|
||||
在像 C 或 C++ 这样的高级代码中,函数是语言的组成部分。在汇编代码中,函数只是我们的创意。
|
||||
|
||||
理想情况下,我们希望能够在我们的寄存器中设置一些值,分支地址,以及预期在某个时刻,分支将返回,并通过代码来设置输出值到寄存器。这就是我们所设想的汇编代码中的函数。困难之处在于我们用什么样的方式去设置寄存器。如果我们只是使用平时所接触到的任意方法去设置寄存器,每个程序可能使用不同的方法,这样你将会发现你很难理解其他程序员所写的代码。另外,编译器也不能像使用汇编代码那样轻松地工作,因为它们压根不知道如何去使用函数。为避免这种困惑,为每个汇编语言设计了一个称为应用程序二进制接口(ABI)的标准,由它来规范函数如何去运行。如果每个人都使用相同的方法去写函数,这样每个人都可以去使用其他人写的函数。在这里,我将教你们这个标准,而从现在开始,我所写的函数将全部遵循这个标准。
|
||||
|
||||
标准规定,寄存器 `r0`、`r1`、`r2` 和 `r3` 将被依此用于函数的输入。如果函数没有输入,那么它有没有值就无关紧要了。如果只需要一个输入,那么它应该总是在寄存器 `r0` 中,如果它需要两个输入,那么第一个输入在寄存器 `r0` 中,而第二个输入在寄存器 `r1` 中,依此类推。输出值也总是在寄存器 `r0` 中。如果函数没有输出,那么 `ro` 中是什么值就不重要了。
|
||||
|
||||
另外,标准要求当一个函数运行之后,寄存器 `r4` 到 `r12` 的值必须与函数启动时的值相同。这意味着当你调用一个函数时,你可以确保寄存器 `r4` 到 `r12` 中的值没有发生变化,但是不能确保寄存器 `r0` 到 `r3` 中的值也没有发生变化。
|
||||
|
||||
当一个函数运行完成后,它将返回到启动它的代码分支处。这意味着它必须知道启动它的代码的地址。为此,需要一个称为`lr`(链接寄存器)的专用寄存器,它总是在保存调用这个函数的指令的地址。
|
||||
|
||||
表 1.1 ARM ABI 寄存器用法
|
||||
| 寄存器 | 简介 | 保留 | 规则 |
|
||||
| ------ | ---------- | ---- | ------------------------------------------------------------ |
|
||||
| r0 | 参数和结果 | 否 | r0 和 r1 用于给函数传递前两个参数,以及函数返回的结果。如果函数返回值不使用它,那么在函数运行之后,它们可以携带任何值。 |
|
||||
| r1 | 参数和结果 | 否 | |
|
||||
| r2 | 参数 | 否 | r2 和 r3 用去给函数传递后两个参数。在函数运行之后,它们可以携带任何值。 |
|
||||
| r3 | 参数 | 否 | |
|
||||
| r4 | 通用寄存器 | 是 | r4 到 r12 用于保存函数运行过程中的值,它们的值在函数调用之后必须与调用之前相同。 |
|
||||
| r5 | 通用寄存器 | 是 | |
|
||||
| r6 | 通用寄存器 | 是 | |
|
||||
| r7 | 通用寄存器 | 是 | |
|
||||
| r8 | 通用寄存器 | 是 | |
|
||||
| r9 | 通用寄存器 | 是 | |
|
||||
| r10 | 通用寄存器 | 是 | |
|
||||
| r11 | 通用寄存器 | 是 | |
|
||||
| r12 | 通用寄存器 | 是 | |
|
||||
| lr | 返回地址 | 否 | 当函数运行完成后,lr 中保存了分支的返回地址,但在函数运行完成之后,它将保存相同的地址。 |
|
||||
| sp | 栈指针 | 是 | sp 是栈指针,在下面有详细描述。它的值在函数运行完成后,必须是相同的。 |
|
||||
|
||||
通常,函数需要使用很多的寄存器,而不仅是 `r0` 到 `r3`。但是,由于 `r4` 到 `r12` 必须在系列动作完成之后值必须保持相同,因此它们需要被保存到某个地方。我们将它们保存到称为栈的地方。
|
||||
|
||||
|
||||
![Stack diagram][3]
|
||||
```
|
||||
一个栈就是我们在计算中用来保存值的一个很形象的方法。就像是摞起来的一堆盘子,你可以从上到下来移除它们,而添加它们时,你只能从下到上来添加。
|
||||
|
||||
在函数运行时,使用栈来保存寄存器值是个非常好的创意。例如,如果我有一个函数需要去使用寄存器 r4 和 r5,它将在一个栈上存放这些寄存器的值。最后用这种方式,它可以再次将它拿回来。更高明的是,如果为完成运行我的函数,需要去运行另一个函数,并且那个函数需要保存一些寄存器,在它运行时,它将把寄存器保存在栈顶上,然后在结束后再将它们拿走。而这并不会影响我保存在寄存器 r4 和 r5 中的值,因为它们是在栈顶上添加的,拿走时也是从栈顶上取出的。
|
||||
|
||||
我们用专用的术语“栈帧”来表示使用特定的方法放到栈上的值。不是每种方法都使用一个栈帧,有些是不需要存储值的。
|
||||
```
|
||||
|
||||
因为栈非常有用,它被直接实现在 ARMv6 的指令集中。一个名为 `sp` (栈指针)的专用寄存器用来保存栈的地址。当需要有东西添加到栈上时,`sp` 寄存器被更新,这样就总是保证它保存的是栈上前一个东西的地址。`push {r4,r5}` 将推送 `r4` 和 `r5` 中的值到栈顶上,而 `pop {r4,r5}` 将(以正确的次序)取回它们。
|
||||
|
||||
### 2、我们的第一个函数
|
||||
|
||||
现在,关于函数的原理我们已经有了一些概念,我们尝试来写一个函数。由于是我们的第一个很基础的例子,我们写一个没有输入的函数,它将输出 GPIO 的地址。在上一节课程中,我们就是写到这个值上,但将它写成函数更好,因为我们在真实的操作系统中经常需要用到它,而我们不可能总是能够记住这个地址。
|
||||
|
||||
复制下列代码到一个名为 `gpio.s` 的新文件中。就像在`source` 目录中使用的 `main.s` 一样。我们将把与 GPIO 控制器相关的所有函数放到一个文件中,这样更好查找。
|
||||
|
||||
```assembly
|
||||
.globl GetGpioAddress
|
||||
GetGpioAddress:
|
||||
ldr r0,=0x20200000
|
||||
mov pc,lr
|
||||
```
|
||||
|
||||
```assembly
|
||||
.globl lbl 使标签 lbl 从其它文件中可访问。
|
||||
|
||||
mov reg1,reg2 复制 reg2 中的值到 reg1 中。
|
||||
```
|
||||
|
||||
这就是一个很简单的完整的函数。`.globl GetGpioAddress` 命令是通知汇编器,让标签 `GetGpioAddress` 在所有文件中全局可访问。这意味着在我们的 `main.s` 文件中,我们可以使用分支指令到标签 `GetGpioAddress` 上,即便这个标签在那个文件中没有定义也没有问题。
|
||||
|
||||
你应该认得 `ldr r0,=0x20200000` 命令,它将 GPIO 控制器地址保存到 r0 中。由于这是一个函数,我们要让它输出寄存器 `r0` 中的值,因此我们不能再像以前那样随意使用任意一个寄存器了。
|
||||
|
||||
`mov pc,lr` 将寄存器 `lr` 中的值复制到 `pc` 中。正如前面所提到的,寄存器 `lr` 总是保存着方法完成后我们要返回的代码的地址。`pc` 是一个专用寄存器,它总是包含下一个要运行的指令的地址。一个普通的分支命令只需要改变这个寄存器的值即可。通过将 `lr` 中的值复制到 `pc` 中,我们就可以将运行的下一行命令改变成我们将要返回的那一行。
|
||||
|
||||
现在这里存在一个合乎常理的问题,那就是我们如何去运行这个代码?我们将需要一个特殊的分支类型 `bl`。它像一个普通的分支一样切换到一个标签,但它在切换之前先更新 `lr` 的值去包含一个分支之后的行的地址。这意味着当函数完成后,将返回到 `bl` 命令之后的那一行上。这就确保了函数能够像任何其它命令那样运行,它简单地运行,做任何需要做的事情,然后推进到下一行。这是函数最有用的方法。当我们使用它时,就将它们按“黑匣子”处理即可,不需要了解它是如何运行的,我们只了解它需要什么输入,以及它给我们什么输出即可。
|
||||
|
||||
到现在为止,我们已经明白了函数如何使用,下一节我们将使用它。
|
||||
|
||||
### 3、一个大的函数
|
||||
|
||||
现在,我们继续去实现一个更大的函数。我们的第一项任务是启用 GPIO 第 16 号针脚的输出。如果它是一个函数那就太好了。我们能够简单地指定针脚号作为函数的输入,然后函数将设置那个针脚的值。那样,我们就可以使用这个代码去控制任意的 GPIO 针脚,而不只是 LED 了。
|
||||
|
||||
将下列的命令复制到 `gpio.s` 文件中的 GetGpioAddress 函数中。
|
||||
|
||||
```assembly
|
||||
.globl SetGpioFunction
|
||||
SetGpioFunction:
|
||||
cmp r0,#53
|
||||
cmpls r1,#7
|
||||
movhi pc,lr
|
||||
```
|
||||
|
||||
```
|
||||
带后缀 ls 的命令只有在上一个比较命令的结果是第一个数字小于或等于第二个数字的情况下才会被运行。它是无符号的。
|
||||
|
||||
带后缀 hi 的命令只有上一个比较命令的结果是第一个数字大于第二个数字的情况下才会被运行。它是无符号的。
|
||||
```
|
||||
|
||||
在写一个函数时,我们首先要考虑的事情就是输入,如果输入错了我们怎么办?在这个函数中,我们有一个输入是 GPIO 针脚号,而它必须是介于 0 到 53 之间的数字,因为只有 54 个针脚。每个针脚有 8 个函数,被编号为 0 到 7,因此函数代码也必须是 0 到 7 之间的数字。我们可能假设输入应该是正确的,但是当在硬件上使用时,这种做法是非常危险的,因为不正确的值将导致极大的负面效应。所以,在这个案例中,我们希望确保输入值在正确的范围。
|
||||
|
||||
为了确保输入值在正确的范围,我们需要做一个检查,即 r0 <= 53 并且 r1 <= 7。首先我们使用前面看到的比较命令去将 `r0` 的值与 53 做比较。下一个指令 `cmpls` 仅在前一个比较指令结果是小于等于 53 时才会去运行。如果一切正常,它将寄存器 `r1` 的值与 7 进行比较,其它的部分都和前面的是一样的。如果最后的比较结果是寄存器值大于那个数字,最后我们将返回到运行函数的代码处。
|
||||
|
||||
这正是我们所希望的效果。如果 r0 中的值大于 53,那么 `cmpls` 命令将不会去运行,但是 `movhi` 会运行。如果 r0 中的值 <= 53,那么 `cmpls` 命令会运行,将 r1 中的值与 7 进行比较,如果它大于 7,`movhi` 会运行,函数结束,否则 `movhi` 不会运行,这样我们就确定 r0 <= 53 并且 r1 <= 7。
|
||||
|
||||
`ls`(低于或相同)与 `le`(小于或等于)有一些细微的差别,以及后缀 `hi` (高于)和 `gt` (大于)也一样有一些细微差别,我们在后面将会讲到。
|
||||
|
||||
将这些命令复制到上面的代码的下面位置。
|
||||
|
||||
```assembly
|
||||
push {lr}
|
||||
mov r2,r0
|
||||
bl GetGpioAddress
|
||||
```
|
||||
|
||||
```assembly
|
||||
push {reg1,reg2,...} 复制列出的寄存器 reg1、reg2、... 到栈顶。该命令仅能用于通用寄存器和 lr 寄存器。
|
||||
|
||||
bl lbl sets lr 设置下一个指令的地址并切换到标签 lbl。
|
||||
```
|
||||
|
||||
这三个命令用于调用我们第一个方法。`push {lr}` 命令复制 `lr` 中的值到栈顶,这样我们在后面可以检索到它。当我们调用 GetGpioAddress 时必须要这样做,我们将需要使用 `lr` 去保存我们函数的返回地址。
|
||||
|
||||
如果我们对 `GetGpioAddress` 函数一无所知,我们应该假设它改变了 `r0`、`r1`、`r2` 和 `r3` 的值 ,我们将移动我们的值到 r4 和 r5 中,以保持在它完成之后寄存器的值相同。幸运的是,我们知道 `GetGpioAddress` 做了什么,并且我们也知道它仅改变了 `r0` 到地址,它并没有影响 `r1`、`r2` 或 `r3` 的值。因此,我们仅去将 GPIO 针脚号从 `r0` 中移出,这样它就不会被覆盖掉,但我们知道,可以将它安全地移到 `r2` 中,因为 `GetGpioAddress` 并不去改变 `r2`。
|
||||
|
||||
最后我们使用 `bl` 指令去运行 `GetGpioAddress`。通常,运行一个函数,我们使用一个术语叫“调用”,从现在开始我们将一直使用这个术语。正如我们前面讨论过的,`bl` 通过更新 `lr` 中的下一个指令的地址,去调用一个函数,接着切换到函数。
|
||||
|
||||
当一个函数结束时,我们称为“返回”。当一个 `GetGpioAddress` 调用返回时,我们已经知道了 `r0` 中包含了 GPIO 的地址,`r1` 中包含了函数代码,而 `r2` 中包含了 GPIO 针脚号。我前面说过,GPIO 函数每 10 个保存在一个块中,因此首先我们需要去判断我们的针脚在哪个块中。这似乎听起来像是要使用一个除法,但是除法做起来非常慢,因此对于这些比较小的数来说,不停地做减法要比除法更好。
|
||||
|
||||
将下面的代码复制到上面的代码中最下面的位置。
|
||||
|
||||
```assembly
|
||||
functionLoop$:
|
||||
|
||||
cmp r2,#9
|
||||
subhi r2,#10
|
||||
addhi r0,#4
|
||||
bhi functionLoop$
|
||||
```
|
||||
|
||||
```assembly
|
||||
add reg,#val 将数字 val 加到寄存器 reg 的内容上。
|
||||
```
|
||||
|
||||
这个简单的循环代码将针脚号与 9 进行比较。如果它大于 9,它将从针脚号上减去 10,并且将 GPIO 控制器地址加上 4,然后再次运行检查。
|
||||
|
||||
这样做的效果就是,现在,`r2` 中将包含一个 0 到 9 之间的数字,它是针脚号除以 9 的余数。`r0` 将包含这个针脚的函数所设置的 GPIO 控制器的地址。它就如同是 “GPIO 控制器地址 + 4 × (GPIO Pin Number ÷ 10)”。
|
||||
|
||||
最后,将下面的代码复制到上面的代码中最下面的位置。
|
||||
|
||||
```assembly
|
||||
add r2, r2,lsl #1
|
||||
lsl r1,r2
|
||||
str r1,[r0]
|
||||
pop {pc}
|
||||
```
|
||||
|
||||
```assembly
|
||||
移位参数 reg,lsl #val 表示将寄存器 reg 中二进制表示的数逻辑左移 val 位之后的结果作为与前面运算的操作数。
|
||||
|
||||
lsl reg,amt 将寄存器 reg 中的二进制数逻辑左移 amt 中的位数。
|
||||
|
||||
str reg,[dst] 与 str reg,[dst,#0] 相同。
|
||||
|
||||
pop {reg1,reg2,...} 从栈顶复制值到寄存器列表 reg1、reg2、.... 仅有通用寄存器与 pc 可以这样弹出值。
|
||||
```
|
||||
|
||||
这个代码完成了这个方法。第一行其实是乘以 3 的变体。乘法在汇编中是一个大而慢的指令,因为电路需要很长时间才能给出答案。有时使用一些能够很快给出答案的指令会让它变得更快。在本案例中,我们知道 r2 × 3 与 r2 × 2 + r2 是相同的。一个寄存器乘以 2 是非常容易的,因为它可以通过将二进制表示的数左移一位来很方便地实现。
|
||||
|
||||
ARMv6 汇编语言其中一个非常有用的特性就是,在使用它之前可以先移动参数所表示的位数。在本案例中,我将 `r2` 加上 `r2` 中二进制表示的数左移一位的结果。在汇编代码中,你可以经常使用这个技巧去更快更容易地计算出答案,但如果你觉得这个技巧使用起来不方便,你也可以写成类似 `mov r3,r2`; `add r2,r3`; `add r2,r3` 这样的代码。
|
||||
|
||||
现在,我们可以将一个函数的值左移 `r2` 中所表示的位数。大多数对数量的指令(比如加法和减法)都有一个可以使用寄存器而不是数字的变体。我们执行这个移位是因为我们想去设置表示针脚号的位,并且每个针脚有三个位。
|
||||
|
||||
然后,我们将函数计算后的值保存到 GPIO 控制器的地址上。我们在循环中已经算出了那个地址,因此我们不需要像 OK01 和 OK02 中那样在一个偏移量上保存它。
|
||||
|
||||
最后,我们从这个方法调用中返回。由于我们将 `lr` 推送到了栈上,因此我们 `pop pc`,它将复制 `lr` 中的值并将它推送到 `pc` 中。这个操作类似于 `mov pc,lr`,因此函数调用将返回到运行它的那一行上。
|
||||
|
||||
敏锐的人可能会注意到,这个函数其实并不能正确工作。虽然它将 GPIO 针脚函数设置为所要求的值,但它会导致在同一个块中的 10 个函数的所有针脚都归 0!在一个大量使用 GPIO 针脚的系统中,这将是一个很恼人的问题。我将这个问题留给有兴趣去修复这个函数的人,以确保只设置相关的 3 个位而不去覆写其它位,其它的所有位都保持不变。关于这个问题的解决方案可以在本课程的下载页面上找到。你可能会发现非常有用的几个函数是 `and`,它是计算两个寄存器的布尔与函数,`mvns` 是计算布尔非函数,而 `orr` 是计算布尔或函数。
|
||||
|
||||
### 4、另一个函数
|
||||
|
||||
现在,我们已经有了能够设置 GPIO 针脚的函数。我们还需要写一个能够打开或关闭 GPIO 针脚的函数。我们不需要写一个打开的函数和一个关闭的函数,只需要一个函数就可以做这两件事情。
|
||||
|
||||
我们将写一个名为 `SetGpio` 的函数,它用 `r0` 中的值作为第一个输入,`r1` 中的值作为第二个输入。如果值为 `0`,我们将关闭针脚,而如果为非零则打开针脚。
|
||||
|
||||
将下列的代码复制粘贴到 `gpio.s` 文件的结尾部分。
|
||||
|
||||
```assembly
|
||||
.globl SetGpio
|
||||
SetGpio:
|
||||
pinNum .req r0
|
||||
pinVal .req r1
|
||||
```
|
||||
|
||||
```assembly
|
||||
alias .req reg 设置寄存器 reg 的别名为 alias。
|
||||
```
|
||||
|
||||
我们再次需要 `.globl` 命令,标记它为其它文件可访问的全局函数。这次我们将使用寄存器别名。寄存器别名允许我们为寄存器使用名字而不仅是 `r0` 或 `r1`。到目前为止,寄存器别名还不是很重要,但随着我们后面写的方法越来越大,它将被证明非常有用,现在开始我们将尝试使用别名。当在指令中使用到 `pinNum .req r0` 时,它的意思是 `pinNum` 表示 `r0`。
|
||||
|
||||
将下面的代码复制粘贴到上述的代码下面位置。
|
||||
|
||||
```assembly
|
||||
cmp pinNum,#53
|
||||
movhi pc,lr
|
||||
push {lr}
|
||||
mov r2,pinNum
|
||||
.unreq pinNum
|
||||
pinNum .req r2
|
||||
bl GetGpioAddress
|
||||
gpioAddr .req r0
|
||||
```
|
||||
|
||||
```assembly
|
||||
.unreq alias 删除别名 alias。
|
||||
```
|
||||
|
||||
就像在函数 `SetGpio` 中所做的第一件事情是检查给定的针脚号是否有效一样。我们需要同样的方式去将 `pinNum (r0)` 与 53 进行比较,如果它大于 53 将立即返回。一旦我们再次调用 `GetGpioAddress`,我们就需要将 `lr`推送到栈上来保护它,将将 `pinNum` 移动到 `r2` 中。然后我们使用 `.unreq` 语句来删除我们给 `r0` 定义的别名。因为针脚号现在保存在寄存器 `r2` 中,我们希望通过别名能够映射到它,因此我们重新定义到 `r2` 的别名。你应该每次在别名使用结束后,立即删除它,这样当它不再存在时,你就不会在后面的代码中因它而产生错误。
|
||||
|
||||
然后,我们调用了 `GetGpioAddress`,并且我们创建了一个指向 `r0`的别名。
|
||||
|
||||
将下面的代码复制粘贴到上述代码的后面位置。
|
||||
|
||||
```assembly
|
||||
pinBank .req r3
|
||||
lsr pinBank,pinNum,#5a
|
||||
lsl pinBank,#2
|
||||
add gpioAddr,pinBank
|
||||
.unreq pinBank
|
||||
```
|
||||
|
||||
```assembly
|
||||
lsr dst,src,#val 将 src 中二进制表示的数右移 val 位,并将结果保存到 dst。
|
||||
```
|
||||
|
||||
对于打开和关闭 GPIO 针脚,每个针脚在 GPIO 控制器上有两个 4 字节组。在每个场景下,第一个 4 字节组控制前 32 个针脚,而第二个 4 字节组控制剩下的 22 个针脚。为了判断我们要设置的针脚在哪个 4 字节组中,我们需要将针脚号除以 32。幸运的是,这很容易,因为它等价于将二进制表示的针脚号右移 5 位。因此,在本案例中,我们将 `r3` 命名为 `pinBank`,然后计算 `pinNum ÷ 32`。因为它是一个 4 字节组,我们需要将它与 4 相乘的结果。它与二进制表示的数左移 2 位的相同的,这就是下一行的命令。你可能想知道我们能否将它右移 3 位呢,这样我们就可以先右移再左移。但是这样做是不行的,因为当我们做 ÷ 32 时有些答案可能是四舍五入的,而如果我们做 ÷ 8 时却不会这样。
|
||||
|
||||
现在,`gpioAddr` 的结果有可能是 20200000~16~(如果针脚号介于 0 到 31 之间),也有可能是 20200004~16~(如果针脚号介于 32 到 53 之间)。这意味着如果加上 28~10~ ,我们将得到打开针脚的地址,而如果加上 40~10~ ,我们将得到关闭针脚的地址。由于我们使用了 `pinBank` ,所以在它之后立即使用 `.unreq` 去删除它。、
|
||||
|
||||
将下面的代码复制粘贴到上述代码的下面位置。
|
||||
|
||||
```assembly
|
||||
and pinNum,#31
|
||||
setBit .req r3
|
||||
mov setBit,#1
|
||||
lsl setBit,pinNum
|
||||
.unreq pinNum
|
||||
```
|
||||
|
||||
```assembly
|
||||
and reg,#val 计算寄存器中的数与 val 的布尔与。
|
||||
```
|
||||
|
||||
函数的下一个部分是产生一个正确的设置数的位。至于 GPIO 控制器去打开或关闭针脚,我们在针脚号除以 32 的余数的位置,给它一个设置数字的位。例如,设置 16 号针脚,我们需要第 16 位设置数字为 1 。设置 45 号针脚,我们需要设置第 13 位数字为 1,因为 45 ÷ 32 = 1 余数 13。
|
||||
|
||||
这个 `and` 命令计算我们需要的余数。它是这样计算的,在输入中所有的二进制位都是 1 时,这个 `and` 运算的结果就是 1,否则就是 0。这是一个很基础的二进制操作,`and` 操作非常快。我们给定的输入是 “pinNum and 31~10~ = 11111~2~”。这意味着答案的后 5 位中只有 1,因此它肯定是在 0 到 31 之间。尤其是在 `pinNum` 的后 5 位的位置是 1 的地方它只有 1。这就如同被 32 整除的余数部分。就像 31 = 32 - 1 并不是巧合。
|
||||
|
||||
![binary division example][4]
|
||||
|
||||
代码的其余部分使用这个值去左移 1 位。这就有了创建我们所需要的二进制数的效果。
|
||||
|
||||
将下面的代码复制粘贴到上述代码的下面位置。
|
||||
|
||||
```assembly
|
||||
teq pinVal,#0
|
||||
.unreq pinVal
|
||||
streq setBit,[gpioAddr,#40]
|
||||
strne setBit,[gpioAddr,#28]
|
||||
.unreq setBit
|
||||
.unreq gpioAddr
|
||||
pop {pc}
|
||||
```
|
||||
|
||||
```assembly
|
||||
teq reg,#val 检查寄存器 reg 中的数字与 val 是否相等。
|
||||
```
|
||||
|
||||
这个代码是方法的结束部分。如前面所说,当 `pinVal` 为 0 时,我们关闭它,否则就打开它。`teq`(等于测试)是另一个比较操作,它仅能够测试是否相等。它类似于 `cmp` ,但它并不能算出哪个数大。如果你只是希望测试数字是否相同,你可以使用 `teq`。
|
||||
|
||||
如果 `pinVal` 是 0,我们将 `setBit` 保存在 GPIO 地址偏移 40 的位置,我们已经知道,这样会关闭那个针脚。否则将它保存在 GPIO 地址偏移 28 的位置,它将打开那个针脚。最后,我们通过弹出 `pc` 返回,这将设置它为我们推送链接寄存器时保存的值。
|
||||
|
||||
### 5、一个新的开始
|
||||
|
||||
在完成上述工作后,我们终于有了我们的 GPIO 函数。现在,我们需要去修改 `main.s` 去使用它们。因为 `main.s` 现在已经有点大了,也更复杂了。将它分成两节将是一个很好的设计。到目前为止,我们一直使用的 `.init` 应该尽可能的让它保持小。我们可以更改代码来很容易地反映出这一点。
|
||||
|
||||
将下列的代码插入到 `main.s` 文件中 `_start: ` 的后面:
|
||||
|
||||
```
|
||||
b main
|
||||
|
||||
.section .text
|
||||
main:
|
||||
mov sp,#0x8000
|
||||
```
|
||||
|
||||
在这里重要的改变是引入了 `.text` 节。我设计了 `makefile` 和链接器脚本,它将 `.text` 节(它是默认节)中的代码放在地址为 8000~16~ 的 `.init` 节之后。这是默认加载地址,并且它给我们提供了一些空间去保存栈。由于栈存在于内存中,它也有一个地址。栈向下增长内存,因此每个新值都低于前一个地址,所以,这便得栈顶是最低的一个地址。
|
||||
|
||||
```
|
||||
图中的 'ATAGs' 节的位置保存了有关树莓派的信息,比如它有多少内存,默认屏幕分辨率是多少。
|
||||
```
|
||||
|
||||
![Layout diagram of operating system][5]
|
||||
|
||||
用下面的代码替换掉所有设置 GPIO 函数针脚的代码:
|
||||
|
||||
```assembly
|
||||
pinNum .req r0
|
||||
pinFunc .req r1
|
||||
mov pinNum,#16
|
||||
mov pinFunc,#1
|
||||
bl SetGpioFunction
|
||||
.unreq pinNum
|
||||
.unreq pinFunc
|
||||
```
|
||||
|
||||
这个代码将使用针脚号 16 和函数代码 1 去调用 `SetGpioFunction`。它的效果就是启用了 OK LED 灯的输出。
|
||||
|
||||
用下面的代码去替换打开 OK LED 灯的代码:
|
||||
|
||||
```assembly
|
||||
pinNum .req r0
|
||||
pinVal .req r1
|
||||
mov pinNum,#16
|
||||
mov pinVal,#0
|
||||
bl SetGpio
|
||||
.unreq pinNum
|
||||
.unreq pinVal
|
||||
```
|
||||
|
||||
这个代码使用 `SetGpio` 去关闭 GPIO 第 16 号针脚,因此将打开 OK LED。如果我们(将第 4 行)替换成 `mov pinVal,#1` 它将关闭 LED 灯。用以上的代码去替换掉你关闭 LED 灯的旧代码。
|
||||
|
||||
### 6、继续向目标前进
|
||||
|
||||
但愿你能够顺利地在你的树莓派上测试我们所做的这一切。到目前为止,我们已经写了一大段代码,因此不可避免会出现错误。如果有错误,可以去查看我们的排错页面。
|
||||
|
||||
如果你的代码已经正常工作,恭喜你。虽然我们的操作系统除了做 [课程 2:OK02][1] 中的事情之外,还做不了别的任何事情,但我们已经学会了函数和格式有关的知识,并且我们现在可以更好更快地编写新特性了。现在,我们在操作系统上修改 GPIO 寄存器将变得非常简单,而它就是用于控制硬件的!
|
||||
|
||||
在 [课程 4:OK04][6] 中,我们将处理我们的 `wait` 函数,目前,它的时间控制还不精确,这样我们就可以更好地控制我们的 LED 灯了,进而最终控制所有的 GPIO 针脚。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok03.html
|
||||
|
||||
作者:[Robert Mullins][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[qhwdw](https://github.com/qhwdw )
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://www.cl.cam.ac.uk/~rdm34
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok02.html
|
||||
[2]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/images/functions.png
|
||||
[3]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/images/stack.png
|
||||
[4]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/images/binary3.png
|
||||
[5]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/images/osLayout.png
|
||||
[6]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok04.html
|
@ -1,336 +0,0 @@
|
||||
如何搜索一个包是否在你的 Linux 发行版中
|
||||
======
|
||||
如果你知道包名称,那么你可以直接安装所需的包。
|
||||
|
||||
在某些情况下,如果你不知道确切的包名称或者你想搜索某些包,那么你可以在分发包管理器的帮助下轻松搜索该包。
|
||||
|
||||
自动搜索包括已安装和可用的包。
|
||||
|
||||
结果的格式取决于选项。如果查询没有生成任何信息,那么意味着没有匹配条件的包。
|
||||
|
||||
这可以通过具有各种选项的分发包管理器来完成。
|
||||
|
||||
我已经在本文中添加了所有可能的选项,你可以选择最好的和最合适你的选项。
|
||||
|
||||
或者,我们可以通过 **whohas** 命令实现这一点。它会从所有的主流发行版(例如 Debian, Ubuntu, Fedora 等)中搜索,而不仅仅是你自己的系统发行版。
|
||||
|
||||
**建议阅读:**
|
||||
**(#)** [适用于 Linux 的命令行包管理器列表以及用法][1]
|
||||
**(#)** [Linux 包管理器的图形前端工具][2]
|
||||
|
||||
### 如何在 Debian/Ubuntu 中搜索一个包
|
||||
|
||||
我们可以使用 apt, apt-cache 和 aptitude 包管理器在基于 Debian 的发行版上查找给定的包。我为这个包管理器中包括了大量的选项。
|
||||
|
||||
我们可以在基于 Debian 的系统中使用三种方式完成此操作。
|
||||
|
||||
* apt 命令
|
||||
* apt-cache 命令
|
||||
* aptitude 命令
|
||||
|
||||
### 如何使用 apt 命令搜索一个包
|
||||
|
||||
APT 代表高级包管理工具 Advanced Packaging Tool(APT),它取代了 apt-get。它有功能丰富的命令行工具,包括所有功能包含在一个命令(APT)里,包括 apt-cache, apt-search, dpkg, apt-cdrom, apt-config, apt-key 等,还有其他几个独特的功能。
|
||||
|
||||
APT 是一个强大的命令行工具,它可以访问 libapt-pkg 底层库的所有特性,它可以用于安装,下载,删除,搜索和管理以及查询关于包的信息,另外它还包含一些较少使用的与包管理相关的命令行实用程序。
|
||||
```
|
||||
$ apt -q list nano vlc
|
||||
Listing...
|
||||
nano/artful,now 2.8.6-3 amd64 [installed]
|
||||
vlc/artful 2.2.6-6 amd64
|
||||
```
|
||||
|
||||
或者,我们可以使用以下格式搜索指定的包。
|
||||
```
|
||||
$ apt search ^vlc
|
||||
Sorting... Done
|
||||
Full Text Search... Done
|
||||
vlc/artful 2.2.6-6 amd64
|
||||
multimedia player and streamer
|
||||
|
||||
vlc-bin/artful 2.2.6-6 amd64
|
||||
binaries from VLC
|
||||
|
||||
vlc-data/artful,artful 2.2.6-6 all
|
||||
Common data for VLC
|
||||
|
||||
vlc-l10n/artful,artful 2.2.6-6 all
|
||||
Translations for VLC
|
||||
|
||||
vlc-plugin-access-extra/artful 2.2.6-6 amd64
|
||||
multimedia player and streamer (extra access plugins)
|
||||
|
||||
vlc-plugin-base/artful 2.2.6-6 amd64
|
||||
multimedia player and streamer (base plugins)
|
||||
|
||||
```
|
||||
|
||||
### 如何使用 apt-cache 命令搜索一个包
|
||||
|
||||
apt-cache 会在 APT 的包缓存上执行各种操作。它会显示有关指定包的信息。apt-cache 不会操纵系统的状态,但提供了从包的元数据中搜索和生成有趣输出的操作。
|
||||
```
|
||||
$ apt-cache search nano | grep ^nano
|
||||
nano - small, friendly text editor inspired by Pico
|
||||
nano-tiny - small, friendly text editor inspired by Pico - tiny build
|
||||
nanoblogger - Small weblog engine for the command line
|
||||
nanoblogger-extra - Nanoblogger plugins
|
||||
nanoc - static site generator written in Ruby
|
||||
nanoc-doc - static site generator written in Ruby - documentation
|
||||
nanomsg-utils - nanomsg utilities
|
||||
nanopolish - consensus caller for nanopore sequencing data
|
||||
|
||||
```
|
||||
|
||||
或者,我们可以使用以下格式搜索指定的包。
|
||||
```
|
||||
$ apt-cache policy vlc
|
||||
vlc:
|
||||
Installed: (none)
|
||||
Candidate: 2.2.6-6
|
||||
Version table:
|
||||
2.2.6-6 500
|
||||
500 http://in.archive.ubuntu.com/ubuntu artful/universe amd64 Packages
|
||||
|
||||
```
|
||||
|
||||
或者,我们可以使用以下格式搜索给定的包。
|
||||
```
|
||||
$ apt-cache pkgnames vlc
|
||||
vlc-bin
|
||||
vlc-plugin-video-output
|
||||
vlc-plugin-sdl
|
||||
vlc-plugin-svg
|
||||
vlc-plugin-samba
|
||||
vlc-plugin-fluidsynth
|
||||
vlc-plugin-qt
|
||||
vlc-plugin-skins2
|
||||
vlc-plugin-visualization
|
||||
vlc-l10n
|
||||
vlc-plugin-notify
|
||||
vlc-plugin-zvbi
|
||||
vlc-plugin-vlsub
|
||||
vlc-plugin-jack
|
||||
vlc-plugin-access-extra
|
||||
vlc
|
||||
vlc-data
|
||||
vlc-plugin-video-splitter
|
||||
vlc-plugin-base
|
||||
|
||||
```
|
||||
|
||||
### 如何使用 aptitude 命令搜索一个包
|
||||
|
||||
aptitude 一个基于文本的 Debian GNU/Linux 软件包系统的接口。它允许用户查看包列表,并执行包管理任务,例如安装,升级和删除包,它可以从可视化界面或命令行执行操作。
|
||||
```
|
||||
$ aptitude search ^vlc
|
||||
p vlc - multimedia player and streamer
|
||||
p vlc:i386 - multimedia player and streamer
|
||||
p vlc-bin - binaries from VLC
|
||||
p vlc-bin:i386 - binaries from VLC
|
||||
p vlc-data - Common data for VLC
|
||||
v vlc-data:i386 -
|
||||
p vlc-l10n - Translations for VLC
|
||||
v vlc-l10n:i386 -
|
||||
p vlc-plugin-access-extra - multimedia player and streamer (extra access plugins)
|
||||
p vlc-plugin-access-extra:i386 - multimedia player and streamer (extra access plugins)
|
||||
p vlc-plugin-base - multimedia player and streamer (base plugins)
|
||||
p vlc-plugin-base:i386 - multimedia player and streamer (base plugins)
|
||||
p vlc-plugin-fluidsynth - FluidSynth plugin for VLC
|
||||
p vlc-plugin-fluidsynth:i386 - FluidSynth plugin for VLC
|
||||
p vlc-plugin-jack - Jack audio plugins for VLC
|
||||
p vlc-plugin-jack:i386 - Jack audio plugins for VLC
|
||||
p vlc-plugin-notify - LibNotify plugin for VLC
|
||||
p vlc-plugin-notify:i386 - LibNotify plugin for VLC
|
||||
p vlc-plugin-qt - multimedia player and streamer (Qt plugin)
|
||||
p vlc-plugin-qt:i386 - multimedia player and streamer (Qt plugin)
|
||||
p vlc-plugin-samba - Samba plugin for VLC
|
||||
p vlc-plugin-samba:i386 - Samba plugin for VLC
|
||||
p vlc-plugin-sdl - SDL video and audio output plugin for VLC
|
||||
p vlc-plugin-sdl:i386 - SDL video and audio output plugin for VLC
|
||||
p vlc-plugin-skins2 - multimedia player and streamer (Skins2 plugin)
|
||||
p vlc-plugin-skins2:i386 - multimedia player and streamer (Skins2 plugin)
|
||||
p vlc-plugin-svg - SVG plugin for VLC
|
||||
p vlc-plugin-svg:i386 - SVG plugin for VLC
|
||||
p vlc-plugin-video-output - multimedia player and streamer (video output plugins)
|
||||
p vlc-plugin-video-output:i386 - multimedia player and streamer (video output plugins)
|
||||
p vlc-plugin-video-splitter - multimedia player and streamer (video splitter plugins)
|
||||
p vlc-plugin-video-splitter:i386 - multimedia player and streamer (video splitter plugins)
|
||||
p vlc-plugin-visualization - multimedia player and streamer (visualization plugins)
|
||||
p vlc-plugin-visualization:i386 - multimedia player and streamer (visualization plugins)
|
||||
p vlc-plugin-vlsub - VLC extension to download subtitles from opensubtitles.org
|
||||
p vlc-plugin-zvbi - VBI teletext plugin for VLC
|
||||
p vlc-plugin-zvbi:i386
|
||||
|
||||
```
|
||||
|
||||
### 如何在 RHEL/CentOS 中搜索一个包
|
||||
|
||||
Yum(Yellowdog Updater Modified)是 Linux 操作系统中的包管理器实用程序之一。Yum 命令用于在一些基于 RedHat 的 Linux 发行版上,它用来安装,更新,搜索和删除软件包。
|
||||
```
|
||||
# yum search ftpd
|
||||
Loaded plugins: fastestmirror, refresh-packagekit, security
|
||||
Loading mirror speeds from cached hostfile
|
||||
* base: centos.hyve.com
|
||||
* epel: mirrors.coreix.net
|
||||
* extras: centos.hyve.com
|
||||
* rpmforge: www.mirrorservice.org
|
||||
* updates: mirror.sov.uk.goscomb.net
|
||||
============================================================== N/S Matched: ftpd ===============================================================
|
||||
nordugrid-arc-gridftpd.x86_64 : ARC gridftp server
|
||||
pure-ftpd.x86_64 : Lightweight, fast and secure FTP server
|
||||
vsftpd.x86_64 : Very Secure Ftp Daemon
|
||||
|
||||
Name and summary matches only, use "search all" for everything.
|
||||
|
||||
```
|
||||
|
||||
或者,我们可以使用以下命令搜索相同内容。
|
||||
```
|
||||
# yum list ftpd
|
||||
```
|
||||
|
||||
### 如何在 Fedora 中搜索一个包
|
||||
|
||||
DNF 代表 Dandified yum。我们可以说 DNF 是下一代 yum 包管理器(Yum 的衍生),它使用 hawkey/libsolv 库作为底层。自从 Fedora 18 开始以及它最终在 Fedora 22 中实施以来,Aleš Kozumplík 就在开始研究 DNF。
|
||||
```
|
||||
# dnf search ftpd
|
||||
Last metadata expiration check performed 0:42:28 ago on Tue Jun 9 22:52:44 2018.
|
||||
============================== N/S Matched: ftpd ===============================
|
||||
proftpd-utils.x86_64 : ProFTPD - Additional utilities
|
||||
pure-ftpd-selinux.x86_64 : SELinux support for Pure-FTPD
|
||||
proftpd-devel.i686 : ProFTPD - Tools and header files for developers
|
||||
proftpd-devel.x86_64 : ProFTPD - Tools and header files for developers
|
||||
proftpd-ldap.x86_64 : Module to add LDAP support to the ProFTPD FTP server
|
||||
proftpd-mysql.x86_64 : Module to add MySQL support to the ProFTPD FTP server
|
||||
proftpd-postgresql.x86_64 : Module to add PostgreSQL support to the ProFTPD FTP
|
||||
: server
|
||||
vsftpd.x86_64 : Very Secure Ftp Daemon
|
||||
proftpd.x86_64 : Flexible, stable and highly-configurable FTP server
|
||||
owfs-ftpd.x86_64 : FTP daemon providing access to 1-Wire networks
|
||||
perl-ftpd.noarch : Secure, extensible and configurable Perl FTP server
|
||||
pure-ftpd.x86_64 : Lightweight, fast and secure FTP server
|
||||
pyftpdlib.noarch : Python FTP server library
|
||||
nordugrid-arc-gridftpd.x86_64 : ARC gridftp server
|
||||
```
|
||||
|
||||
或者,我们可以使用以下命令搜索相同的内容。
|
||||
```
|
||||
# dnf list proftpd
|
||||
Failed to synchronize cache for repo 'heikoada-terminix', disabling.
|
||||
Last metadata expiration check: 0:08:02 ago on Tue 26 Jun 2018 04:30:05 PM IST.
|
||||
Available Packages
|
||||
proftpd.x86_64
|
||||
```
|
||||
|
||||
### 如何在 Arch Linux 中搜索一个包
|
||||
|
||||
pacman 代表包管理实用程序(pacman)。它是一个用于安装,构建,删除和管理 Arch Linux 软件包的命令行实用程序。pacman 使用 libalpm(Arch Linux Package Management(ALPM)库)作为底层来执行所有操作。
|
||||
|
||||
在本例中,我将要搜索 chromium 包。
|
||||
```
|
||||
# pacman -Ss chromium
|
||||
extra/chromium 48.0.2564.116-1
|
||||
The open-source project behind Google Chrome, an attempt at creating a safer, faster, and more stable browser
|
||||
extra/qt5-webengine 5.5.1-9 (qt qt5)
|
||||
Provides support for web applications using the Chromium browser project
|
||||
community/chromium-bsu 0.9.15.1-2
|
||||
A fast paced top scrolling shooter
|
||||
community/chromium-chromevox latest-1
|
||||
Causes the Chromium web browser to automatically install and update the ChromeVox screen reader extention. Note: This
|
||||
package does not contain the extension code.
|
||||
community/fcitx-mozc 2.17.2313.102-1
|
||||
Fcitx Module of A Japanese Input Method for Chromium OS, Windows, Mac and Linux (the Open Source Edition of Google Japanese
|
||||
Input)
|
||||
```
|
||||
|
||||
默认情况下,`-s` 选项内置 ERE(扩展正则表达式)会导致很多不需要的结果。使用以下格式会仅匹配包名称。
|
||||
```
|
||||
# pacman -Ss '^chromium-'
|
||||
|
||||
```
|
||||
|
||||
pkgfile 是一个用于在 Arch Linux 官方仓库的包中搜索文件的工具。
|
||||
```
|
||||
# pkgfile chromium
|
||||
```
|
||||
|
||||
### 如何在 openSUSE 中搜索一个包
|
||||
|
||||
Zypper 是 SUSE 和 openSUSE 发行版的命令行包管理器。它用于安装,更新,搜索和删除包以及管理仓库,执行各种查询等。Zypper 命令行接口到 ZYpp 系统管理库(libzypp)。
|
||||
```
|
||||
# zypper search ftp
|
||||
or
|
||||
# zypper se ftp
|
||||
Loading repository data...
|
||||
Reading installed packages...
|
||||
S | Name | Summary | Type
|
||||
--+----------------+-----------------------------------------+--------
|
||||
| proftpd | Highly configurable GPL-licensed FTP -> | package
|
||||
| proftpd-devel | Development files for ProFTPD | package
|
||||
| proftpd-doc | Documentation for ProFTPD | package
|
||||
| proftpd-lang | Languages for package proftpd | package
|
||||
| proftpd-ldap | LDAP Module for ProFTPD | package
|
||||
| proftpd-mysql | MySQL Module for ProFTPD | package
|
||||
| proftpd-pgsql | PostgreSQL Module for ProFTPD | package
|
||||
| proftpd-radius | Radius Module for ProFTPD | package
|
||||
| proftpd-sqlite | SQLite Module for ProFTPD | package
|
||||
| pure-ftpd | A Lightweight, Fast, and Secure FTP S-> | package
|
||||
| vsftpd | Very Secure FTP Daemon - Written from-> | package
|
||||
```
|
||||
|
||||
### 如何使用 whohas 命令搜索一个包
|
||||
|
||||
whohas 命令是一个智能工具,从所有主流发行版中搜索指定包,如 Debian, Ubuntu, Gentoo, Arch, AUR, Mandriva, Fedora, Fink, FreeBSD 和 NetBSD。
|
||||
```
|
||||
$ whohas nano
|
||||
Mandriva nano-debug 2.3.1-1mdv2010.2.x http://sophie.zarb.org/rpms/0b33dc73bca710749ad14bbc3a67e15a
|
||||
Mandriva nano-debug 2.2.4-1mdv2010.1.i http://sophie.zarb.org/rpms/d9dfb2567681e09287b27e7ac6cdbc05
|
||||
Mandriva nano-debug 2.2.4-1mdv2010.1.x http://sophie.zarb.org/rpms/3299516dbc1538cd27a876895f45aee4
|
||||
Mandriva nano 2.3.1-1mdv2010.2.x http://sophie.zarb.org/rpms/98421c894ee30a27d9bd578264625220
|
||||
Mandriva nano 2.3.1-1mdv2010.2.i http://sophie.zarb.org/rpms/cea07b5ef9aa05bac262fc7844dbd223
|
||||
Mandriva nano 2.2.4-1mdv2010.1.s http://sophie.zarb.org/rpms/d61f9341b8981e80424c39c3951067fa
|
||||
Mandriva spring-mod-nanoblobs 0.65-2mdv2010.0.sr http://sophie.zarb.org/rpms/74bb369d4cbb4c8cfe6f6028e8562460
|
||||
Mandriva nanoxml-lite 2.2.3-4.1.4mdv2010 http://sophie.zarb.org/rpms/287a4c37bc2a39c0f277b0020df47502
|
||||
Mandriva nanoxml-manual-lite 2.2.3-4.1.4mdv2010 http://sophie.zarb.org/rpms/17dc4f638e5e9964038d4d26c53cc9c6
|
||||
Mandriva nanoxml-manual 2.2.3-4.1.4mdv2010 http://sophie.zarb.org/rpms/a1b5092cd01fc8bb78a0f3ca9b90370b
|
||||
Gentoo nano 9999 http://packages.gentoo.org/package/app-editors/nano
|
||||
Gentoo nano 9999 http://packages.gentoo.org/package/app-editors/nano
|
||||
Gentoo nano 2.9.8 http://packages.gentoo.org/package/app-editors/nano
|
||||
Gentoo nano 2.9.7 http://packages.gentoo.org/package/app-editors/nano
|
||||
```
|
||||
|
||||
如果你希望只从当前发行版仓库中搜索指定包,使用以下格式:
|
||||
```
|
||||
$ whohas -d Ubuntu vlc
|
||||
Ubuntu vlc 2.1.6-0ubuntu14.04 1M all http://packages.ubuntu.com/trusty/vlc
|
||||
Ubuntu vlc 2.1.6-0ubuntu14.04 1M all http://packages.ubuntu.com/trusty-updates/vlc
|
||||
Ubuntu vlc 2.2.2-5ubuntu0.16. 1M all http://packages.ubuntu.com/xenial/vlc
|
||||
Ubuntu vlc 2.2.2-5ubuntu0.16. 1M all http://packages.ubuntu.com/xenial-updates/vlc
|
||||
Ubuntu vlc 2.2.6-6 40K all http://packages.ubuntu.com/artful/vlc
|
||||
Ubuntu vlc 3.0.1-3build1 32K all http://packages.ubuntu.com/bionic/vlc
|
||||
Ubuntu vlc 3.0.2-0ubuntu0.1 32K all http://packages.ubuntu.com/bionic-updates/vlc
|
||||
Ubuntu vlc 3.0.3-1 33K all http://packages.ubuntu.com/cosmic/vlc
|
||||
Ubuntu browser-plugin-vlc 2.0.6-2 55K all http://packages.ubuntu.com/trusty/browser-plugin-vlc
|
||||
Ubuntu browser-plugin-vlc 2.0.6-4 47K all http://packages.ubuntu.com/xenial/browser-plugin-vlc
|
||||
Ubuntu browser-plugin-vlc 2.0.6-4 47K all http://packages.ubuntu.com/artful/browser-plugin-vlc
|
||||
Ubuntu browser-plugin-vlc 2.0.6-4 47K all http://packages.ubuntu.com/bionic/browser-plugin-vlc
|
||||
Ubuntu browser-plugin-vlc 2.0.6-4 47K all http://packages.ubuntu.com/cosmic/browser-plugin-vlc
|
||||
Ubuntu libvlc-bin 2.2.6-6 27K all http://packages.ubuntu.com/artful/libvlc-bin
|
||||
Ubuntu libvlc-bin 3.0.1-3build1 17K all http://packages.ubuntu.com/bionic/libvlc-bin
|
||||
Ubuntu libvlc-bin 3.0.2-0ubuntu0.1 17K all http://packages.ubuntu.com/bionic-updates/libvlc-bin
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/how-to-search-if-a-package-is-available-on-your-linux-distribution-or-not/
|
||||
|
||||
作者:[Prakash Subramanian][a]
|
||||
选题:[lujun9972](https://github.com/lujun9972)
|
||||
译者:[MjSeven](https://github.com/MjSeven)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.2daygeek.com/author/prakash/
|
||||
[1]:https://www.2daygeek.com/list-of-command-line-package-manager-for-linux/
|
||||
[2]:https://www.2daygeek.com/list-of-graphical-frontend-tool-for-linux-package-manager/
|
@ -0,0 +1,149 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (HankChow)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Comparing 3 open source databases: PostgreSQL, MariaDB, and SQLite)
|
||||
[#]: via: (https://opensource.com/article/19/1/open-source-databases)
|
||||
[#]: author: (Sam Bocetta https://opensource.com/users/sambocetta)
|
||||
|
||||
开源数据库 PostgreSQL、MariaDB 和 SQLite 的对比
|
||||
======
|
||||
> 要知道如何选择最适合你的需求的开源数据库。
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/data_container_block.png?itok=S8MbXEYw)
|
||||
|
||||
在现代企业的技术领域中,开源软件已经成为了一股不可忽视的重要力量。借助[<ruby>开源运动<rt>open source movement</rt></ruby>][1]的东风,很多重大的技术已经得到了长足的发展。
|
||||
|
||||
个中原因显而易见,尽管一些基于 Linux 的开源网络标准可能不如著名厂商的产品那么受欢迎,但是不同制造商的智能设备之间能够互相通信,开源技术功不可没。当然也有不少人认为开源应用比厂商提供的产品更加好,所以无论如何,使用开源数据库进行开发确实是相当有利的。
|
||||
|
||||
和其它类型的应用软件一样,[不同的开源数据库管理系统之间在功能和特性上可能会存在着比较大的差异][2]。因此,如果要为整个团队选择一个开源数据库,那么应该重点考察数据库是否对用户友好、是否能够持续适应团队需求、是否能够提供足够安全的功能等方面的因素。
|
||||
|
||||
出于这方面考虑,我们在这篇文章中对一些开源数据库进行了概述和对比。但也有可能略过了一些常用的数据库。需要提到的是,MongoDB 最近更改了它的许可证,因此它已经不是完全的开源产品了。从商业角度来看,这个决定是很有意义的,因为 MongoDB 已经成为了[约 27000 家公司][3]在数据库托管方面的实际解决方案,这也意味着 MongoDB 已经不再被视为真正的开源产品。
|
||||
|
||||
另外,在 MySQL 被 Oracle 收购之后,这个产品就已经不再具有开源性质了。MySQL 在过去相当长的一段时间里都是很多项目的首选数据库,因此它的案例也是摆在其它开源数据库面前的一个巨大挑战。
|
||||
|
||||
下面讨论一下我们提到的三个开源数据库。
|
||||
|
||||
### PostgreSQL
|
||||
|
||||
[PostgreSQL][4] 可以说是开源数据库中的一个重要成员。无论是哪种规模的企业,PostgreSQL 可能都是它们的首选解决方案。Oracle 对 MySQL 的收购在当时来说可能具有一定的商业意义,但是随着云存储的日益壮大,[开发者对 MySQL 的依赖程度或许并不如以前那么大了][5]。
|
||||
|
||||
尽管 PostgreSQL 不是一个最近几年才面世的新产品,但它却是借助了 [MySQL 衰落][6]的机会才逐渐成为最受欢迎的开源数据库之一。由于它和 MySQL 的工作方式非常相似,因此很多热衷于使用开源软件的开发者都纷纷转向 PostgreSQL。
|
||||
|
||||
#### 优势
|
||||
|
||||
* 目前 PostgreSQL 最显著的优点是它的算法效率高,因此它的性能就比其它的数据库也高一些。这一点在处理大型数据集的时候就可以很明显地体现出来了,否则在运算过程中 I/O 会成为瓶颈。
|
||||
* PostgreSQL 也是最灵活的开源数据库之一,使用 Python、Perl、Java、Ruby、C 或者 R 都能够很方便地调用数据库。
|
||||
* 作为最常用的几个开源数据库之中,PostgreSQL 的社区支持是做得最好的。
|
||||
|
||||
|
||||
|
||||
|
||||
#### 劣势
|
||||
|
||||
* 在数据量比较大的时候,PostgreSQL 的效率毋庸置疑是很高的,但对于数据量较小的情况,使用 PostgreSQL 就显得不如其它的一些工具轻量级了。
|
||||
|
||||
* 尽管拥有一个很优秀的社区支持,但 PostgreSQL 的核心文档仍然需要作出改进。
|
||||
|
||||
* 如果你需要使用并行计算或者集群化等高级工具,就需要安装 PostgreSQL 的第三方插件。尽管官方有计划将这些功能逐步添加到主要版本当中,但可能会需要再等待好几年才能实现。
|
||||
|
||||
|
||||
|
||||
|
||||
### MariaDB
|
||||
|
||||
[MariaDB][7] 是 MySQL 的真正开源发行版本(在 [GNU GPLv2][8] 下发布)。在 Oracle 收购 MySQL 之后,MySQL 的一些核心开发人员认为 Oracle 会破坏 MySQL 的开源理念,因此建立了 MariaDB 这个独立的分支。
|
||||
|
||||
MariaDB 在开发过程中替换了 MySQL 的几个关键组件,但仍然尽可能地保持兼容 MySQL。MariaDB 使用了 Aria 作为存储引擎,这个存储引擎既可以作为事务式引擎,也可以作为非事务式引擎。在 MariaDB 独立出来之前,就[有一些人推测][10] Aria 会成为 MySQL 未来版本中的标准引擎。
|
||||
|
||||
#### 优势
|
||||
|
||||
* 由于 MariaDB [频繁进行安全发布][11],很多用户选择使用 MariaDB 而不选择 MySQL。尽管这不一定代表 MariaDB 会比 MySQL 更加安全,但确实表明它的开发社区对安全性十分重视。
|
||||
|
||||
* 有一些人认为,MariaDB 的主要优点就是它在坚持开源的同时会与 MySQL 保持高度兼容,这就表示从 MySQL 向 MariaDB 的迁移会非常容易。
|
||||
|
||||
* 也正是由于这种兼容性,MariaDB 也可以和其它常用于 MySQL 的语言配合使用,因此从 MySQL 迁移到 MariaDB 之后,学习和调试代码的时间成本会非常低。
|
||||
|
||||
* 你可以将 WordPress 和 MariaDB(而不是 MySQL)[配合使用][12]从而获得更好的性能和更丰富的功能。WordPress 是[最受欢迎的<ruby>内容管理系统<rt>Content Management System</rt></ruby>][13](CMS),并且拥有活跃的开源开发者社区。各种第三方插件在 WordPress 和 MariaDB 配合使用时都能够正常工作。
|
||||
|
||||
|
||||
|
||||
|
||||
#### 劣势
|
||||
|
||||
* MariaDB 有时会变得比较臃肿,尤其是它的 IDX 日志文件在长期使用之后会变得非常大,最终导致性能下降。
|
||||
|
||||
* MariaDB 的缓存并没有期望中那么快,这可能会让人有所失望。
|
||||
|
||||
* 尽管 MariaDB 最初承诺兼容 MySQL,但目前 MariaDB 已经不是完全兼容 MySQL。如果要从 MySQL 迁移到 MariaDB,就需要额外做一些兼容工作。
|
||||
|
||||
|
||||
|
||||
|
||||
### SQLite
|
||||
|
||||
[SQLite][14] 可以说是世界上实现最多的数据库引擎,因为它被很多流行的 web 浏览器、操作系统和手机所采用。它最初是作为 MySQL 的轻量级分支所开发的。SQLite 和很多其它的数据库不同,它不采用客户端-服务端的引擎架构,而是将整个软件嵌入到每个实现当中。
|
||||
|
||||
这样的架构让 SQLite 拥有一个强大的优势,就是在嵌入式系统或者分布式系统中,每台机器都搭载了数据库的整个实现。这样的做法减少了系统间的调用,从而大大提高了数据库的性能。
|
||||
|
||||
#### 优势
|
||||
|
||||
* 如果你需要构建和实现一个小型数据库,SQLite [可能是最好的选择][15]。它小而灵活,不需要费工夫寻求各种变通方案,就可以在嵌入式系统中实现。
|
||||
|
||||
* SQLite 体积很小,因此速度也很快。其它的一些高级数据库可能会使用复杂的优化方式来提高效率,但不如SQLite 这样减小数据库大小更为直接。
|
||||
|
||||
* SQLite 被广泛采用也导致它可能是兼容性最高的数据库。如果你希望将应用程序集成到智能手机上,只要有第三方应用程序使用到了 SQLite,就能够正常运行数据库了。
|
||||
|
||||
|
||||
|
||||
|
||||
#### 劣势
|
||||
|
||||
* SQLite 的轻量意味着它缺少了很多其它大型数据库的常见功能。例如数据加密就是[抵御网络攻击][16]的标准功能,而 SQLite 却没有内置这个功能。
|
||||
|
||||
* SQLite 的广泛流行和源码公开使它易于使用,但是也让它更容易遭受攻击。这是它最大的劣势。SQLite 经常被发现高位的漏洞,例如最近的 [Magellan][17]。
|
||||
|
||||
* 尽管 SQLite 单文件的方式拥有速度上的优势,但是要使用它实现多用户环境却比较困难。
|
||||
|
||||
|
||||
|
||||
|
||||
### 哪个开源数据库才是最好的?
|
||||
|
||||
当然,对于开源数据库的选择还是取决于业务的需求以及系统的体量。对于小型数据库或者是使用量比较小的数据库,可以使用比较轻量级的解决方案,这样不仅可以加快实现的速度,而且由于系统的复杂程度不算太高,花在调试上的时间成本也不会太高。
|
||||
|
||||
而对于大型的系统,尤其是业务增长速度较快的业务,最好还是花时间使用更复杂的数据库(例如 PostgreSQL)。这是一个磨刀不误砍柴工的选择,能够让你不至于在后期再重新选择另一款数据库。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/1/open-source-databases
|
||||
|
||||
作者:[Sam Bocetta][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[HankChow](https://github.com/HankChow)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/sambocetta
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/article/18/2/pivotal-moments-history-open-source
|
||||
[2]: https://blog.capterra.com/free-database-software/
|
||||
[3]: https://idatalabs.com/tech/products/mongodb
|
||||
[4]: https://www.postgresql.org/
|
||||
[5]: https://www.theregister.co.uk/2018/05/31/rise_of_the_open_source_data_strategies/
|
||||
[6]: https://www.itworld.com/article/2721995/big-data/signs-of-mysql-decline-on-horizon.html
|
||||
[7]: https://mariadb.org/
|
||||
[8]: https://github.com/MariaDB/server/blob/10.4/COPYING
|
||||
[9]: https://mariadb.com/about-us/
|
||||
[10]: http://kb.askmonty.org/en/aria-faq
|
||||
[11]: https://mariadb.org/tag/security/
|
||||
[12]: https://mariadb.com/resources/blog/how-to-install-and-run-wordpress-with-mariadb/
|
||||
[13]: https://websitesetup.org/popular-cms/
|
||||
[14]: https://www.sqlite.org/index.html
|
||||
[15]: https://www.sqlite.org/aff_short.html
|
||||
[16]: https://hostingcanada.org/most-common-website-vulnerabilities/
|
||||
[17]: https://www.securitynewspaper.com/2018/12/18/critical-vulnerability-in-sqlite-you-should-update-now/
|
||||
|
||||
|
@ -0,0 +1,90 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Get started with Roland, a random selection tool for the command line)
|
||||
[#]: via: (https://opensource.com/article/19/1/productivity-tools-roland)
|
||||
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney (Kevin Sonney))
|
||||
|
||||
开始使用 Roland,一款命令行随机选择工具
|
||||
======
|
||||
|
||||
Roland 是我们在开源工具系列中的第七个工具,它将帮助你在 2019 年提高工作效率。
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/dice_tabletop_board_gaming_game.jpg?itok=y93eW7HN)
|
||||
|
||||
每年年初似乎都有疯狂的冲动想提高工作效率。新年的决心,渴望开启新的一年,当然,“抛弃旧的,拥抱新的”的态度促成了这一切。通常这时的建议严重偏向闭源和专有软件,但事实上并不用这样。
|
||||
|
||||
这是我挑选出的 19 个新的(或者对你而言新的)开源工具中的第七个工具来帮助你在 2019 年更有效率。
|
||||
|
||||
### Roland
|
||||
|
||||
当一周的工作结束后,我唯一想做的就是躺到沙发上打一个周末的游戏。但即使我的职业义务在工作日结束后停止了,但我仍然需要管理我的家庭。洗衣、宠物护理、确保我孩子有他所需要的东西,以及最重要的是:决定晚餐吃什么。
|
||||
|
||||
像许多人一样,我经常受到[决策疲劳][1]的困扰,根据速度、准备难易以及(坦白地说)任何让我压力最小的方式都会导致不太健康的晚餐选择。
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/roland-1.png)
|
||||
|
||||
[Roland][2]让我计划饭菜变得容易。Roland 是一款专为桌面角色扮演游戏设计的 Perl 应用。它从怪物和雇佣者等物品列表中随机挑选。从本质上讲,Roland 在命令行做的事情与游戏大师在掷骰子时做的同样的事情,以便在游戏大师的《对玩家的坏事书》中的桌子上查找东西。
|
||||
|
||||
通过微小的修改,Roland 可以做得更多。例如,只需添加一张桌子,我就可以让 Roland 帮我选择晚餐。
|
||||
|
||||
第一步是安装 Roland 及其依赖项。
|
||||
|
||||
```
|
||||
git clone git@github.com:rjbs/Roland.git
|
||||
cpan install Getopt::Long::Descriptive Moose \
|
||||
namespace::autoclean List:AllUtils Games::Dice \
|
||||
Sort::ByExample Data::Bucketeer Text::Autoformat \
|
||||
YAML::XS
|
||||
cd oland
|
||||
```
|
||||
|
||||
接下来,创建一个名为 **dinner** 的 YAML 文档,并输入我们所有的用餐选项。
|
||||
|
||||
```
|
||||
type: list
|
||||
pick: 1
|
||||
items:
|
||||
- "frozen pizza"
|
||||
- "chipotle black beans"
|
||||
- "huevos rancheros"
|
||||
- "nachos"
|
||||
- "pork roast"
|
||||
- "15 bean soup"
|
||||
- "roast chicken"
|
||||
- "pot roast"
|
||||
- "grilled cheese sandwiches"
|
||||
```
|
||||
|
||||
运行命令 **bin/roland dinner** 将读取文件并选择其中一项。
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/roland-2.png)
|
||||
|
||||
我想提前计划一周,这样我可以提前购买所有食材。 **pick** 命令确定列表中要选择的物品数量,现在,**pick** 设置为 1。如果我想计划一周的晚餐菜单,我可以将 **pick: 1** 变成 **pick: 7**,它会提供一周的菜单。你还可以使用 **-m** 选项手动输入选择。
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/roland-3.png)
|
||||
|
||||
你也可以用 Roland 做些有趣的事情,比如用经典短语添加一个名为 **8ball** 的文件。
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/roland-4.png)
|
||||
|
||||
你可以创建各种文件来帮助做出长时间工作后看起来非常难做的常见决策。即使你不用来做这个,你仍然可以用它来决定为今晚的游戏设置哪个狡猾的陷阱。
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/1/productivity-tools-roland
|
||||
|
||||
作者:[Kevin Sonney][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ksonney (Kevin Sonney)
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://en.wikipedia.org/wiki/Decision_fatigue
|
||||
[2]: https://github.com/rjbs/Roland
|
Loading…
Reference in New Issue
Block a user