2019年1月

简介

对于最后的项目,你有两个选择:

  • 继续使用你自己的 JOS 内核并做 实验 6,包括实验 6 中的一个挑战问题。(你可以随意地、以任何有趣的方式去扩展实验 6 或者 JOS 的任何部分,当然了,这不是课程规定的。)
  • 在一个、二个或三个人组成的团队中,你选择去做一个涉及了你的 JOS 的项目。这个项目必须是涉及到与实验 6 相同或更大的领域(如果你是团队中的一员)。

目标是为了获得乐趣或探索更高级的 O/S 的话题;你不需要做最新的研究。

如果你做了你自己的项目,我们将根据你的工作量有多少、你的设计有多优雅、你的解释有多高明、以及你的解决方案多么有趣或多有创意来为你打分。我们知道时间有限,因此也不期望你能在本学期结束之前重写 Linux。要确保你的目标是合理的;合理地设定一个绝对可以实现的最小目标(即:控制你的实验 6 的规模),如果进展顺利,可以设定一个更大的目标。

如果你做了实验 6,我们将根据你是否通过了测试和挑战练习来为你打分。

交付期限

11 月 3 日:Piazza 讨论和 1、2、或 3 年级组选择(根据你的最终选择来定)。使用在 Piazza 上的 lab7 标记/目录。在 Piazza 上的文章评论区与其它人计论想法。使用这些文章帮你去找到有类似想法的其它学生一起组建一个小组。课程的教学人员将在 Piazza 上为你的项目想法给出反馈;如果你想得到更详细的反馈,可以与我们单独讨论。

.

11 月 9 日:在 提交网站 上提交一个提议,只需要一到两个段落就可以。提议要包括你的小组成员列表、你的计划、以及明确的设计和实现打算。(如果你做实验 6,就不用做这个了)

.

12 月 7 日:和你的简短报告一起提交源代码。将你的报告放在与名为 “README.pdf” 的文件相同的目录下。由于你只是这个实验任务小组中的一员,你可能需要去使用 git 在小组成员之间共享你的项目代码。因此你需要去决定哪些源代码将作为你的小组项目的共享起始点。一定要为你的最终项目去创建一个分支,并且命名为 lab7。(如果你做了实验 6,就按实验 6 的提交要求做即可。)

.

12 月 11 日这一周:简短的课堂演示。为你的 JOS 项目准备一个简短的课堂演示。为了你的项目演示,我们将提供一个投影仪。根据小组数量和每个小组选择的项目类型,我们可能会限制总的演讲数,并且有些小组可能最终没有机会上台演示。

.

12 月 11 日这一周:助教们验收。向助教演示你的项目,因此我们可能会提问一些问题,去了解你所做的一些细节。

项目想法

如果你不做实验 6,下面是一个启迪你的想法列表。但是,你应该大胆地去实现你自己的想法。其中一些想法只是一个开端,并且本身不在实验 6 的领域内,并且其它的可能是在更大的领域中。

  • 使用 x86 虚拟机支持 去构建一个能够运行多个访客系统(比如,多个 JOS 实例)的虚拟机监视器。
  • 使用 Intel SGX 硬件保护机制做一些有用的事情。这是使用 Intel SGX 的最新的论文
  • 让 JOS 文件系统支持写入、文件创建、为持久性使用日志、等等。或许你可以从 Linux EXT3 上找到一些启示。
  • 软更新WAFL、ZFS、或其它较高级的文件系统上找到一些使用文件系统的想法。
  • 给一个文件系统添加快照功能,以便于用户能够查看过去的多个时间点上的文件系统。为了降低空间使用量,你或许要使用一些写时复制技术。
  • 使用分页去提供实时共享的内存,来构建一个 分布式的共享内存(DSM)系统,以便于你在一个机器集群上运行多线程的共享内存的并行程序。当一个线程尝试去访问位于另外一个机器上的页时,页故障将给 DSM 系统提供一个机会,让它基于网络去从当前存储这个页的任意一台机器上获取这个页。
  • 允许进程在机器之间基于网络进行迁移。你将需要做一些关于一个进程状态的多个片段方面的事情,但是由于在 JOS 中许多状态是在用户空间中,它或许从 Linux 上的进程迁移要容易一些。
  • 在 JOS 中实现 分页 到磁盘,这样那个进程使用的内存就可以大于真实的内存。使用交换空间去扩展你的内存。
  • 为 JOS 实现文件的 mmap()
  • 使用 xfi 将一个进程的代码沙箱化。
  • 支持 x86 的 2MB 或 4MB 的页大小)。
  • 修改 JOS 让内核支持进程内的线程。从查看 课堂上的 uthread 任务 去开始。实现调度器触发将是实现这个项目的一种方式。
  • 在 JOS 的内核中或文件系统中(实现多线程之后),使用细粒度锁或无锁并发。Linux 内核使用 读复制更新 去执行无需上锁的读取操作。通过在 JOS 中实现它来探索 RCU,并使用它去支持无锁读取的名称缓存。
  • 实现 外内核论文 中的想法。例如包过滤器。
  • 使 JOS 拥有软实时行为。用它来辨识一些应用程序时非常有用。
  • 使 JOS 运行在 64 位 CPU 上。这包括重设计虚拟内存让它使用 4 级页表。有关这方面的文档,请查看 参考页
  • 移植 JOS 到一个不同的微处理器。这个 osdev wiki 或许对你有帮助。
  • 为 JOS 系统增加一个“窗口”系统,包括图形驱动和鼠标。有关这方面的文档,请查看 参考页sqrt(x) 就是一个 JOS “窗口” 系统的示例。
  • 在 JOS 中实现 dune,以提供特权硬件指令给用户空间应用程序。
  • 写一个用户级调试器,添加类似跟踪的功能;硬件寄存器概要(即:Oprofile);调用跟踪等等。
  • 为(静态的)Linux 可运行程序做一个二进制仿真。

via: https://pdos.csail.mit.edu/6.828/2018/labs/lab7/

作者:csail.mit 选题:lujun9972 译者:qhwdw 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

这篇文章将帮助你了解 Linux 中 /etc/services 文件,包括它的内容,格式以及重要性。

Internet 守护程序(ineted)是 Linux 世界中的重要服务。它借助 /etc/services 文件来处理所有网络服务。在本文中,我们将向你介绍这个文件的内容,格式以及它对于 Linux 系统的意义。

/etc/services 文件包含网络服务和它们映射端口的列表。inetdxinetd 会查看这些细节,以便在数据包到达各自的端口或服务有需求时,它会调用特定的程序。

作为普通用户,你可以查看此文件,因为文件一般都是可读的。要编辑此文件,你需要有 root 权限。

$ ll /etc/services
-rw-r--r--. 1 root root 670293 Jun  7  2013 /etc/services

/etc/services 文件格式

service-name    port/protocol   [aliases..]  [#comment]

最后两个字段是可选的,因此用 [ ] 表示。

其中:

  • service-name 是网络服务的名称。例如 telnetftp 等。
  • port/protocol 是网络服务使用的端口(一个数值)和服务通信使用的协议(TCP/UDP)。
  • alias 是服务的别名。
  • comment 是你可以添加到服务的注释或说明。以 # 标记开头。

/etc/services 文件示例

# 每行描述一个服务,形式如下:
#
# service-name  port/protocol  [aliases ...]   [# comment]

tcpmux          1/tcp                           # TCP port service multiplexer
rje             5/tcp                           # Remote Job Entry
echo            7/udp
discard         9/udp           sink null

在这里,你可以看到可选的最后两个字段的用处。discard 服务的别名为 sinknull


via: https://kerneltalks.com/linux/understanding-etc-services-file-in-linux/

作者:kerneltalks 选题:lujun9972 译者:MjSeven 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

以前,我们介绍 Ubuntu 推出的 Snaps。Snaps 是由 Canonical 公司为 Ubuntu 开发的,并随后移植到其他的 Linux 发行版,如 Arch、Gentoo、Fedora 等等。由于一个 snap 包中含有软件的二进制文件和其所需的所有依赖和库,所以可以在无视软件版本、在任意 Linux 发行版上安装软件。和 Snaps 类似,还有一个名为 Flatpak 的工具。也许你已经知道,为不同的 Linux 发行版打包并分发应用是一件多么费时又复杂的工作,因为不同的 Linux 发行版的库不同,库的版本也不同。现在,Flatpak 作为分发桌面应用的新框架可以让开发者完全摆脱这些负担。开发者只需构建一个 Flatpak app 就可以在多种发行版上安装使用。这真是又酷又棒!

用户也完全不用担心库和依赖的问题了,所有的东西都和 app 打包在了一起。更重要的是 Flatpak app 们都自带沙箱,而且与宿主操作系统的其他部分隔离。对了,Flatpak 还有一个很棒的特性,它允许用户在同一个系统中安装同一应用的多个版本,例如 VLC 播放器的 2.1 版、2.2 版、2.3 版。这使开发者测试同一个软件的多个版本变得更加方便。

在本文中,我们将指导你如何在 GNU/Linux 中安装 Flatpak。

安装 Flatpak

Flatpak 可以在大多数的主流 Linux 发行版上安装使用,如 Arch Linux、Debian、Fedora、Gentoo、Red Hat、Linux Mint、openSUSE、Solus、Mageia 还有 Ubuntu。

在 Arch Linux 上,使用这一条命令来安装 Flatpak:

$ sudo pacman -S flatpak

对于 Debian 用户,Flatpak 被收录进 Stretch 或之后版本的默认软件源中。要安装 Flatpak,直接执行:

$ sudo apt install flatpak

对于 Fedora 用户,Flatpak 是发行版默认安装的软件。你可以直接跳过这一步。

如果因为某种原因没有安装的话,可以执行:

$ sudo dnf install flatpak

对于 RHEL 7 用户,安装 Flatpak 的命令为:

$ sudo yum install flatpak

如果你在使用 Linux Mint 18.3,那么 Flatpat 也随系统默认安装,所以跳过这一步。

在 openSUSE Tumbleweed 中,使用 Zypper 包管理来安装 Flatpak:

$ sudo zypper install flatpak

而 Ubuntu 需要添加下面的软件源再安装 Flatpak,命令如下:

$ sudo add-apt-repository ppa:alexlarsson/flatpak
$ sudo apt update
$ sudo apt install flatpak

Gnome 提供了一个 Flatpak 插件,安装它就可以使用图形界面来安装 Flatpak app 了。插件的安装命令为:

$ sudo apt install gnome-software-plugin-flatpak

如果你是用发行版没有在上述的说明里,请你参考官方安装指南

开始使用 Flatpak

有不少流行应用都支持 Flatpak 安装,如 Gimp、Kdenlive、Steam、Spotify、Visual Sudio Code 等。

下面让我来一起学习 flatpak 的基本操作命令。

首先,我们需要添加远程仓库。

添加软件仓库

添加 Flathub 仓库:

Flathub 是一个包含了几乎所有 flatpak 应用的仓库。运行这条命令来启用它:

$ sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo

对于流行应用来说,Flathub 已经可以满足需求。如果你想试试 GNOME 应用的话,可以添加 GNOME 的仓库。

添加 GNOME 仓库:

GNOME 仓库包括了所有的 GNOME 核心应用,它提供了两种版本: 稳定版 stable 每日构建版 nightly

使用下面的命令来添加 GNOME 稳定版仓库:

$ wget https://sdk.gnome.org/keys/gnome-sdk.gpg
$ sudo flatpak remote-add --gpg-import=gnome-sdk.gpg --if-not-exists gnome-apps https://sdk.gnome.org/repo-apps/

需要注意的是,GNOME 稳定版仓库中的应用需要 3.20 版本的 org.gnome.Platform 运行时环境

安装稳定版运行时环境,请执行:

$ sudo flatpak remote-add --gpg-import=gnome-sdk.gpg gnome https://sdk.gnome.org/repo/

如果想使用每日构建版的 GNOME 仓库,使用如下的命令:

$ wget https://sdk.gnome.org/nightly/keys/nightly.gpg
$ sudo flatpak remote-add --gpg-import=nightly.gpg --if-not-exists gnome-nightly-apps https://sdk.gnome.org/nightly/repo-apps/

同样,每日构建版的 GNOME 仓库也需要 org.gnome.Platform 运行时环境的每日构建版本

执行下面的命令安装每日构建版的运行时环境:

$ sudo flatpak remote-add --gpg-import=nightly.gpg gnome-nightly https://sdk.gnome.org/nightly/repo/

查看软件仓库

要查看已经添加的软件仓库,执行下面的命令:

$ flatpak remotes
Name Options
flathub system
gnome system
gnome-apps system
gnome-nightly system
gnome-nightly-apps system

如你所见,上述命令会列出你添加到系统中的软件仓库。此外,执行结果还表明了软件仓库的配置是 用户级 per-user 还是 系统级 system-wide

删除软件仓库

要删除软件仓库,例如 flathub,用这条命令:

$ sudo flatpak remote-delete flathub

这里的 flathub 是软件仓库的名字。

安装 Flatpak 应用

这一节,我们将学习如何安装 flatpak 应用。

要安装一个应用,只要一条命令就能完成:

$ sudo flatpak install flathub com.spotify.Client

所有的稳定版 GNOME 软件仓库中的应用,都使用“stable”作为版本名。

例如,想从稳定版 GNOME 软件仓库中安装稳定版 Evince,就执行:

$ sudo flatpak install gnome-apps org.gnome.Evince stable

所有的每日构建版 GNOME 仓库中的应用,都使用“master”作为版本名。

例如,要从每日构建版 GNOME 软件仓库中安装 gedit 的每次构建版本,就执行:

$ sudo flatpak install gnome-nightly-apps org.gnome.gedit master

如果不希望应用安装在 系统级 system-wide ,而只安装在 用户级 per-user ,那么你可以这样安装软件:

$ flatpak install --user <name-of-app>

所有的应用都会被存储在 $HOME/.var/app/ 目录下.

$ ls $HOME/.var/app/
com.spotify.Client

执行 Flatpak 应用

你可以直接使用 应用启动器 application launcher 来运行已安装的 Flatpak 应用。如果你想从命令行启动的话,以 Spotify 为例,执行下面的命令:

$ flatpak run com.spotify.Client

列出已安装的 Flatpak 应用

要查看已安装的应用程序和运行时环境,执行:

$ flatpak list

想只查看已安装的应用,那就用这条命令:

$ flatpak list --app

如果想查询已添加的软件仓库中的可安装程序和可安装的运行时环境,使用命令:

$ flatpak remote-ls

只列出可安装的应用程序的命令是:

$ flatpak remote-ls --app

查询指定远程仓库中的所有可安装的应用程序和运行时环境,这里以 gnome-apps 为例,执行命令:

$ flatpak remote-ls gnome-apps

只列出可安装的应用程序,这里以 flathub 为例:

$ flatpak remote-ls flathub --app

更新应用程序

更新所有的 Flatpak 应用程序,执行:

$ flatpak update

更新指定的 Flatpak 应用程序,执行:

$ flatpak update com.spotify.Client

获取应用详情

执行下面的命令来查看已安装应用程序的详细信息:

$ flatpak info io.github.mmstick.FontFinder

输出样例:

Ref: app/io.github.mmstick.FontFinder/x86_64/stable
ID: io.github.mmstick.FontFinder
Arch: x86_64
Branch: stable
Origin: flathub
Date: 2018-04-11 15:10:31 +0000
Subject: Workaround appstream issues (391ef7f5)
Commit: 07164e84148c9fc8b0a2a263c8a468a5355b89061b43e32d95008fc5dc4988f4
Parent: dbff9150fce9fdfbc53d27e82965010805f16491ec7aa1aa76bf24ec1882d683
Location: /var/lib/flatpak/app/io.github.mmstick.FontFinder/x86_64/stable/07164e84148c9fc8b0a2a263c8a468a5355b89061b43e32d95008fc5dc4988f4
Installed size: 2.5 MB
Runtime: org.gnome.Platform/x86_64/3.28

删除应用程序

要删除一个 Flatpak 应用程序,这里以 spotify 为例,执行:

$ sudo flatpak uninstall com.spotify.Client

如果你需要更多信息,可以参考 Flatpak 的帮助。

$ flatpak --help

到此,希望你对 Flatpak 有了一些基础了解。

如果你觉得这篇指南有些帮助,请在你的社交媒体上分享它来支持我们。

稍后还有更多精彩内容,敬请期待~


via: https://www.ostechnix.com/flatpak-new-framework-desktop-applications-linux/

作者:SK 选题:lujun9972 译者:wwhio 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

OK01 课程讲解了树莓派如何入门,以及在树莓派上如何启用靠近 RCA 和 USB 端口的 OK 或 ACT 的 LED 指示灯。这个指示灯最初是为了指示 OK 状态的,但它在第二版的树莓派上被改名为 ACT。

1、入门

我们假设你已经访问了下载页面,并且已经获得了必需的 GNU 工具链。也下载了一个称为操作系统模板的文件。请下载这个文件并在一个新目录中解开它。

2、开始

现在,你已经展开了这个模板文件,在 source 目录中创建一个名为 main.s 的文件。这个文件包含了这个操作系统的代码。具体来看,这个文件夹的结构应该像下面这样:

build/
   (empty)
source/
   main.s
kernel.ld
LICENSE
Makefile

用文本编辑器打开 main.s 文件,这样我们就可以输入汇编代码了。树莓派使用了称为 ARMv6 的汇编代码变体,这就是我们即将要写的汇编代码类型。

扩展名为 .s 的文件一般是汇编代码,需要记住的是,在这里它是 ARMv6 的汇编代码。

首先,我们复制下面的这些命令。

.section .init
.globl _start
_start:

实际上,上面这些指令并没有在树莓派上做任何事情,它们是提供给汇编器的指令。汇编器是一个转换程序,它将我们能够理解的汇编代码转换成树莓派能够理解的机器代码。在汇编代码中,每个行都是一个新的命令。上面的第一行告诉汇编器 1 在哪里放我们的代码。我们提供的模板中将它放到一个名为 .init 的节中的原因是,它是输出的起始点。这很重要,因为我们希望确保我们能够控制哪个代码首先运行。如果不这样做,首先运行的代码将是按字母顺序排在前面的代码!.section 命令简单地告诉汇编器,哪个节中放置代码,从这个点开始,直到下一个 .section 或文件结束为止。

在汇编代码中,你可以跳行、在命令前或后放置空格去提升可读性。

接下来两行是停止一个警告消息,它们并不重要。 2

3、第一行代码

现在,我们正式开始写代码。计算机执行汇编代码时,是简单地一行一行按顺序执行每个指令,除非明确告诉它不这样做。每个指令都是开始于一个新行。

复制下列指令。

ldr r0,=0x20200000
ldr reg,=val 将数字 val 加载到名为 reg 的寄存器中。

那是我们的第一个命令。它告诉处理器将数字 0x20200000 保存到寄存器 r0 中。在这里我需要去回答两个问题, 寄存器 register 是什么?0x20200000 是一个什么样的数字?

寄存器在处理器中就是一个极小的内存块,它是处理器保存正在处理的数字的地方。处理器中有很多寄存器,很多都有专门的用途,我们在后面会一一接触到它们。最重要的有十三个(命名为 r0r1r2、…、r9r10r11r12),它们被称为通用寄存器,你可以使用它们做任何计算。由于是写我们的第一行代码,我们在示例中使用了 r0,当然你可以使用它们中的任何一个。只要后面始终如一就没有问题。

树莓派上的一个单独的寄存器能够保存任何介于 04,294,967,295(含)之间的任意整数,它可能看起来像一个很大的内存,实际上它仅有 32 个二进制比特。

0x20200000 确实是一个数字。只不过它是以十六进制表示的。下面的内容详细解释了十六进制的相关信息:

延伸阅读:十六进制解释

十六进制是另一种表示数字的方式。你或许只知道十进制的数字表示方法,十进制共有十个数字:0123456789。十六进制共有十六个数字:0123456789abcdef

你可能还记得十进制是如何用位制来表示的。即最右侧的数字是个位,紧接着的左边一位是十位,再接着的左边一位是百位,依此类推。也就是说,它的值是 100 × 百位的数字,再加上 10 × 十位的数字,再加上 1 × 个位的数字。

567 is 5 hundreds, 6 tens and 7 units.

从数学的角度来看,我们可以发现规律,最右侧的数字是 10 0 = 1s,紧接着的左边一位是 10 1 = 10s,再接着是 10 2 = 100s,依此类推。我们设定在系统中,0 是最低位,紧接着是 1,依此类推。但如果我们使用一个不同于 10 的数字为幂底会是什么样呢?我们在系统中使用的十六进制就是这样的一个数字。

567 is 5x10^2+6x10^1+7x10^0

567 = 5x10^2+6x10^1+7x10^0 = 2x16^2+3x16^1+7x16^0

上面的数学等式表明,十进制的数字 567 等于十六进制的数字 237。通常我们需要在系统中明确它们,我们使用下标 10 表示它是十进制数字,用下标 16 表示它是十六进制数字。由于在汇编代码中写上下标的小数字很困难,因此我们使用 0x 来表示它是一个十六进制的数字,因此 0x237 的意思就是 237 16

那么,后面的 abcdef 又是什么呢?好问题!在十六进制中为了能够写每个数字,我们就需要额外的东西。例如 9 16 = 9×16 0 = 9 10 ,但是 10 16 = 1×16 1 + 1×16 0 = 16 10 。因此,如果我们只使用 0、1、2、3、4、5、6、7、8 和 9,我们就无法写出 10 10 、11 10 、12 10 、13 10 、14 10 、15 10 。因此我们引入了 6 个新的数字,这样 a 16 = 10 10 、b 16 = 11 10 、c 16 = 12 10 、d 16 = 13 10 、e 16 = 14 10 、f 16 = 15 10

所以,我们就有了另一种写数字的方式。但是我们为什么要这么麻烦呢?好问题!由于计算机总是工作在二进制中,事实证明,十六进制是非常有用的,因为每个十六进制数字正好是四个二进制数字的长度。这种方法还有另外一个好处,那就是许多计算机的数字都是十六进制的整数倍,而不是十进制的整数倍。比如,我在上面的汇编代码中使用的一个数字 20200000 16 。如果我们用十进制来写,它就是一个不太好记住的数字 538968064 10

我们可以用下面的简单方法将十进制转换成十六进制:

Conversion example

  1. 我们以十进制数字 567 为例来说明。
  2. 将十进制数字 567 除以 16 并计算其余数。例如 567 ÷ 16 = 35 余数为 7。
  3. 在十六进制中余数就是答案中的最后一位数字,在我们的例子中它是 7。
  4. 重复第 2 步和第 3 步,直到除法结果的整数部分为 0。例如 35 ÷ 16 = 2 余数为 3,因此 3 就是答案中的下一位。2 ÷ 16 = 0 余数为 2,因此 2 就是答案的接下来一位。
  5. 一旦除法结果的整数部分为 0 就结束了。答案就是反序的余数,因此 567 10 = 237 16

转换十六进制数字为十进制,也很容易,将数字展开即可,因此 237 16 = 2×16 2 + 3×16 1 +7 ×16 0 = 2×256 + 3×16 + 7×1 = 512 + 48 + 7 = 567。

因此,我们所写的第一个汇编命令是将数字 20200000 16 加载到寄存器 r0 中。那个命令看起来似乎没有什么用,但事实并非如此。在计算机中,有大量的内存块和设备。为了能够访问它们,我们给每个内存块和设备指定了一个地址。就像邮政地址或网站地址一样,它用于标识我们想去访问的内存块或设备的位置。计算机中的地址就是一串数字,因此上面的数字 20200000 16 就是 GPIO 控制器的地址。这个地址是由制造商的设计所决定的,他们也可以使用其它地址(只要不与其它的冲突即可)。我之所以知道这个地址是 GPIO 控制器的地址是因为我看了它的手册, 3 地址的使用没有专门的规范(除了它们都是以十六进制表示的大数以外)。

4、启用输出

A diagram showing key parts of the GPIO controller.

阅读了手册可以得知,我们需要给 GPIO 控制器发送两个消息。我们必须用它的语言告诉它,如果我们这样做了,它将非常乐意实现我们的意图,去打开 OK 的 LED 指示灯。幸运的是,它是一个非常简单的芯片,为了让它能够理解我们要做什么,只需要给它设定几个数字即可。

mov r1,#1
lsl r1,#18
str r1,[r0,#4]

mov reg,#val 将数字 val 放到名为 reg 的寄存器中。

lsl reg,#val 将寄存器 reg 中的二进制操作数左移 val 位。

str reg,[dest,#val] 将寄存器 reg 中的数字保存到地址 dest + val 上。

这些命令的作用是在 GPIO 的第 16 号插针上启用输出。首先我们在寄存器 r1 中获取一个必需的值,接着将这个值发送到 GPIO 控制器。因此,前两个命令是尝试取值到寄存器 r1 中,我们可以像前面一样使用另一个命令 ldr 来实现,但 lsl 命令对我们后面能够设置任何给定的 GPIO 针比较有用,因此从一个公式中推导出值要比直接写入来好一些。表示 OK 的 LED 灯是直接连线到 GPIO 的第 16 号针脚上的,因此我们需要发送一个命令去启用第 16 号针脚。

寄存器 r1 中的值是启用 LED 针所需要的。第一行命令将数字 1 10 放到 r1 中。在这个操作中 mov 命令要比 ldr 命令快很多,因为它不需要与内存交互,而 ldr 命令是将需要的值从内存中加载到寄存器中。尽管如此,mov 命令仅能用于加载某些值。 4 在 ARM 汇编代码中,基本上每个指令都使用一个三字母代码表示。它们被称为助记词,用于表示操作的用途。mov 是 “move” 的简写,而 ldr 是 “load register” 的简写。mov 是将第二个参数 #1 移动到前面的 r1 寄存器中。一般情况下,# 肯定是表示一个数字,但我们已经看到了不符合这种情况的一个反例。

第二个指令是 lsl(逻辑左移)。它的意思是将第一个参数的二进制操作数向左移第二个参数所表示的位数。在这个案例中,将 1 10 (即 1 2 )向左移 18 位(将它变成 1000000000000000000 2=262144 10 )。

如果你不熟悉二进制表示法,可以看下面的内容:

延伸阅读: 二进制解释

与十六进制一样,二进制是写数字的另一种方法。在二进制中只有两个数字,即 01。它在计算机中非常有用,因为我们可以用电路来实现它,即电流能够通过电路表示为 1,而电流不能通过电路表示为 0。这就是计算机能够完成真实工作和做数学运算的原理。尽管二进制只有两个数字,但它却能够表示任何一个数字,只是写起来有点长而已。

567 in decimal = 1000110111 in binary

这个图片展示了 567 10 的二进制表示是 1000110111 2 。我们使用下标 2 来表示这个数字是用二进制写的。

我们在汇编代码中大量使用二进制的其中一个巧合之处是,数字可以很容易地被 2 的幂(即 124816)乘或除。通常乘法和除法都是非常难的,而在某些特殊情况下却变得非常容易,所以二进制非常重要。

13*4 = 52, 1101*100=110100

将一个二进制数字左移 n 位就相当于将这个数字乘以 2 n。因此,如果我们想将一个数乘以 4,我们只需要将这个数字左移 2 位。如果我们想将它乘以 256,我们只需要将它左移 8 位。如果我们想将一个数乘以 12 这样的数字,我们可以有一个替代做法,就是先将这个数乘以 8,然后再将那个数乘以 4,最后将两次相乘的结果相加即可得到最终结果(N × 12 = N × (8 + 4) = N × 8 + N × 4)。

53/16 = 3, 110100/10000=11

右移一个二进制数 n 位就相当于这个数除以 2 n 。在右移操作中,除法的余数位将被丢弃。不幸的是,如果对一个不能被 2 的幂次方除尽的二进制数字做除法是非常难的,这将在 课程 9 Screen04 中讲到。

Binary Terminology

这个图展示了二进制常用的术语。一个 比特 bit 就是一个单独的二进制位。一个“ 半字节 nibble “ 是 4 个二进制位。一个 字节 byte 是 2 个半字节,也就是 8 个比特。 半字 half 是指一个字长度的一半,这里是 2 个字节。 word 是指处理器上寄存器的大小,因此,树莓派的字长是 4 字节。按惯例,将一个字最高有效位标识为 31,而将最低有效位标识为 0。顶部或最高位表示最高有效位,而底部或最低位表示最低有效位。一个 kilobyte(KB)就是 1000 字节,一个 megabyte 就是 1000 KB。这样表示会导致一些困惑,到底应该是 1000 还是 1024(二进制中的整数)。鉴于这种情况,新的国际标准规定,一个 KB 等于 1000 字节,而一个 Kibibyte(KiB)是 1024 字节。一个 Kb 是 1000 比特,而一个 Kib 是 1024 比特。

树莓派默认采用小端法,也就是说,从你刚才写的地址上加载一个字节时,是从一个字的低位字节开始加载的。

再强调一次,我们只有去阅读手册才能知道我们所需要的值。手册上说,GPIO 控制器中有一个 24 字节的集合,由它来决定 GPIO 针脚的设置。第一个 4 字节与前 10 个 GPIO 针脚有关,第二个 4 字节与接下来的 10 个针脚有关,依此类推。总共有 54 个 GPIO 针脚,因此,我们需要 6 个 4 字节的一个集合,总共是 24 个字节。在每个 4 字节中,每 3 个比特与一个特定的 GPIO 针脚有关。我们想去启用的是第 16 号 GPIO 针脚,因此我们需要去设置第二组 4 字节,因为第二组的 4 字节用于处理 GPIO 针脚的第 10-19 号,而我们需要第 6 组 3 比特,它在上面的代码中的编号是 18(6×3)。

最后的 str(“store register”)命令去保存第一个参数中的值,将寄存器 r1 中的值保存到后面的表达式计算出来的地址上。这个表达式可以是一个寄存器,在上面的例子中是 r0,我们知道 r0 中保存了 GPIO 控制器的地址,而另一个值是加到它上面的,在这个例子中是 #4。它的意思是将 GPIO 控制器地址加上 4 得到一个新的地址,并将寄存器 r1 中的值写到那个地址上。那个地址就是我们前面提到的第二组 4 字节的位置,因此,我们发送我们的第一个消息到 GPIO 控制器上,告诉它准备启用 GPIO 第 16 号针脚的输出。

5、生命的信号

现在,LED 已经做好了打开准备,我们还需要实际去打开它。意味着需要给 GPIO 控制器发送一个消息去关闭 16 号针脚。是的,你没有看错,就是要发送一个关闭的消息。芯片制造商认为,在 GPIO 针脚关闭时打开 LED 更有意义。 5 硬件工程师经常做这种反常理的决策,似乎是为了让操作系统开发者保持警觉。可以认为是给自己的一个警告。

mov r1,#1
lsl r1,#16
str r1,[r0,#40]

希望你能够认识上面全部的命令,先不要管它的值。第一个命令和前面一样,是将值 1 推入到寄存器 r1 中。第二个命令是将二进制的 1 左移 16 位。由于我们是希望关闭 GPIO 的 16 号针脚,我们需要在下一个消息中将第 16 比特设置为 1(想设置其它针脚只需要改变相应的比特位即可)。最后,我们写这个值到 GPIO 控制器地址加上 40 10 的地址上,这将使那个针脚关闭(加上 28 将打开针脚)。

6、永远幸福快乐

似乎我们现在就可以结束了,但不幸的是,处理器并不知道我们做了什么。事实上,处理器只要通电,它就永不停止地运转。因此,我们需要给它一个任务,让它一直运转下去,否则,树莓派将进入休眠(本示例中不会,LED 灯会一直亮着)。

loop$:
b loop$

name: 下一行的名字。

b label 下一行将去标签 label 处运行。

第一行不是一个命令,而是一个标签。它给下一行命名为 loop$,这意味着我们能够通过名字来指向到该行。这就称为一个标签。当代码被转换成二进制后,标签将被丢弃,但这对我们通过名字而不是数字(地址)找到行比较有用。按惯例,我们使用一个 ​$ 表示这个标签只对这个代码块中的代码起作用,让其它人知道,它不对整个程序起作用。b(“branch”)命令将去运行指定的标签中的命令,而不是去运行它后面的下一个命令。因此,下一行将再次去运行这个 b 命令,这将导致永远循环下去。因此处理器将进入一个无限循环中,直到它安全关闭为止。

代码块结尾的一个空行是有意这样写的。GNU 工具链要求所有的汇编代码文件都是以空行结束的,因此,这就可以你确实是要结束了,并且文件没有被截断。如果你不这样处理,在汇编器运行时,你将收到烦人的警告。

7、树莓派上场

由于我们已经写完了代码,现在,我们可以将它上传到树莓派中了。在你的计算机上打开一个终端,改变当前工作目录为 source 文件夹的父级目录。输入 make 然后回车。如果报错,请参考排错章节。如果没有报错,你将生成三个文件。 kernel.img 是你的编译后的操作系统镜像。kernel.list 是你写的汇编代码的一个清单,它实际上是生成的。这在将来检查程序是否正确时非常有用。kernel.map 文件包含所有标签结束位置的一个映射,这对于跟踪值非常有用。

为安装你的操作系统,需要先有一个已经安装了树莓派操作系统的 SD 卡。如果你浏览 SD 卡中的文件,你应该能看到一个名为 kernel.img 的文件。将这个文件重命名为其它名字,比如 kernel_linux.img。然后,复制你编译的 kernel.img 文件到 SD 卡中原来的位置,这将用你的操作系统镜像文件替换现在的树莓派操作系统镜像。想切换回来时,只需要简单地删除你自己的 kernel.img 文件,然后将前面重命名的文件改回 kernel.img 即可。我发现,保留一个原始的树莓派操作系统的备份是非常有用的,万一你要用到它呢。

将这个 SD 卡插入到树莓派,并打开它的电源。这个 OK 的 LED 灯将亮起来。如果不是这样,请查看故障排除页面。如果一切如愿,恭喜你,你已经写出了你的第一个操作系统。课程 2 OK02 将指导你让 LED 灯闪烁和关闭闪烁。


  1. 是的,我说错了,它告诉的是链接器,它是另一个程序,用于将汇编器转换过的几个代码文件链接到一起。直接说是汇编器也没有大问题。
  2. 其实它们对你很重要。由于 GNU 工具链主要用于开发操作系统,它要求入口点必须是名为 _start 的地方。由于我们是开发一个操作系统,无论什么时候,它总是从 _start 开时的,而我们可以使用 .section .init 命令去设置它。因此,如果我们没有告诉它入口点在哪里,就会使工具链困惑而产生警告消息。所以,我们先定义一个名为 _start 的符号,它是所有人可见的(全局的),紧接着在下一行生成符号 _start 的地址。我们很快就讲到这个地址了。
  3. 本教程的设计减少了你阅读树莓派开发手册的难度,但是,如果你必须要阅读它,你可以在这里 SoC-Peripherals.pdf 找到它。由于添加了混淆,手册中 GPIO 使用了不同的地址系统。我们的操作系统中的地址 0x20200000 对应到手册中是 0x7E200000。
  4. mov 能够加载的值只有前 8 位是 1 的二进制表示的值。换句话说就是一个 0 后面紧跟着 8 个 10
  5. 一个很友好的硬件工程师是这样向我解释这个问题的:

原因是现在的芯片都是用一种称为 CMOS 的技术来制成的,它是互补金属氧化物半导体的简称。互补的意思是每个信号都连接到两个晶体管上,一个是使用 N 型半导体的材料制成,它用于将电压拉低,而另一个使用 P 型半导体材料制成,它用于将电压升高。在任何时刻,仅有一个半导体是打开的,否则将会短路。P 型材料的导电性能不如 N 型材料。这意味着三倍大的 P 型半导体材料才能提供与 N 型半导体材料相同的电流。这就是为什么 LED 总是通过降低为低电压来打开它,因为 N 型半导体拉低电压比 P 型半导体拉高电压的性能更强。

还有一个原因。早在上世纪七十年代,芯片完全是由 N 型材料制成的(NMOS),P 型材料部分使用了一个电阻来代替。这意味着当信号为低电压时,即便它什么事都没有做,芯片仍然在消耗能量(并发热)。你的电话装在口袋里什么事都不做,它仍然会发热并消耗你的电池电量,这不是好的设计。因此,信号设计成 “活动时低”,而不活动时为高电压,这样就不会消耗能源了。虽然我们现在已经不使用 NMOS 了,但由于 N 型材料的低电压信号比 P 型材料的高电压信号要快,所以仍然使用了这种设计。通常在一个 “活动时低” 信号名字上方会有一个条型标记,或者写作 SIGNAL_n/SIGNAL。但是即便这样,仍然很让人困惑,那怕是硬件工程师,也不可避免这种困惑!


via: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok01.html

作者:Robert Mullins 选题:lujun9972 译者:qhwdw 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

如果你正在寻找一个 Evernote 和 Google Keep 的替代品,那么 Turtl 是一个可靠的记笔记工具。

我认识的每个人都会记笔记,许多人使用在线笔记应用,如 Evernote、Simplenote 或 Google Keep。这些都是很好的工具,但你不得不担忧信息的安全性和隐私性 —— 特别是考虑到 Evernote 2016 年的隐私策略变更。如果你想要更好地控制笔记和数据,你需要转向开源工具。

无论你离开 Evernote 的原因是什么,都有开源替代品。让我们来看看其中一个选择:Turtl。

入门

Turtl 背后的开发人员希望你将其视为“具有绝对隐私的 Evernote”。说实话,我不能保证 Turtl 提供的隐私级别,但它是一个非常好的笔记工具。

要开始使用 Turtl,下载适用于 Linux、Mac OS 或 Windows 的桌面客户端,或者获取它的 Android 应用。安装它,然后启动客户端或应用。系统会要求你输入用户名和密码。Turtl 使用密码来生成加密密钥,根据开发人员的说法,加密密钥会在将笔记存储在设备或服务器上之前对其进行加密。

使用 Turtl

你可以使用 Turtl 创建以下类型的笔记:

  • 密码
  • 档案
  • 图片
  • 书签
  • 文字笔记

无论你选择何种类型的笔记,你都可以在类似的窗口中创建:

Create new text note with Turtl

在 Turtl 中创建新笔记

添加笔记标题、文字并(如果你正在创建文件或图像笔记)附加文件或图像等信息。然后单击“保存”。

你可以通过 Markdown 为你的笔记添加格式。因为没有工具栏快捷方式,所以你需要手动添加格式。

如果你需要整理笔记,可以将它们添加到“白板”中。白板就像 Evernote 中的笔记本。要创建新的白板,请单击 “Board” 选项卡,然后单击“创建”按钮。输入白板的标题,然后单击“创建”。

Create new board in Turtl

在 Turtl 中创建新的白板

要向白板中添加笔记,请创建或编辑笔记,然后单击笔记底部的“此笔记不在任何白板”的链接。选择一个或多个白板,然后单击“完成”。

要为笔记添加标记,请单击记事本底部的“标记”图标,输入一个或多个以逗号分隔的关键字,然后单击“完成”。

跨设备同步你的笔记

例如,如果你在多台计算机和 Android 设备上使用 Turtl,Turtl 会在你上线时同步你的笔记。但是,我在同步时遇到了一个小问题:我手机上创建的笔记经常不会同步到我的笔记本电脑上。我尝试通过单击窗口左上角的图标手动同步,然后单击立即同步,但这并不总是有效。我发现偶尔需要单击“设置”图标,然后单击“清除本地数据”。然后我需要重新登录 Turtl,但所有数据都能正确同步了。

一个疑问和一些问题

当我开始使用 Turtl 时,我被一个疑问所困扰:我的笔记保存在哪里?事实证明,Turtl 背后的开发人员位于美国,这也是他们服务器的所在地。虽然 Turtl 使用的加密非常强大并且你的笔记在服务器上加密,但我偏执地认为你不应该在 Turtl 中保存任何敏感内容(或在任何类似的在线笔记中)。

Turtl 以平铺视图显示笔记,让人想起 Google Keep:

Notes in Turtl

Turtl 中的一系列笔记

无法在桌面或 Android 应用上将其更改为列表视图。这对我来说不是问题,但我听说有些人因为它没有列表视图而不喜欢 Turtl。

说到 Android 应用,它并不差。但是,它没有与 Android 共享菜单集成。如果你想把在其他应用中看到或阅读的内容添加到 Turtl 笔记中,则需要手动复制并粘贴。

我已经在我的 Linux 笔记本,运行 GalliumOS 的 Chromebook,还有一台 Android 手机上使用 Turtl 几个月了。对所有这些设备来说这都是一种非常无缝的体验。虽然它不是我最喜欢的开源笔记工具,但 Turtl 做得非常好。试试看它,它可能是你正在寻找的简单的笔记工具。


via: https://opensource.com/article/17/12/using-turtl-open-source-alternative-evernote

作者:Scott Nesbitt 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

一篇涵盖了在 Ubuntu 和其他 Linux 发行版中使用 PPA 的几乎所有问题的深入的文章。

如果你一直在使用 Ubuntu 或基于 Ubuntu 的其他 Linux 发行版,例如 Linux Mint、Linux Lite、Zorin OS 等,你可能会遇到以下三种神奇的命令:

sudo add-apt-repository ppa:dr-akulavich/lighttable
sudo apt-get update
sudo apt-get install lighttable-installer

许多网站推荐使用类似于以上几行的形式 在 Ubuntu 中安装应用程序。这就是所谓的使用 PPA 安装应用程序。

但什么是 PPA?为什么要用它?使用 PPA 安全吗?如何正确使用 PPA?如何删除 PPA?

我将在这个详细的指南中回答上述所有问题。即使你已经了解了一些关于 PPA 的事情,我相信这篇文章仍然会让你了解这方面的更多知识。

请注意我正在使用 Ubuntu 撰写本文。因此,我几乎在各个地方都使用了 Ubuntu 这个术语,但文中的说明和步骤也适用于其他基于 Debian/Ubuntu 的发行版。

什么是 PPA?为什么要使用 PPA?

Everything you need to know about PPA in Ubuntu Linux

PPA 表示 个人软件包存档 Personal Package Archive

这样说容易理解吗?可能不是很容易。

在了解 PPA 之前,你应该了解 Linux 中软件仓库的概念。关于软件仓库,在这里我不会详述。

软件仓库和包管理的概念

软件仓库是一组文件,其中包含各种软件及其版本的信息,以及校验和等其他一些详细信息。每个版本的 Ubuntu 都有自己的四个官方软件仓库:

  • Main - Canonical 支持的自由开源软件。
  • Universe - 社区维护的自由开源软件。
  • Restricted - 设备的专有驱动程序。
  • Multiverse - 受版权或法律问题限制的软件。

你可以在 这里 看到所有版本的 Ubuntu 的软件仓库。你可以浏览并转到各个仓库。例如,可以在 这里 找到 Ubuntu 16.04 的主存储库(Main)。

所以,PPA 基本上是一个包含软件信息的网址。那你的系统又是如何知道这些仓库的位置的呢?

这些信息存储在 /etc/apt 目录中的 sources.list 文件中。如果查看此文件的内容,你就会看到里面有软件仓库的网址。# 开头的行将被忽略。

这样的话,当你运行 sudo apt update 命令时,你的系统将使用 APT 工具 来检查软件仓库并将软件及其版本信息存储在缓存中。当你使用 sudo apt install package_name 命令时,它通过该信息从实际存储软件的网址获取该软件包。

如果软件仓库中没有关于某个包的信息,你将看到如下错误:

E: Unable to locate package

此时,建议阅读我的 apt 命令使用指南 一文,这将帮你更好地理解 aptupdate 等命令。

以上是关于软件仓库的内容。但什么是 PPA?PPA 和软件仓库又有什么关联呢?

为什么要用 PPA?

如你所见,Ubuntu 对系统中的软件进行管理,更重要的是控制你在系统上获得哪个版本的软件。但想象一下开发人员发布了软件的新版本的情况。

Ubuntu 不会立即提供该新版本的软件。需要一个步骤来检查此新版本的软件是否与系统兼容,从而可以确保系统的稳定性。

但这也意味着它需要经过几周才能在 Ubuntu 上可用,在某些情况下,这可能需要几个月的时间。不是每个人都想等待那么长时间才能获得他们最喜欢的软件的新版本。

类似地,假设有人开发了一款软件,并希望 Ubuntu 将该软件包含在官方软件仓库中。在 Ubuntu 做出决定并将其包含在官方存软件仓库之前,还需要几个月的时间。

另一种情况是在 beta 测试阶段。即使官方软件仓库中提供了稳定版本的软件,软件开发人员也可能希望某些终端用户测试他们即将发布的版本。他们是如何使终端用户对即将发布的版本进行 beta 测试的呢?

通过 PPA!

如何使用 PPA?PPA 是怎样工作的?

正如我已经告诉过你的那样,PPA 代表 个人软件包存档 Personal Package Archive 。在这里注意 “个人” 这个词,它暗示了这是开发人员独有的东西,并没有得到分发的正式许可。

Ubuntu 提供了一个名为 Launchpad 的平台,使软件开发人员能够创建自己的软件仓库。终端用户,也就是你,可以将 PPA 仓库添加到 sources.list 文件中,当你更新系统时,你的系统会知道这个新软件的可用性,然后你可以使用标准的 sudo apt install 命令安装它。

sudo add-apt-repository ppa:dr-akulavich/lighttable
sudo apt-get update
sudo apt-get install lighttable-installer

概括一下上面三个命令:

  • sudo add-apt-repository <PPA_info> <- 此命令将 PPA 仓库添加到列表中。
  • sudo apt-get update <- 此命令更新可以在当前系统上安装的软件包列表。
  • sudo apt-get install <package_in_PPA> <- 此命令安装软件包。

你会发现使用 sudo apt update 命令非常重要,否则你的系统将无法知道新软件包何时可用。

现在让我们更详细地看一下第一个命令。

sudo add-apt-repository ppa:dr-akulavich/lighttable

你会注意到此命令没有软件仓库的 URL。这是因为该工具被设计成将 URL 信息抽象之后再展示给你。

小小注意一下:如果你添加的是 ppa:dr-akulavich/lighttable,你会得到 Light Table。但是如果你添加 ppa:dr-akulavich,你将得到 “上层软件仓库” 中的所有仓库或软件包。它是按层级划分的。

基本上,当您使用 add-apt-repository 添加 PPA 时,它将执行与手动运行这些命令相同的操作:

deb http://ppa.launchpad.net/dr-akulavich/lighttable/ubuntu YOUR_UBUNTU_VERSION_HERE main
deb-src http://ppa.launchpad.net/dr-akulavich/lighttable/ubuntu YOUR_UBUNTU_VERSION_HERE main

以上两行是将任何软件仓库添加到你系统的 sources.list 文件的传统方法。但 PPA 会自动为你完成这些工作,无需考虑确切的软件仓库 URL 和操作系统版本。

此处不那么重要的一点是,当你使用 PPA 时,它不会更改原始的 sources.list 文件。相反,它在 /etc/apt/sources.d 目录中创建了两个文件,一个 .list 文件和一个带有 .save 后缀的备份文件。

Using a PPA in Ubuntu

PPA 创建了单独的 sources.list 文件

带有后缀 .list 的文件含有添加软件仓库的信息的命令。

PPA add repository information

一个 PPA 的 source.list 文件的内容

这是一种安全措施,可以确保添加的 PPA 不会和原始的 sources.list 文件弄混,它还有助于移除 PPA。

为什么使用 PPA?为何不用 DEB 包

你可能会问为什么要使用 PPA,PPA 需要通过命令行使用,而不是每个人都喜欢用命令行。为什么不直接分发可以图形方式安装的 DEB 包呢?

答案在于更新的过程。如果使用 DEB 包安装软件,将无法保证在运行 sudo apt updatesudo apt upgrade 命令时,已安装的软件会被更新为较新的版本。

这是因为 apt 的升级过程依赖于 sources.list 文件。如果文件中没有相应的软件条目,则不会通过标准软件更新程序获得更新。

那么这是否意味着使用 DEB 安装的软件永远不会得到更新?不是的。这取决于 DEB 包的创建方式。

一些开发人员会自动在 sources.list 中添加一个条目,这样软件就可以像普通软件一样更新。谷歌 Chrome 浏览器就是这样一个例子。

某些软件会在运行时通知你有新版本可用。你必须下载新的 DEB 包并再次运行,来将当前软件更新为较新版本。Oracle Virtual Box 就是这样一个例子。

对于其余的 DEB 软件包,你必须手动查找更新,这很不方便,尤其是在你的软件面向 Beta 测试者时,你需要频繁的添加很多更新。这正是 PPA 要解决的问题。

官方 PPA vs 非官方 PPA

你或许听过官方 PPA 或非官方 PPA 这个词,二者有什么不同呢?

开发人员为他们的软件创建的 PPA 称为官方 PPA。很明显,这是因为它来自项目开发者。

但有时,个人会创建由其他开发人员所创建的项目的 PPA。

为什么会有人这样做? 因为许多开发人员只提供软件的源代码,而且你也知道 在 Linux 中从源代码安装软件 是一件痛苦的事情,并不是每个人都可以或者会这样做。

这就是志愿者自己从这些源代码创建 PPA 以便其他用户可以轻松安装软件的原因。毕竟,使用这 3 行命令比从源代码安装要容易得多。

确保你的 Linux 发行版本可以使用 PPA

当在 Ubuntu 或任何其他基于 Debian 的发行版中使用 PPA 时,你应该记住一些事情。

并非每个 PPA 都适用于你的特定版本。你应该知道正在使用 哪个版本的 Ubuntu。版本的开发代号很重要,因为当你访问某个 PPA 的页面时,你可以看到该 PPA 都支持哪些版本的 Ubuntu。

对于其他基于 Ubuntu 的发行版,你可以查看 /etc/os-release 的内容来 找出 Ubuntu 版本 的信息。

Verify PPA availability for Ubuntu version

检查 PPA 是否适用于你的 Ubuntu 版本

如何知道 PPA 的网址呢?只需在网上搜索 PPA 的名称,如 ppa:dr-akulavich/lighttable,第一个搜索结果来自 Launchpad,这是托管 PPA 的官方平台。你也可以转到 Launchpad 并直接在那里搜索所需的 PPA。

如果不验证是否适用当前的版本就添加 PPA,当尝试安装不适用于你的系统版本的软件时,可能会看到类似下面的错误。

E: Unable to locate package

更糟糕的是,因为它已经添加到你的 source.list 中,每次运行软件更新程序时,你都会看到 “无法下载软件仓库信息” 的错误。

Failed to download repository information Ubuntu 13.04

如果你在终端中运行 sudo apt update,错误提示将包含导致此问题的仓库的更多详细信息。你可以在 sudo apt update 的输出内容结尾看到类似的内容:

W: Failed to fetch http://ppa.launchpad.net/venerix/pkg/ubuntu/dists/raring/main/binary-i386/Packages  404  Not Found
E: Some index files failed to download. They have been ignored, or old ones used instead.

上面的错误提示说的很明白,是因为系统找不到当前版本对应的仓库。还记得我们之前看到的仓库结构吗?APT 将尝试在 http://ppa.launchpad.net/<PPA_NAME>/ubuntu/dists/<Ubuntu_Version> 中寻找软件信息。

如果特定版本的 PPA 不可用,它将永远无法打开 URL,你会看到著名的 404 错误。

为什么 PPA 不适用于所有 Ubuntu 发行版?

这是因为 PPA 的作者必须编译软件并在特定版本上创建 PPA。考虑到每六个月发布一个新的 Ubuntu 版本,为每个版本的 Ubuntu 更新 PPA 是一项繁琐的任务,并非所有开发人员都有时间这样做。

如果 PPA 不适用于你的系统版本,该如何安装应用程序?

尽管 PPA 不适用于你的 Ubuntu 版本,你仍然可以下载 DEB 文件并安装应用程序。

比如说,你访问 Light Table 的 PPA 页面,使用刚刚学到的有关 PPA 的知识,你会发现 PPA 不适用于你的特定 Ubuntu 版本。

你可以点击 “查看软件包详细信息”。

Get DEB file from PPA

在这里,你可以单击软件包以显示更多详细信息,还可以在此处找到包的源代码和 DEB 文件。

Download DEB file from PPA

我建议 使用 Gdebi 安装这些 DEB 文件 而不是通过软件中心,因为 Gdebi 在处理依赖项方面要好得多。

请注意,以这种方式安装的软件包可能无法获得任何将来的更新。

我认为你已经阅读了足够多的关于添加 PPA 的内容,那么如何删除 PPA 及其安装的软件呢?

如何删除 PPA?

我过去曾写过 删除 PPA 的教程,这里写的也是同样的方法。

我建议在删除 PPA 之前删除从 PPA 安装的软件。如果只是删除 PPA,则已安装的软件仍保留在系统中,但不会获得任何更新。这不是你想要的,不是吗?

那么,问题来了,如何知道是哪个 PPA 安装了哪个应用程序?

查找 PPA 安装的软件包并将其移除

Ubuntu 软件中心无法移除 PPA 安装的软件包,你必须使用具有更多高级功能的 Synaptic 包管理器。

可以从软件中心安装 Synaptic 或使用以下命令进行安装:

sudo apt install synaptic

安装后,启动 Synaptic 包管理器并选择 “Origin”。你会看到添加到系统的各种软件仓库。PPA 条目将以前缀 PPA 进行标识,单击以查看 PPA 可用的包。已安装的软件前面会有恰当的符号进行标识。

Managing PPA with Synaptic package manager

查找通过 PPA 安装的软件包

找到包后,你可以从 Synaptic 删除它们。此外,也始终可以选择使用命令行进行移除:

sudo apt remove package_name

删除 PPA 安装的软件包后,你可以继续从 sources.list 中删除PPA。

以图形界面的方式删除 PPA

在设置中打开 “软件和更新”,然后点击 “其他软件” 选项卡。查找要删除的 PPA:

Delete a PPA from Software Source

此处你可以进项两项操作,可以取消选择 PPA 或选择 “删除” 选项。

区别在于,当你取消选择 PPA 条目时,系统将在 /etc/apt/sources.list.d 中的ppa_name.list 文件中注释掉仓库条目;但如果选择 “删除” 选项,将会删除 /etc/apt/sources.list.d目录中 ppa_name.list 文件里的仓库条目。

在这两种情况下,文件 ppa_name.list 都保留在所在的目录中,即使它是空的。

使用 PPA 安全吗?

这是一个主观问题。纯粹主义者厌恶 PPA,因为大多数时候 PPA 来自第三方开发者。但与此同时,PPA 在 Debian/Ubuntu 世界中很受欢迎,因为它们提供了更简单的安装选项。

就安全性而言,很少见到因为使用 PPA 之后你的 Linux 系统被黑客攻击或注入恶意软件。到目前为止,我不记得发生过这样的事件。

官方 PPA 可以不加考虑的使用,使用非官方 PPA 完全是你自己的决定。

根据经验,如果程序需要 sudo 权限,则应避免通过第三方 PPA 进行安装。

你如何看待使用 PPA?

我知道这篇文章需要挺长时间来阅读,但我想让你更好地了解 PPA。我希望这份详细指南能够回答你关于使用 PPA 的大部分问题。

如果你对 PPA 有更多疑问,请随时在评论区提问。

如果你发现任何技术或语法错误,或者有改进的建议,请告诉我。


via: https://itsfoss.com/ppa-guide/

作者:Abhishek Prakash 选题:lujun9972 译者:jlztan 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出