Merge remote-tracking branch 'LCTT/master'

This commit is contained in:
Xingyu.Wang
2019-03-08 23:12:43 +08:00
8 changed files with 792 additions and 783 deletions

View File

@@ -1,6 +1,8 @@
Ansible 初学者成功指南
Ansible 入门秘诀
======
> 用 Ansible 自动化你的数据中心的关键点。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/bus-big-data.png?itok=L34b2exg)
Ansible 是一个开源自动化工具,可以从中央控制节点统一配置服务器、安装软件或执行各种 IT 任务。它采用一对多、<ruby>无客户端<rt>agentless</rt></ruby>的机制,从控制节点上通过 SSH 发送指令给远端的客户机来完成任务(当然除了 SSH 外也可以用别的协议)。
@@ -11,36 +13,34 @@ Ansible 的主要使用群体是系统管理员,他们经常会周期性地执
![](https://opensource.com/sites/default/files/u128651/mapping-bash-commands-to-ansible.png)
这是个简单的例子,但应该能够证明:在 yaml 文件里写好命令然后在远程服务器上运行,是一件非常轻松的事。而且如果运行环境不同,就可以加入判断条件,指明某些命令只能在特定的服务器上运行(如:只在那些不是 Ubuntu 或 Debian 的系统上运行 `yum` 命令)。
这是个简单的例子,但应该能够证明:在 yaml 文件里写好命令然后在远程服务器上运行,是一件非常轻松的事。而且如果运行环境不同,就可以加入判断条件,指明某些命令只能在特定的服务器上运行(如:只在那些不是 Ubuntu 或 Debian 的系统上运行 `yum` 命令)。
Ansible 的一个重要特性是用 playbook 来描述一个计算机系统的最终状态,所以一个 playbook 可以在服务器上反复执行而不影响其最终状态(译注:即是幂等的)。如果某个任务已经被实施过了(如,“用户 `sysman` 已经存在”),那么 Ansible 就会忽略它继续执行后续的任务。
Ansible 的一个重要特性是用<ruby>剧本<rt>playbook</rt></ruby>来描述一个计算机系统的最终状态,所以一个剧本可以在服务器上反复执行而不影响其最终状态(LCTT 译注:即是幂等的)。如果某个任务已经被实施过了(如,“用户 `sysman` 已经存在”),那么 Ansible 就会忽略它继续执行后续的任务。
### 定义
* **<ruby>任务<rt>Tasks</rt></ruby>** task 是工作的最小单位,它可以是个动作,比如“安装一个数据库服务”、“安装一个 web 服务器”、“创建一条防火墙规则”或者“把这个配置文件拷贝到那个服务器上去”。
* **<ruby>战术动作<rt>Plays</rt></ruby>** play 由 task 组成,例如,一个 play 的内容是要“设置一个数据库,给 web 服务用”这就包含了如下任务1安装数据库包2设置数据库管理员密码3创建数据库实例4为该实例分配权限。
* **<ruby>战术手册<rt>Playbook</rt></ruby>**(译者playbook 原指美式橄榄球队的[战术手册][5] playbook 由 play 组成,一个 playbook 可能像这样:“设置我的网站,包含后端数据库”,其中的 play 包括1设置数据库服务器2设置 web 服务器。
* **<ruby>角色<rt>Roles</rt></ruby>** Role 用来保存和组织 playbook,以便分享和再次使用它们。还拿上个例子来说,如果你需要一个全新的 web 服务器,就可以用别人已经写好并分享出来的 role 来设置。因为 role 是高度可配置的(如果编写正确的话),可以根据部署需求轻松地复用它们。
* **<ruby>Ansible 星系<rt>Ansible Galaxy</rt></ruby>:** [Ansible Galaxy][1] 是一个在线仓库,里面保存的是由社区成员上传的 role,方便彼此分享。它与 GitHub 紧密集成,因此这些 role 可以先在 Git 仓库里组织好,然后通过 Ansible Galaxy 分享出来。
* <ruby>任务<rt>task</rt></ruby>:是工作的最小单位,它可以是个动作,比如“安装一个数据库服务”、“安装一个 web 服务器”、“创建一条防火墙规则”或者“把这个配置文件拷贝到那个服务器上去”。
* <ruby>动作<rt>play</rt></ruby> 由任务组成,例如,一个动作的内容是要“设置一个数据库,给 web 服务用”这就包含了如下任务1安装数据库包2设置数据库管理员密码3创建数据库实例4为该实例分配权限。
* <ruby>剧本<rt>playbook</rt></ruby>LCTT 译playbook 原指美式橄榄球队的[战术手册][5],也常指“剧本”,此处惯例采用“剧本”译名)由动作组成,一个剧本可能像这样:“设置我的网站,包含后端数据库”,其中的动作包括1设置数据库服务器2设置 web 服务器。
* <ruby>角色<rt>role</rt></ruby>用来保存和组织剧本,以便分享和再次使用它们。还拿上个例子来说,如果你需要一个全新的 web 服务器,就可以用别人已经写好并分享出来的角色来设置。因为角色是高度可配置的(如果编写正确的话),可以根据部署需求轻松地复用它们。
* <ruby>[Ansible 星系][1]<rt>Ansible Galaxy</rt></ruby>是一个在线仓库,里面保存的是由社区成员上传的角色,方便彼此分享。它与 GitHub 紧密集成,因此这些角色可以先在 Git 仓库里组织好,然后通过 Ansible 星系分享出来。
这些定义以及它们之间的关系可以用下图来描述:
![](https://opensource.com/sites/default/files/u128651/ansible-definitions.png)
请注意上面的例子只是组织任务的方式之一,我们当然也可以把安装数据库和安装 web 服务器的 playbook 拆开,放到不同的 role 里。Ansible Galaxy 上最常见的 role 是独立安装配置每个应用服务,你可以参考这些安装 [mysql][2] 和 [httpd][3] 的例子。
请注意上面的例子只是组织任务的方式之一,我们当然也可以把安装数据库和安装 web 服务器的剧本拆开,放到不同的角色里。Ansible 星系上最常见的角色是独立安装配置每个应用服务,你可以参考这些安装 [mysql][2] 和 [httpd][3] 的例子。
### 编写 playbook 的小贴士
### 编写剧本的小技巧
学习 Ansible 最好的资源是其[官方文档][4]。另外,像学习其他东西一样,搜索引擎是你的好朋友。我推荐你从一些简单的任务开始,比如安装应用或创建用户。下面是一些有用的指南:
* 在测试的时候少选几台服务器,这样你的 play 可以执行的更快一些。如果它们在一台机器上执行成功,在其他机器上也没问题。
* 总是在真正运行前做一次<ruby>测试<rt>dry run</rt></ruby>以确保所有的命令都能正确执行(要运行测试,加上 `--check-mode` 参数 )。
* 在测试的时候少选几台服务器,这样你的动作可以执行的更快一些。如果它们在一台机器上执行成功,在其他机器上也没问题。
* 总是在真正运行前做一次<ruby>测试<rt>dry run</rt></ruby>以确保所有的命令都能正确执行(要运行测试,加上 `--check-mode` 参数 )。
* 尽可能多做测试,别担心搞砸。任务里描述的是所需的状态,如果系统已经达到预期状态,任务会被简单地忽略掉。
* 确保在 `/etc/ansible/hosts` 里定义的主机名都可以被正确解析。
* 因为是用 SSH 与远程主机通信主控节点必须要接受密钥所以你面临如下选择1要么在正式使用之前就做好与远程主机的密钥交换工作2要么在开始管理某台新的远程主机时做好准备输入“Yes”因为你要接受对方的 SSH 密钥交换请求(译注:还有另一个不那么安全的选择,修改主控节点的 ssh 配置文件,将 `StrictHostKeyChecking` 设置成“no”
* 尽管你可以在同一个 playbook 内把不同 Linux 发行版的任务整合到一起,但为每个发行版单独编写 playbook 会更明晰一些。
* 因为是用 SSH 与远程主机通信,主控节点必须要接受密钥所以你面临如下选择1要么在正式使用之前就做好与远程主机的密钥交换工作2要么在开始管理某台新的远程主机时做好准备输入 “Yes”因为你要接受对方的 SSH 密钥交换请求(LCTT 译注:还有另一个不那么安全的选择,修改主控节点的 ssh 配置文件,将 `StrictHostKeyChecking` 设置成 “no”
* 尽管你可以在同一个剧本内把不同 Linux 发行版的任务整合到一起,但为每个发行版单独编写剧本会更明晰一些。
### 总结一下
@@ -50,7 +50,6 @@ Ansible 是你在数据中心里实施运维自动化的好选择,因为它:
* 将指令保存在 YAML 文件中(虽然也支持 JSON比写 shell 脚本更简单。
* 开源,因此你也可以做出自己的贡献,让它更加强大!
你是怎样使用 Ansible 让数据中心更加自动化的呢?请在评论中分享您的经验。
--------------------------------------------------------------------------------
@@ -59,7 +58,7 @@ via: https://opensource.com/article/18/2/tips-success-when-getting-started-ansib
作者:[Jose Delarosa][a]
译者:[jdh8383](https://github.com/jdh8383)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@@ -1,496 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: (ezio )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Computer Laboratory Raspberry Pi: Lesson 10 Input01)
[#]: via: (https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/input01.html)
[#]: author: (Alex Chadwick https://www.cl.cam.ac.uk)
ezio is translating
Computer Laboratory Raspberry Pi: Lesson 10 Input01
======
Welcome to the Input lesson series. In this series, you will learn how to receive inputs to the Raspberry Pi using the keyboard. We will start with just revealing the input, and then move to a more traditional text prompt.
This first input lesson teaches some theory about drivers and linking, as well as about keyboards and ends up displaying text on the screen.
### 1 Getting Started
It is expected that you have completed the OK series, and it would be helpful to have completed the Screen series. Many of the files from that series will be called, without comment. If you do not have these files, or prefer to use a correct implementation, download the template for this lesson from the [Downloads][1] page. If you're using your own implementation, please remove everything after your call to SetGraphicsAddress.
### 2 USB
```
The USB standard was designed to make simple hardware in exchange for complex software.
```
As you are no doubt aware, the Raspberry Pi model B has two USB ports, commonly used for connecting a mouse and keyboard. This was a very good design decision, USB is a very generic connector, and many different kinds of device use it. It's simple to build new devices for, simple to write device drivers for, and is highly extensible thanks to USB hubs. Could it get any better? Well, no, in fact for an Operating Systems developer this is our worst nightmare. The USB standard is huge. I really mean it this time, it is over 700 pages, before you've even thought about connecting a device.
I spoke to a number of other hobbyist Operating Systems developers about this and they all say one thing: don't bother. "It will take too long to implement", "You won't be able to write a tutorial on it" and "It will be of little benefit". In many ways they are right, I'm not able to write a tutorial on the USB standard, as it would take weeks. I also can't teach how to write device drivers for all the different devices, so it is useless on its own. However, I can do the next best thing: Get a working USB driver, get a keyboard driver, and then teach how to use these in an Operating System. I set out searching for a free driver that would run in an operating system that doesn't even know what a file is yet, but I couldn't find one. They were all too high level. So, I attempted to write one. Everybody was right, this took weeks to do. However, I'm pleased to say I did get one that works with no external help from the Operating System, and can talk to a mouse and keyboard. It is by no means complete, efficient, or correct, but it does work. It has been written in C and the full source code can be found on the downloads page for those interested.
So, this tutorial won't be a lesson on the USB standard (at all). Instead we'll look at how to work with other people's code.
### 3 Linking
```
Linking allows us to make reusable code 'libraries' that anyone can use in their program.
```
Since we're about to incorporate external code into the Operating System, we need to talk about linking. Linking is a process which is applied to programs or Operating System to link in functions. What this means is that when a program is made, we don't necessarily code every function (almost certainly not in fact). Linking is what we do to make our program link to functions in other people's code. This has actually been going on all along in our Operating Systems, as the linker links together all of the different files, each of which is compiled separately.
```
Programs often just call libraries, which call other libraries and so on until eventually they call an Operating System library which we would write.
```
There are two types of linking: static and dynamic. Static linking is like what goes on when we make our Operating Systems. The linker finds all the addresses of the functions, and writes them into the code, before the program is finished. Dynamic linking is linking that occurs after the program is 'complete'. When it is loaded, the dynamic linker goes through the program and links any functions which are not in the program to libraries in the Operating System. This is one of the jobs our Operating System should eventually be capable of, but for now everything will be statically linked.
The USB driver I have written is suitable for static linking. This means I give you the compiled code for each of my files, and then the linker finds functions in your code which are not defined in your code, and links them to functions in my code. On the [Downloads][1] page for this lesson is a makefile and my USB driver, which you will need to continue. Download them and replace the makefile in your code with this one, and also put the driver in the same folder as that makefile.
### 4 Keyboards
In order to get input into our Operating System, we need to understand at some level how keyboards actually work. Keyboards have two types of keys: Normal and Modifier keys. The normal keys are the letters, numbers, function keys, etc. They constitute almost every key on the keyboard. The modifiers are up to 8 special keys. These are left shift, right shift, left control, right control, left alt, right alt, left GUI and right GUI. The keyboard can detect any combination of the modifier keys being held, as well as up to 6 normal keys. Every time a key changes (i.e. is pushed or released), it reports this to the computer. Typically, keyboards also have three LEDs for Caps Lock, Num Lock and Scroll Lock, which are controlled by the computer, not the keyboard itself. Keyboards may have many more lights such as power, mute, etc.
In order to help standardise USB keyboards, a table of values was produced, such that every keyboard key ever is given a unique number, as well as every conceivable LED. The table below lists the first 126 of values.
Table 4.1 USB Keyboard Keys
| Number | Description | Number | Description | Number | Description | Number | Description | |
| ------ | ---------------- | ------- | ---------------------- | -------- | -------------- | --------------- | -------------------- | |
| 4 | a and A | 5 | b and B | 6 | c and C | 7 | d and D | |
| 8 | e and E | 9 | f and F | 10 | g and G | 11 | h and H | |
| 12 | i and I | 13 | j and J | 14 | k and K | 15 | l and L | |
| 16 | m and M | 17 | n and N | 18 | o and O | 19 | p and P | |
| 20 | q and Q | 21 | r and R | 22 | s and S | 23 | t and T | |
| 24 | u and U | 25 | v and V | 26 | w and W | 27 | x and X | |
| 28 | y and Y | 29 | z and Z | 30 | 1 and ! | 31 | 2 and @ | |
| 32 | 3 and # | 33 | 4 and $ | 34 | 5 and % | 35 | 6 and ^ | |
| 36 | 7 and & | 37 | 8 and * | 38 | 9 and ( | 39 | 0 and ) | |
| 40 | Return (Enter) | 41 | Escape | 42 | Delete (Backspace) | 43 | Tab | |
| 44 | Spacebar | 45 | - and _ | 46 | = and + | 47 | [ and { | |
| 48 | ] and } | 49 | \ and | | 50 | # and ~ | 51 | ; and : |
| 52 | ' and " | 53 | ` and ~ | 54 | , and < | 55 | . and > | |
| 56 | / and ? | 57 | Caps Lock | 58 | F1 | 59 | F2 | |
| 60 | F3 | 61 | F4 | 62 | F5 | 63 | F6 | |
| 64 | F7 | 65 | F8 | 66 | F9 | 67 | F10 | |
| 68 | F11 | 69 | F12 | 70 | Print Screen | 71 | Scroll Lock | |
| 72 | Pause | 73 | Insert | 74 | Home | 75 | Page Up | |
| 76 | Delete forward | 77 | End | 78 | Page Down | 79 | Right Arrow | |
| 80 | Left Arrow | 81 | Down Arrow | 82 | Up Arrow | 83 | Num Lock | |
| 84 | Keypad / | 85 | Keypad * | 86 | Keypad - | 87 | Keypad + | |
| 88 | Keypad Enter | 89 | Keypad 1 and End | 90 | Keypad 2 and Down Arrow | 91 | Keypad 3 and Page Down | |
| 92 | Keypad 4 and Left Arrow | 93 | Keypad 5 | 94 | Keypad 6 and Right Arrow | 95 | Keypad 7 and Home | |
| 96 | Keypad 8 and Up Arrow | 97 | Keypad 9 and Page Up | 98 | Keypad 0 and Insert | 99 | Keypad . and Delete | |
| 100 | \ and | | 101 | Application | 102 | Power | 103 | Keypad = |
| 104 | F13 | 105 | F14 | 106 | F15 | 107 | F16 | |
| 108 | F17 | 109 | F18 | 110 | F19 | 111 | F20 | |
| 112 | F21 | 113 | F22 | 114 | F23 | 115 | F24 | |
| 116 | Execute | 117 | Help | 118 | Menu | 119 | Select | |
| 120 | Stop | 121 | Again | 122 | Undo | 123 | Cut | |
| 124 | Copy | 125 | Paste | 126 | Find | 127 | Mute | |
| 128 | Volume Up | 129 | Volume Down | | | | | |
The full list can be found in section 10, page 53 of [HID Usage Tables 1.12][2].
### 5 The Nut Behind the Wheel
```
These summaries and the code they describe form an API - Application Product Interface.
```
Normally, when you work with someone else's code, they provide a summary of their methods, what they do and roughly how they work, as well as how they can go wrong. Here is a table of the relevant instructions required to use my USB driver.
Table 5.1 Keyboard related functions in CSUD
| Function | Arguments | Returns | Description |
| ----------------------- | ----------------------- | ----------------------- | ----------------------- |
| UsbInitialise | None | r0 is result code | This method is the all-in-one method that loads the USB driver, enumerates all devices and attempts to communicate with them. This method generally takes about a second to execute, though with a few USB hubs plugged in this can be significantly longer. After this method is completed methods in the keyboard driver become available, regardless of whether or not a keyboard is indeed inserted. Result code explained below. |
| UsbCheckForChange | None | None | Essentially provides the same effect as UsbInitialise, but does not provide the same one time initialisation. This method checks every port on every connected hub recursively, and adds new devices if they have been added. This should be very quick if there are no changes, but can take up to a few seconds if a hub with many devices is attached. |
| KeyboardCount | None | r0 is count | Returns the number of keyboards currently connected and detected. UsbCheckForChange may update this. Up to 4 keyboards are supported by default. Up to this many keyboards may be accessed through this driver. |
| KeyboardGetAddress | r0 is index | r0 is address | Retrieves the address of a given keyboard. All other functions take a keyboard address in order to know which keyboard to access. Thus, to communicate with a keyboard, first check the count, then retrieve the address, then use other methods. Note, the order of keyboards that this method returns may change after calls to UsbCheckForChange. |
| KeyboardPoll | r0 is address | r0 is result code | Reads in the current key state from the keyboard. This operates via polling the device directly, contrary to the best practice. This means that if this method is not called frequently enough, a key press could be missed. All reading methods simply return the value as of the last poll. |
| KeyboardGetModifiers | r0 is address | r0 is modifier state | Retrieves the status of the modifier keys as of the last poll. These are the shift, alt control and GUI keys on both sides. This is returned as a bit field, such that a 1 in the bit 0 means left control is held, bit 1 means left shift, bit 2 means left alt, bit 3 means left GUI and bits 4 to 7 mean the right versions of those previous. If there is a problem r0 contains 0. |
| KeyboardGetKeyDownCount | r0 is address | r0 is count | Retrieves the number of keys currently held down on the keyboard. This excludes modifier keys. Normally, this cannot go above 6. If there is an error this method returns 0. |
| KeyboardGetKeyDown | r0 is address, r1 is key number | r0 is scan code | Retrieves the scan code (see Table 4.1) of a particular held down key. Normally, to work out which keys are down, call KeyboardGetKeyDownCount and then call KeyboardGetKeyDown up to that many times with increasing values of r1 to determine which keys are down. Returns 0 if there is a problem. It is safe (but not recommended) to call this method without calling KeyboardGetKeyDownCount and interpret 0s as keys not held. Note, the order or scan codes can change randomly (some keyboards sort numerically, some sort temporally, no guarantees are made). |
| KeyboardGetKeyIsDown | r0 is address, r1 is scan code | r0 is status | Alternative to KeyboardGetKeyDown, checks if a particular scan code is among the held down keys. Returns 0 if not, or a non-zero value if so. Faster when detecting particular scan codes (e.g. looking for ctrl+c). On error, returns 0. |
| KeyboardGetLedSupport | r0 is address | r0 is LEDs | Checks which LEDs a particular keyboard supports. Bit 0 being 1 represents Number Lock, bit 1 represents Caps Lock, bit 2 represents Scroll Lock, bit 3 represents Compose, bit 4 represents Kana, bit 5 represents Power, bit 6 represents Mute and bit 7 represents Compose. As per the USB standard, none of these LEDs update automatically (e.g. Caps Lock must be set manually when the Caps Lock scan code is detected). |
| KeyboardSetLeds | r0 is address, r1 is LEDs | r0 is result code | Attempts to turn on/off the specified LEDs on the keyboard. See below for result code values. See KeyboardGetLedSupport for LEDs' values. |
```
Result codes are an easy way to handle errors, but often more elegant solutions exist in higher level code.
```
Several methods return 'result codes'. These are commonplace in C code, and are just numbers which represent what happened in a method call. By convention, 0 always indicates success. The following result codes are used by this driver.
Table 5.2 - CSUD Result Codes
| Code | Description |
| ---- | ----------------------------------------------------------------------- |
| 0 | Method completed successfully. |
| -2 | Argument: A method was called with an invalid argument. |
| -4 | Device: The device did not respond correctly to the request. |
| -5 | Incompatible: The driver is not compatible with this request or device. |
| -6 | Compiler: The driver was compiled incorrectly, and is broken. |
| -7 | Memory: The driver ran out of memory. |
| -8 | Timeout: The device did not respond in the expected time. |
| -9 | Disconnect: The device requested has disconnected, and cannot be used. |
The general usage of the driver is as follows:
1. Call UsbInitialise
2. Call UsbCheckForChange
3. Call KeyboardCount
4. If this is 0, go to 2.
5. For each keyboard you support:
1. Call KeyboardGetAddress
2. Call KeybordGetKeyDownCount
3. For each key down:
1. Check whether or not it has just been pushed
2. Store that the key is down
4. For each key stored:
1. Check whether or not key is released
2. Remove key if released
6. Perform actions based on keys pushed/released
7. Go to 2.
Ultimately, you may do whatever you wish to with the keyboard, and these methods should allow you to access all of its functionality. Over the next 2 lessons, we shall look at completing the input side of a text terminal, similarly to most command line computers, and interpreting the commands. In order to do this, we're going to need to have keyboard inputs in a more useful form. You may notice that my driver is (deliberately) unhelpful, because it doesn't have methods to deduce whether or not a key has just been pushed down or released, it only has methods about what is currently held down. This means we'll need to write such methods ourselves.
### 6 Updates Available
Repeatedly checking for updates is called 'polling'. This is in contrast to interrupt driven IO, where the device sends a signal when data is ready.
First of all, let's implement a method KeyboardUpdate which detects the first keyboard and uses its poll method to get the current input, as well as saving the last inputs for comparison. We can then use this data with other methods to translate scan codes to keys. The method should do precisely the following:
1. Retrieve a stored keyboard address (initially 0).
2. If this is not 0, go to 9.
3. Call UsbCheckForChange to detect new keyboards.
4. Call KeyboardCount to detect how many keyboards are present.
5. If this is 0 store the address as 0 and return; we can't do anything with no keyboard.
6. Call KeyboardGetAddress with parameter 0 to get the first keyboard's address.
7. Store this address.
8. If this is 0, return; there is some problem.
9. Call KeyboardGetKeyDown 6 times to get each key currently down and store them
10. Call KeyboardPoll
11. If the result is non-zero go to 3. There is some problem (such as disconnected keyboard).
To store the values mentioned above, we will need the following values in the .data section.
```
.section .data
.align 2
KeyboardAddress:
.int 0
KeyboardOldDown:
.rept 6
.hword 0
.endr
```
```
.hword num inserts the half word constant num into the file directly.
```
```
.rept num [commands] .endr copies the commands commands to the output num times.
```
Try to implement the method yourself. My implementation for this is as follows:
1.
```
.section .text
.globl KeyboardUpdate
KeyboardUpdate:
push {r4,r5,lr}
kbd .req r4
ldr r0,=KeyboardAddress
ldr kbd,[r0]
```
We load in the keyboard address.
2.
```
teq kbd,#0
bne haveKeyboard$
```
If the address is non-zero, we have a keyboard. Calling UsbCheckForChanges is slow, and so if everything works we avoid it.
3.
```
getKeyboard$:
bl UsbCheckForChange
```
If we don't have a keyboard, we have to check for new devices.
4.
```
bl KeyboardCount
```
Now we see if a new keyboard has been added.
5.
```
teq r0,#0
ldreq r1,=KeyboardAddress
streq r0,[r1]
beq return$
```
There are no keyboards, so we have no keyboard address.
6.
```
mov r0,#0
bl KeyboardGetAddress
```
Let's just get the address of the first keyboard. You may want to allow more.
7.
```
ldr r1,=KeyboardAddress
str r0,[r1]
```
Store the keyboard's address.
8.
```
teq r0,#0
beq return$
mov kbd,r0
```
If we have no address, there is nothing more to do.
9.
```
saveKeys$:
mov r0,kbd
mov r1,r5
bl KeyboardGetKeyDown
ldr r1,=KeyboardOldDown
add r1,r5,lsl #1
strh r0,[r1]
add r5,#1
cmp r5,#6
blt saveKeys$
```
Loop through all the keys, storing them in KeyboardOldDown. If we ask for too many, this returns 0 which is fine.
10.
```
mov r0,kbd
bl KeyboardPoll
```
Now we get the new keys.
11.
```
teq r0,#0
bne getKeyboard$
return$:
pop {r4,r5,pc}
.unreq kbd
```
Finally we check if KeyboardPoll worked. If not, we probably disconnected.
With our new KeyboardUpdate method, checking for inputs becomes as simple as calling this method at regular intervals, and it will even check for disconnections etc. This is a useful method to have, as our actual key processing may differ based on the situation, and so being able to get the current input in its raw form with one method call is generally applicable. The next method we ideally want is KeyboardGetChar, a method that simply returns the next key pressed as an ASCII character, or returns 0 if no key has just been pressed. This could be extended to support typing a key multiple times if it is held for a certain duration, and to support the 'lock' keys as well as modifiers.
To make this method it is useful if we have a method KeyWasDown, which simply returns 0 if a given scan code is not in the KeyboardOldDown values, and returns a non-zero value otherwise. Have a go at implementing this yourself. As always, a solution can be found on the downloads page.
### 7 Look Up Tables
```
In many areas of programming, the larger the program, the faster it is. Look up tables are large, but are very fast. Some problems can be solved by a mixture of look up tables and normal functions.
```
The KeyboardGetChar method could be quite complex if we write it poorly. There are 100s of scan codes, each with different effects depending on the presence or absence of the shift key or other modifiers. Not all of the keys can be translated to a character. For some characters, multiple keys can produce the same character. A useful trick in situations with such vast arrays of possibilities is look up tables. A look up table, much like in the physical sense, is a table of values and their results. For some limited functions, the simplest way to deduce the answer is just to precompute every answer, and just return the correct one by retrieving it. In this case, we could build up a sequence of values in memory such that the nth value into the sequence is the ASCII character code for the scan code n. This means our method would simply have to detect if a key was pressed, and then retrieve its value from the table. Further, we could have a separate table for the values when shift is held, so that the shift key simply changes which table we're working with.
After the .section .data command, copy the following tables:
```
.align 3
KeysNormal:
.byte 0x0, 0x0, 0x0, 0x0, 'a', 'b', 'c', 'd'
.byte 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'
.byte 'm', 'n', 'o', 'p', 'q', 'r', 's', 't'
.byte 'u', 'v', 'w', 'x', 'y', 'z', '1', '2'
.byte '3', '4', '5', '6', '7', '8', '9', '0'
.byte '\n', 0x0, '\b', '\t', ' ', '-', '=', '['
.byte ']', '\\\', '#', ';', '\'', '`', ',', '.'
.byte '/', 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
.byte 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
.byte 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
.byte 0x0, 0x0, 0x0, 0x0, '/', '*', '-', '+'
.byte '\n', '1', '2', '3', '4', '5', '6', '7'
.byte '8', '9', '0', '.', '\\\', 0x0, 0x0, '='
.align 3
KeysShift:
.byte 0x0, 0x0, 0x0, 0x0, 'A', 'B', 'C', 'D'
.byte 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L'
.byte 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T'
.byte 'U', 'V', 'W', 'X', 'Y', 'Z', '!', '"'
.byte '£', '$', '%', '^', '&', '*', '(', ')'
.byte '\n', 0x0, '\b', '\t', ' ', '_', '+', '{'
.byte '}', '|', '~', ':', '@', '¬', '<', '>'
.byte '?', 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
.byte 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
.byte 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
.byte 0x0, 0x0, 0x0, 0x0, '/', '*', '-', '+'
.byte '\n', '1', '2', '3', '4', '5', '6', '7'
.byte '8', '9', '0', '.', '|', 0x0, 0x0, '='
```
```
.byte num inserts the byte constant num into the file directly.
```
```
Most assemblers and compilers recognise escape sequences; character sequences such as \t which insert special characters instead.
```
These tables map directly the first 104 scan codes onto the ASCII characters as a table of bytes. We also have a separate table describing the effects of the shift key on those scan codes. I've used the ASCII null character (0) for all keys without direct mappings in ASCII (such as the function keys). Backspace is mapped to the ASCII backspace character (8 denoted \b), enter is mapped to the ASCII new line character (10 denoted \n) and tab is mapped to the ASCII horizontal tab character (9 denoted \t).
The KeyboardGetChar method will need to do the following:
1. Check if KeyboardAddress is 0. If so, return 0.
2. Call KeyboardGetKeyDown up to 6 times. Each time:
1. If key is 0, exit loop.
2. Call KeyWasDown. If it was, go to the next key.
3. If the scan code is more than 103, go to the next key.
4. Call KeyboardGetModifiers
5. If shift is held, load the address of KeysShift. Otherwise load KeysNormal.
6. Read the ASCII value from the table.
7. If it is 0, go to the next key otherwise return this ASCII code and exit.
3. Return 0.
Try to implement this yourself. My implementation is presented below:
1.
```
.globl KeyboardGetChar
KeyboardGetChar:
ldr r0,=KeyboardAddress
ldr r1,[r0]
teq r1,#0
moveq r0,#0
moveq pc,lr
```
Simple check to see if we have a keyboard.
2.
```
push {r4,r5,r6,lr}
kbd .req r4
key .req r6
mov r4,r1
mov r5,#0
keyLoop$:
mov r0,kbd
mov r1,r5
bl KeyboardGetKeyDown
```
r5 will hold the index of the key, r4 holds the keyboard address.
1.
```
teq r0,#0
beq keyLoopBreak$
```
If a scan code is 0, it either means there is an error, or there are no more keys.
2.
```
mov key,r0
bl KeyWasDown
teq r0,#0
bne keyLoopContinue$
```
If a key was already down it is uninteresting, we only want ot know about key presses.
3.
```
cmp key,#104
bge keyLoopContinue$
```
If a key has a scan code higher than 104, it will be outside our table, and so is not relevant.
4.
```
mov r0,kbd
bl KeyboardGetModifiers
```
We need to know about the modifier keys in order to deduce the character.
5.
```
tst r0,#0b00100010
ldreq r0,=KeysNormal
ldrne r0,=KeysShift
```
We detect both a left and right shift key as changing the characters to their shift variants. Remember, a tst instruction computes the logical AND and then compares it to zero, so it will be equal to 0 if and only if both of the shift bits are zero.
6.
```
ldrb r0,[r0,key]
```
Now we can load in the key from the look up table.
7.
```
teq r0,#0
bne keyboardGetCharReturn$
keyLoopContinue$:
add r5,#1
cmp r5,#6
blt keyLoop$
```
If the look up code contains a zero, we must continue. To continue, we increment the index, and check if we've reached 6.
3.
```
keyLoopBreak$:
mov r0,#0
keyboardGetCharReturn$:
pop {r4,r5,r6,pc}
.unreq kbd
.unreq key
```
We return our key here, if we reach keyLoopBreak$, then we know there is no key held, so return 0.
### 8 Notepad OS
Now we have our KeyboardGetChar method, we can make an operating system that just types what the user writes to the screen. For simplicity we'll ignore all the unusual keys. In 'main.s' delete all code after bl SetGraphicsAddress. Call UsbInitialise, set r4 and r5 to 0, then loop forever over the following commands:
1. Call KeyboardUpdate
2. Call KeyboardGetChar
3. If it is 0, got to 1
4. Copy r4 and r5 to r1 and r2 then call DrawCharacter
5. Add r0 to r4
6. If r4 is 1024, add r1 to r5 and set r4 to 0
7. If r5 is 768 set r5 to 0
8. Go to 1
Now compile this and test it on the Pi. You should almost immediately be able to start typing text to the screen when the Pi starts. If not, please see our troubleshooting page.
When it works, congratulations, you've achieved an interface with the computer. You should now begin to realise that you've almost got a primitive operating system together. You can now interface with the computer, issuing it commands, and receive feedback on screen. In the next tutorial, [Input02][3] we will look at producing a full text terminal, in which the user types commands, and the computer executes them.
--------------------------------------------------------------------------------
via: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/input01.html
作者:[Alex Chadwick][a]
选题:[lujun9972][b]
译者:[ezio](https://github.com/oska874)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.cl.cam.ac.uk
[b]: https://github.com/lujun9972
[1]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/downloads.html
[2]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/downloads/hut1_12v2.pdf
[3]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/input02.html

View File

@@ -1,122 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: (geekpi)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (How To Get Flatpak Apps And Games Built With OpenGL To Work With Proprietary Nvidia Graphics Drivers)
[#]: via: (https://www.linuxuprising.com/2018/06/how-to-get-flatpak-apps-and-games-built.html)
[#]: author: (Logix https://plus.google.com/118280394805678839070)
How To Get Flatpak Apps And Games Built With OpenGL To Work With Proprietary Nvidia Graphics Drivers
======
**Some applications and games built with OpenGL support and packaged as Flatpak fail to start with proprietary Nvidia drivers. This article explains how to get such Flatpak applications or games them to start, without installing the open source drivers (Nouveau).**
Here's an example. I'm using the proprietary Nvidia drivers on my Ubuntu 18.04 desktop (`nvidia-driver-390`) and when I try to launch the latest
```
$ /usr/bin/flatpak run --branch=stable --arch=x86_64 --command=krita --file-forwarding org.kde.krita
Gtk-Message: Failed to load module "canberra-gtk-module"
Gtk-Message: Failed to load module "canberra-gtk-module"
libGL error: No matching fbConfigs or visuals found
libGL error: failed to load driver: swrast
Could not initialize GLX
```
To fix Flatpak games and applications not starting when using OpenGL with proprietary Nvidia graphics drivers, you'll need to install a runtime for your currently installed proprietary Nvidia drivers. Here's how to do this.
**1\. Add the FlatHub repository if you haven't already. You can find exact instructions for your Linux distribution[here][1].**
**2. Now you'll need to figure out the exact version of the proprietary Nvidia drivers installed on your system. **
_This step is dependant of the Linux distribution you're using and I can't cover all cases. The instructions below are Ubuntu-oriented (and Ubuntu flavors) but hopefully you can figure out for yourself the Nvidia drivers version installed on your system._
To do this in Ubuntu, open `Software & Updates` , switch to the `Additional Drivers` tab and note the name of the Nvidia driver package.
As an example, this is `nvidia-driver-390` in my case, as you can see here:
![](https://1.bp.blogspot.com/-FAfjtGNeUJc/WzYXMYTFBcI/AAAAAAAAAx0/xUhIO83IAjMuK4Hn0jFUYKJhSKw8y559QCLcBGAs/s1600/additional-drivers-nvidia-ubuntu.png)
That's not all. We've only found out the Nvidia drivers major version but we'll also need to know the minor version. To get the exact Nvidia driver version, which we'll need for the next step, run this command (should work in any Debian-based Linux distribution, like Ubuntu, Linux Mint and so on):
```
apt-cache policy NVIDIA-PACKAGE-NAME
```
Where NVIDIA-PACKAGE-NAME is the Nvidia drivers package name listed in `Software & Updates` . For example, to see the exact installed version of the `nvidia-driver-390` package, run this command:
```
$ apt-cache policy nvidia-driver-390
nvidia-driver-390:
Installed: 390.48-0ubuntu3
Candidate: 390.48-0ubuntu3
Version table:
* 390.48-0ubuntu3 500
500 http://ro.archive.ubuntu.com/ubuntu bionic/restricted amd64 Packages
100 /var/lib/dpkg/status
```
In this command's output, look for the `Installed` section and note the version numbers (excluding `-0ubuntu3` and anything similar). Now we know the exact version of the installed Nvidia drivers (`390.48` in my example). Remember this because we'll need it for the next step.
**3\. And finally, you can install the Nvidia runtime for your installed proprietary Nvidia graphics drivers, from FlatHub**
To list all the available Nvidia runtime packages available on FlatHub, you can use this command:
```
flatpak remote-ls flathub | grep nvidia
```
Hopefully the runtime for your installed Nvidia drivers is available on FlatHub. You can now proceed to install the runtime by using this command:
* For 64bit systems:
```
flatpak install flathub org.freedesktop.Platform.GL.nvidia-MAJORVERSION-MINORVERSION
```
Replace MAJORVERSION with the Nvidia driver major version installed on your computer (390 in my example above) and
MINORVERSION with the minor version (48 in my example from step 2).
For example, to install the runtime for Nvidia graphics driver version 390.48, you'd have to use this command:
```
flatpak install flathub org.freedesktop.Platform.GL.nvidia-390-48
```
* For 32bit systems (or to be able to run 32bit applications or games on 64bit), install the 32bit runtime using:
```
flatpak install flathub org.freedesktop.Platform.GL32.nvidia-MAJORVERSION-MINORVERSION
```
Once again, replace MAJORVERSION with the Nvidia driver major version installed on your computer (390 in my example above) and MINORVERSION with the minor version (48 in my example from step 2).
For example, to install the 32bit runtime for Nvidia graphics driver version 390.48, you'd have to use this command:
```
flatpak install flathub org.freedesktop.Platform.GL32.nvidia-390-48
```
That is all you need to do to get applications or games packaged as Flatpak that are built with OpenGL to run.
--------------------------------------------------------------------------------
via: https://www.linuxuprising.com/2018/06/how-to-get-flatpak-apps-and-games-built.html
作者:[Logix][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://plus.google.com/118280394805678839070
[1]:https://flatpak.org/setup/
[2]:https://www.linuxuprising.com/2018/06/free-painting-software-krita-410.html
[3]:https://www.linuxuprising.com/2018/06/winepak-is-flatpak-repository-for.html
[4]:https://github.com/winepak/applications/issues/23
[5]:https://github.com/flatpak/flatpak/issues/138

View File

@@ -1,146 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: (zero-mk)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Top Hex Editors for Linux)
[#]: via: (https://itsfoss.com/hex-editors-linux)
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
Top Hex Editors for Linux
======
Hex editor lets you view/edit the binary data of a file which is in the form of “hexadecimal” values and hence the name “Hex” editor. Lets be frank, not everyone needs it. Only a specific group of users who have to deal with the binary data use it.
If you have no idea, what it is, let me give you an example. Suppose, you have the configuration files of a game, you can open them using a hex editor and change certain values to have more ammo/score and so on. To know more about Hex editors, you should start with the [Wikipedia page][1].
In case you already know whats it used for let us take a look at the best Hex editors available for Linux.
### 5 Best Hex Editors Available
![Best Hex Editors for Linux][2]
**Note:** The hex editors mentioned are in no particular order of ranking.
#### 1\. Bless Hex Editor
![bless hex editor][3]
**Key Features** :
* Raw disk editing
* Multilevel undo/redo operations.
* Multiple tabs
* Conversion table
* Plugin support to extend the functionality
Bless is one of the most popular Hex editor available for Linux. You can find it listed in your AppCenter or Software Center. If that is not the case, you can check out their [GitHub page][4] for the build and the instructions associated.
It can easily handle editing big files without slowing down so its a fast hex editor.
#### 2\. GNOME Hex Editor
![gnome hex editor][5]
**Key Features:**
* View/Edit in either Hex/Ascii
* Edit large files
*
Yet another amazing Hex editor specifically tailored for GNOME. Well, I personally use Elementary OS, so I find it listed in the App Center. You should find it in the Software Center as well. If not, refer to the [GitHub page][6] for the source.
You can use this editor to view/edit in either hex or ASCII. The user interface is quite simple as you can see in the image above.
#### 3\. Okteta
![okteta][7]
**Key Features:**
* Customizable data views
* Multiple tabs
* Character encodings: All 8-bit encodings as supplied by Qt, EBCDIC
* Decoding table listing common simple data types.
Okteta is a simple hex editor with not so fancy features. Although it can handle most of the tasks. Theres a separate module of it which you can use to embed this in other programs to view/edit files.
Similar to all the above-mentioned editors, you can find this listed on your AppCenter and Software center as well.
#### 4\. wxHexEditor
![wxhexeditor][8]
**Key Features:**
* Easily handle big files
* Has x86 disassembly support
* **** Sector Indication **** on Disk devices
* Supports customizable hex panel formatting and colors.
This is something interesting. It is primarily a Hex editor but you can also use it as a low level disk editor. For example, if you have a problem with your HDD, you can use this editor to edit the the sectors in raw hex and fix it.
You can find it listed on your App Center and Software Center. If not, [Sourceforge][9] is the way to go.
#### 5\. Hexedit (Command Line)
![hexedit][10]
**Key Features** :
* Works via terminal
* Its fast and simple
If you want something to work on your terminal, you can go ahead and install Hexedit via the console. Its my favorite Linux hex editor in command line.
When you launch it, you will have to specify the location of the file, and itll then open it for you.
To install it, just type in:
```
sudo apt install hexedit
```
### Wrapping Up
Hex editors could come in handy to experiment and learn. If you are someone experienced, you should opt for the one with more feature with a GUI. Although, it all comes down to personal preferences.
What do you think about the usefulness of Hex editors? Which one do you use? Did we miss listing your favorite? Let us know in the comments!
![][11]
--------------------------------------------------------------------------------
via: https://itsfoss.com/hex-editors-linux
作者:[Ankush Das][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://itsfoss.com/author/ankush/
[b]: https://github.com/lujun9972
[1]: https://en.wikipedia.org/wiki/Hex_editor
[2]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/01/Linux-hex-editors-800x450.jpeg?resize=800%2C450&ssl=1
[3]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/01/bless-hex-editor.jpg?ssl=1
[4]: https://github.com/bwrsandman/Bless
[5]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/01/ghex-hex-editor.jpg?ssl=1
[6]: https://github.com/GNOME/ghex
[7]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/01/okteta-hex-editor-800x466.jpg?resize=800%2C466&ssl=1
[8]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/01/wxhexeditor.jpg?ssl=1
[9]: https://sourceforge.net/projects/wxhexeditor/
[10]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/01/hexedit-console.jpg?resize=800%2C566&ssl=1
[11]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/01/Linux-hex-editors.jpeg?fit=800%2C450&ssl=1

View File

@@ -1,5 +1,5 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: translator: (geekpi)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )

View File

@@ -0,0 +1,506 @@
[#]: collector: (lujun9972)
[#]: translator: (ezio )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Computer Laboratory Raspberry Pi: Lesson 10 Input01)
[#]: via: (https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/input01.html)
[#]: author: (Alex Chadwick https://www.cl.cam.ac.uk)
计算机实验课 树莓派: 课程 10 输入01
======
欢迎进入输入课程系列。在本系列,你将会学会如何使用键盘接收输入给树莓派。我们将会从揭示输入开始本课,然后开始传统的文本命令。
这是第一堂输入课,会教授一些关于驱动和链接的理论,同样也包含键盘的知识,最后以在屏幕上显示文本结束。
### 1 开始
希望你已经完成了 OK 系列课程, 这会对你完成屏幕系列课程很有帮助。很多 OK 课程上的文件会被使用而不会做解释。如果你没有这些文件,或者希望使用一个正确的实现, 可以从该堂课的[下载页][1]下载模板。如果你使用你自己的实现,请删除调用了 `SetGraphicsAddress` 之后全部的代码。
### 2 USB
```
USB 标准的设计目的是通过复杂的硬件来简化硬件。
```
如你所知,树莓派 B 型有两个 USB 接口通常用来连接一个鼠标和一个键盘。这是一个非常好的设计决策USB 是一个非常通用的接口, 很多种设备都可以使用它。这就很容易为它设计新外设,很容易为它编写设备驱动, 而且通过 USB 集线器可以非常容易扩展。还能更好吗当然是不能实际上对一个操作系统开发者来说这就是我们的噩梦。USB 标准太大了。 我是真的,在你思考如何连接设备之前,它的文档将近 700 页。
我和很多爱好操作系统的开发者谈过这些,而他们全部都说几句话:不要抱怨。“实现这个需要花费很久时间”,“你不可能写出关于 USB 的教程”,“收益太小了”。在很多方面,他们是对的,我不可能写出一个关于 USB 标准的教程, 那得花费几周时间。我同样不能教授如何为全部所有的设备编写外设驱动,所以使用自己写的驱动是没什么用的。然而,我可以做仅次于最好的事情是获取一个正常工作的 USB 驱动,拿一个键盘驱动,然后教授如何在操作系统中使用它们。我开始寻找可以运行在一个甚至不知道文件是什么的操作系统的自由驱动,但是我一个都找不到。他们都太高层了。所以我尝试写一个。每个人都是对的,这耗费了我几周时间。然而我高兴的说我我做这些工作没有获取操作系统以外的帮助,并且可以和鼠标和键盘通信。这句不是完整的,高效的,或者正确的,但是它能工作。驱动是以 C 编写的,而且有兴趣的可以在下载页找到全部源代码。
所以,这一个教程不会是 USB 标准的课程(一点也没有)。实际上我们将会看到如何使用其他人的代码。
### 3 链接
```
链接允许我们制作可重用的代码库,所有人都可以在他们的程序中使用。
```
既然我们要引进外部代码到操作系统,我们就需要谈一谈链接。链接是一种过程,可以在程序或者操作系统中链接函数。这意味着当一个程序生成之后,我们不必要编写每一个函数(几乎可以肯定,实际上并非如此)。链接就是我们做的用来把我们程序和别人代码中的函数连结在一起。这个实际上已经在我们的操作系统进行了,因为链接器吧所有不同的文件链接在一起,每个都是分开编译的。
```
程序经常知识调用库,这些库会调用其它的库,知道最终调用了我们写的操作系统。
```
有两种链接:静态和动态。静态链接就像我们在制作自己的操作系统时进行的。链接器找到全部函数的地址,然后在链接结束前,将这些地址都写入代码中。动态链接是在程序“完成”之后。当程序加载后,动态链接器检查程序,然后在操作系统的库找到所有不在程序里的函数。这就是我们的操作系统最终应该能够完成的一项工作,但是现在所有东西都将是静态链接的。
我编写的 USB 驱动程序适合静态编译。这意味着我给你我的每个文件的编译后的代码,然后链接器找到你的代码中的那些没有实现的函数,就将这些函数链接到我的代码。在本课的 [下载页][1] 是一个 makefile 和我的 USB 驱动,这是接下来需要的。下载并使用这 makefile 替换你的代码中的 makefile 同事将驱动放在和这个 makefile 相同的文件夹。
### 4 键盘
为了将输入传给我们的操作系统,我们需要在某种程度上理解键盘是如何实际工作的。键盘有两种按键:普通键和修饰键。普通按键是字母、数字、功能键,等等。他们构成了键盘上几乎每一个按键。修饰键是最多 8 个特殊键。他们是左 shift 右 shift 左 ctrl右 ctrl左 alt 右 alt左 GUI 和右 GUI。键盘可以检测出所有的组合中那个修饰键被按下了以及最多 6 个普通键。每次一个按钮变化了i.e. 是按下了还是释放了),键盘就会报告给电脑。通常,键盘也会有 3 个 LED 灯,分别指示 Caps 锁定Num 锁定,和 Scroll 锁定,这些都是由电脑控制的,而不是键盘自己。键盘也可能由更多的灯,比如电源、静音,等等。
为了帮助标准 USB 键盘,产生了一个按键值的表,每个键盘按键都一个唯一的数字,每个可能的 LED 也类似。下面的表格列出了前 126 个值。
Table 4.1 USB 键盘值
| 序号 | 描述 | 序号 | 描述 | 序号 | 描述 | 序号 | 描述 | |
| ------ | ---------------- | ------- | ---------------------- | -------- | -------------- | --------------- | -------------------- |----|
| 4 | a and A | 5 | b and B | 6 | c and C | 7 | d and D | |
| 8 | e and E | 9 | f and F | 10 | g and G | 11 | h and H | |
| 12 | i and I | 13 | j and J | 14 | k and K | 15 | l and L | |
| 16 | m and M | 17 | n and N | 18 | o and O | 19 | p and P | |
| 20 | q and Q | 21 | r and R | 22 | s and S | 23 | t and T | |
| 24 | u and U | 25 | v and V | 26 | w and W | 27 | x and X | |
| 28 | y and Y | 29 | z and Z | 30 | 1 and ! | 31 | 2 and @ | |
| 32 | 3 and # | 33 | 4 and $ | 34 | 5 and % | 35 | 6 and ^ | |
| 36 | 7 and & | 37 | 8 and * | 38 | 9 and ( | 39 | 0 and ) | |
| 40 | Return (Enter) | 41 | Escape | 42 | Delete (Backspace) | 43 | Tab | |
| 44 | Spacebar | 45 | - and _ | 46 | = and + | 47 | [ and { | |
| 48 | ] and } | 49 | \ and | 50 | # and ~ | 51 | ; and : |
| 52 | ' and " | 53 | ` and ~ | 54 | , and < | 55 | . and > | |
| 56 | / and ? | 57 | Caps Lock | 58 | F1 | 59 | F2 | |
| 60 | F3 | 61 | F4 | 62 | F5 | 63 | F6 | |
| 64 | F7 | 65 | F8 | 66 | F9 | 67 | F10 | |
| 68 | F11 | 69 | F12 | 70 | Print Screen | 71 | Scroll Lock | |
| 72 | Pause | 73 | Insert | 74 | Home | 75 | Page Up | |
| 76 | Delete forward | 77 | End | 78 | Page Down | 79 | Right Arrow | |
| 80 | Left Arrow | 81 | Down Arrow | 82 | Up Arrow | 83 | Num Lock | |
| 84 | Keypad / | 85 | Keypad * | 86 | Keypad - | 87 | Keypad + | |
| 88 | Keypad Enter | 89 | Keypad 1 and End | 90 | Keypad 2 and Down Arrow | 91 | Keypad 3 and Page Down | |
| 92 | Keypad 4 and Left Arrow | 93 | Keypad 5 | 94 | Keypad 6 and Right Arrow | 95 | Keypad 7 and Home | |
| 96 | Keypad 8 and Up Arrow | 97 | Keypad 9 and Page Up | 98 | Keypad 0 and Insert | 99 | Keypad . and Delete | |
| 100 | \ and | 101 | Application | 102 | Power | 103 | Keypad = |
| 104 | F13 | 105 | F14 | 106 | F15 | 107 | F16 | |
| 108 | F17 | 109 | F18 | 110 | F19 | 111 | F20 | |
| 112 | F21 | 113 | F22 | 114 | F23 | 115 | F24 | |
| 116 | Execute | 117 | Help | 118 | Menu | 119 | Select | |
| 120 | Stop | 121 | Again | 122 | Undo | 123 | Cut | |
| 124 | Copy | 125 | Paste | 126 | Find | 127 | Mute | |
| 128 | Volume Up | 129 | Volume Down | | | | | |
完全列表可以在[HID 页表 1.12][2]的 53 页,第 10 节找到
### 5 车轮后的螺母
```
这些总结和代码的描述组成了一个 API - 应用程序产品接口。
```
通常,当你使用其他人的代码,他们会提供一份自己代码的总结,描述代码都做了什么,粗略介绍了是如何工作的,以及什么情况下会出错。下面是一个使用我的 USB 驱动的相关步骤要求。
Table 5.1 CSUD 中和键盘相关的函数
| 函数 | 参数 | 返回值 | 描述 |
| ----------------------- | ----------------------- | ----------------------- | -----------------------|
| UsbInitialise | None | r0 is result code | 这个方法是一个集多种功能于一身的方法它加载USB驱动程序枚举所有设备并尝试与它们通信。这种方法通常需要大约一秒钟的时间来执行但是如果插入几个USB集线器执行时间会明显更长。在此方法完成之后键盘驱动程序中的方法就可用了不管是否确实插入了键盘。返回代码如下解释。|
| UsbCheckForChange | None | None | 本质上提供与 `usbinitialization` 相同的效果,但不提供相同的一次初始化。该方法递归地检查每个连接的集线器上的每个端口,如果已经添加了新设备,则添加它们。如果没有更改,这应该是非常快的,但是如果连接了多个设备的集线器,则可能需要几秒钟的时间。|
| KeyboardCount | None | r0 is count | 返回当前连接并检测到的键盘数量。`UsbCheckForChange` 可能会对此进行更新。默认情况下最多支持4个键盘。多达这么多的键盘可以通过这个驱动程序访问。|
| KeyboardGetAddress | r0 is index | r0 is address | 检索给定键盘的地址。所有其他函数都需要一个键盘地址,以便知道要访问哪个键盘。因此,要与键盘通信,首先要检查计数,然后检索地址,然后使用其他方法。注意,在调用 `UsbCheckForChange` 之后,此方法返回的键盘顺序可能会改变。
|
| KeyboardPoll | r0 is address | r0 is result code | 从键盘读取当前键状态。这是通过直接轮询设备来操作的,与最佳实践相反。这意味着,如果没有频繁地调用此方法,可能会错过一个按键。所有读取方法只返回上次轮询时的值。
|
| KeyboardGetModifiers | r0 is address | r0 is modifier state | 检索上次轮询时修饰符键的状态。这是两边的 `shift` 键、`alt` 键和 `GUI` 键。这回作为一个位字段返回这样位0中的1表示左控件被保留位1表示左 `shift`位2表示左 `alt` 位3表示左 `GUI`位4到7表示前几位的右版本。如果有问题`r0` 包含0。|
| KeyboardGetKeyDownCount | r0 is address | r0 is count | 检索当前按下键盘的键数。这排除了修饰键。这通常不能超过6次。如果有错误这个方法返回0。|
| KeyboardGetKeyDown | r0 is address, r1 is key number | r0 is scan code | 检索特定下拉键的扫描代码(见表4.1)。通常,要计算出哪些键是关闭的,可以调用 `KeyboardGetKeyDownCount`,然后多次调用 `KeyboardGetKeyDown` ,将 `r1` 的值递增以确定哪些键是关闭的。如果有问题返回0。在不调用 `KeyboardGetKeyDownCount` 并将0解释为未持有的键的情况下调用此方法是安全的(但不建议这样做)。注意,顺序或扫描代码可以随机更改(有些键盘按数字排序,有些键盘按时间排序,没有任何保证)。|
| KeyboardGetKeyIsDown | r0 is address, r1 is scan code | r0 is status | 除了 `KeyboardGetKeyDown` 之外还可以检查下拉键中是否有特定的扫描代码。如果不是返回0;如果是,返回一个非零值。当检测特定的扫描代码(例如寻找ctrl+c)更快。出错时返回0。
|
| KeyboardGetLedSupport | r0 is address | r0 is LEDs | 检查特定键盘支持哪些led。第0位代表数字锁定第1位代表大写锁定第2位代表滚动锁定第3位代表合成第4位代表假名第5位代表能量第6位代表静音第7位代表合成。根据USB标准这些led都不是自动更新的(例如,当检测到大写锁定扫描代码时,必须手动设置大写锁定)。|
| KeyboardSetLeds | r0 is address, r1 is LEDs | r0 is result code | 试图打开/关闭键盘上指定的 LED 灯。查看下面的结果代码值。参见 `KeyboardGetLedSupport` 获取 LED 的值。
|
```
返回值是一种处理错误的简单方法,但是通常更优雅的解决途径存在于更高层次的代码。
```
有几种方法返回 ‘返回值’。这些都是 C 代码的老生常谈了,就是用数字代表函数调用发生了什么。通常情况, 0 总是代表操作成功。下面的是驱动用到的返回值。
Table 5.2 - CSUD 返回值
| 代码 | 描述 |
| ---- | ----------------------------------------------------------------------- |
| 0 | 方法成功完成。 |
| -2 | 参数: 函数调用了无效参数。 |
| -4 | 设备: 设备没有正确响应请求。 |
| -5 | 不匹配: 驱动不适用于这个请求或者设备。 |
| -6 | 编译器: 驱动没有正确编译,或者被破坏了。 |
| -7 | 内存: 驱动用尽了内存。 |
| -8 | 超时: 设备没有在预期的时间内响应请求。 |
| -9 | 断开连接: 被请求的设备断开连接,或者不能使用。 |
驱动的通常用法如下:
1. 调用 `UsbInitialise`
2. 调用 `UsbCheckForChange`
3. 调用 `KeyboardCount`
4. 如果返回 0重复步骤 2。
5. 针对你支持的每种键盘:
1. 调用 ·KeyboardGetAddress·
2. 调用 ·KeybordGetKeyDownCount·
3. 针对每个按下的按键:
1. 检查它是否已经被按下了
2. 保存按下的按键
4. 针对每个保存的按键:
3. 检查按键是否被释放了
4. 如果释放了就删除
6. 根据按下/释放的案件执行操作
7. 重复步骤 2.
最后,你可能做所有你想对键盘做的事,而这些方法应该允许你访问键盘的全部功能。在接下来的两节课,我们将会着眼于完成文本终端的输入部分,类似于大部分的命令行电脑,以及命令的解释。为了做这些,我们将需要在更有用的形式下得到一个键盘输入。你可能注意到我的驱动是(故意)没有太大帮助,因为它并没有方法来判断是否一个案件刚刚按下或释放了,它只有芳芳来判断当前那个按键是按下的。这就意味着我们需要自己编写这些方法。
### 6 可用更新
重复检查更新被称为 ‘轮询’。这是针对驱动 IO 中断而言的,这种情况下设备在准备好后会发一个信号。
首先,让我们实现一个 `KeyboardUpdate` 方法,检查第一个键盘,并使用轮询方法来获取当前的输入,以及保存最后一个输入来对比。然后我们可以使用这个数据和其它方法来将扫描码转换成按键。这个方法应该按照下面的说明准确操作:
1. 提取一个保存好的键盘地址(初始值为 0
2. 如果不是0 进入步骤9.
3. 调用 `UsbCheckForChange` 检测新键盘。
4. 调用 `KeyboardCount` 检测有几个键盘在线。
5. 如果返回0意味着没有键盘可以让我们操作只能退出了。
6. 调用 `KeyboardGetAddress` 参数是 0获取第一个键盘的地址。
7. 保存这个地址。
8. 如果这个值是0那么退出这里应该有些问题。
9. 调用 `KeyboardGetKeyDown` 6 次,获取每次按键按下的值并保存。
10. 调用 `KeyboardPoll`
11. 如果返回值非 0进入步骤 3。这里应该有些问题比如键盘断开连接
要保存上面提到的值,我们将需要下面 `.data` 段的值。
```
.section .data
.align 2
KeyboardAddress:
.int 0
KeyboardOldDown:
.rept 6
.hword 0
.endr
```
```
.hword num 直接将半字的常数插入文件。
```
```
.rept num [commands] .endr 复制 `commands` 命令到输出 num 次。
```
试着自己实现这个方法。对此,我的实现如下:
1.
```
.section .text
.globl KeyboardUpdate
KeyboardUpdate:
push {r4,r5,lr}
kbd .req r4
ldr r0,=KeyboardAddress
ldr kbd,[r0]
```
我们加载键盘的地址。
2.
```
teq kbd,#0
bne haveKeyboard$
```
如果地址非0就说明我们有一个键盘。调用 `UsbCheckForChanges` 慢,所以如果全部事情都起作用,我们要避免调用这个函数。
3.
```
getKeyboard$:
bl UsbCheckForChange
```
如果我们一个键盘都没有,我们就必须检查新设备。
4.
```
bl KeyboardCount
```
如果有心键盘添加,我们就会看到这个。
5.
```
teq r0,#0
ldreq r1,=KeyboardAddress
streq r0,[r1]
beq return$
```
如果没有键盘,我们就没有键盘地址。
6.
```
mov r0,#0
bl KeyboardGetAddress
```
让我们获取第一个键盘的地址。你可能想要更多。
7.
```
ldr r1,=KeyboardAddress
str r0,[r1]
```
保存键盘地址。
8.
```
teq r0,#0
beq return$
mov kbd,r0
```
如果我们没有地址,这里就没有其它活要做了。
9.
```
saveKeys$:
mov r0,kbd
mov r1,r5
bl KeyboardGetKeyDown
ldr r1,=KeyboardOldDown
add r1,r5,lsl #1
strh r0,[r1]
add r5,#1
cmp r5,#6
blt saveKeys$
```
Loop through all the keys, storing them in KeyboardOldDown. If we ask for too many, this returns 0 which is fine.
查询遍全部按键,在 `KeyboardOldDown` 保存下来。如果我们询问的太多了,返回 0 也是正确的。
10.
```
mov r0,kbd
bl KeyboardPoll
```
现在哦我们得到了新的按键。
11.
```
teq r0,#0
bne getKeyboard$
return$:
pop {r4,r5,pc}
.unreq kbd
```
最后我们要检查 `KeyboardOldDown` 是否工作了。如果没工作,那么我们可能是断开连接了。
有了我们新的 `KeyboardUpdate` 方法,检查输入变得简单到固定周期调用这个方法,而它甚至可以检查断开连接,等等。这是一个有用的方法,因为我们实际的按键处理会根据条件不同而有所差别,所以能够用一个函数调以它的原始方式获取当前的输入是可行的。下一个方法我们理想希望的是 `KeyboardGetChar`,简单的返回下一个按下的按钮的 ASCII 字符,或者如果没有按键按下就返回 0。这可以扩展到支持将一个按键多次按下如果它保持了一个特定时间也支持锁定键和修饰键。
要使这个方法有用,如果我们有一个 `KeyWasDown` 方法如果给定的扫描代码不在keyboard dolddown值中它只返回0否则返回一个非零值。你可以自己尝试一下。与往常一样可以在下载页面找到解决方案。
### 7 查找表
```
在编程的许多领域,程序越大,速度越快。查找表很大,但是速度很快。有些问题可以通过查找表和普通函数的组合来解决。
```
`KeyboardGetChar`方法如果写得不好,可能会非常复杂。有 100 多种扫描代码,每种代码都有不同的效果,这取决于 shift 键或其他修饰符的存在与否。并不是所有的键都可以转换成一个字符。对于一些字符,多个键可以生成相同的字符。在有如此多可能性的情况下,一个有用的技巧是查找表。查找表与物理意义上的查找表非常相似,它是一个值及其结果的表。对于一些有限的函数,推导出答案的最简单方法就是预先计算每个答案,然后通过检索返回正确的答案。在这种情况下,我们可以建立一个序列的值在内存中,n值序列的ASCII字符代码扫描代码n。这意味着我们的方法只会发现如果一个键被按下,然后从表中检索它的值。此外当按住shift键时我们可以为值创建一个单独的表这样shift键就可以简单地更改正在处理的表。
在 `.section` `.data` 命令之后,复制下面的表:
```
.align 3
KeysNormal:
.byte 0x0, 0x0, 0x0, 0x0, 'a', 'b', 'c', 'd'
.byte 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'
.byte 'm', 'n', 'o', 'p', 'q', 'r', 's', 't'
.byte 'u', 'v', 'w', 'x', 'y', 'z', '1', '2'
.byte '3', '4', '5', '6', '7', '8', '9', '0'
.byte '\n', 0x0, '\b', '\t', ' ', '-', '=', '['
.byte ']', '\\\', '#', ';', '\'', '`', ',', '.'
.byte '/', 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
.byte 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
.byte 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
.byte 0x0, 0x0, 0x0, 0x0, '/', '*', '-', '+'
.byte '\n', '1', '2', '3', '4', '5', '6', '7'
.byte '8', '9', '0', '.', '\\\', 0x0, 0x0, '='
.align 3
KeysShift:
.byte 0x0, 0x0, 0x0, 0x0, 'A', 'B', 'C', 'D'
.byte 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L'
.byte 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T'
.byte 'U', 'V', 'W', 'X', 'Y', 'Z', '!', '"'
.byte '£', '$', '%', '^', '&', '*', '(', ')'
.byte '\n', 0x0, '\b', '\t', ' ', '_', '+', '{'
.byte '}', '|', '~', ':', '@', '¬', '<', '>'
.byte '?', 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
.byte 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
.byte 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
.byte 0x0, 0x0, 0x0, 0x0, '/', '*', '-', '+'
.byte '\n', '1', '2', '3', '4', '5', '6', '7'
.byte '8', '9', '0', '.', '|', 0x0, 0x0, '='
```
```
.byte num 直接插入字节常量 num 到文件。
```
```
大部分的汇编器和编译器识别转义序列;插入特殊字符的字符序列,如\t。
```
这些表直接将前 104 个扫描代码映射到 ASCII 字符,作为一个字节表。我们还有一个单独的表来描述 `shift` 键对这些扫描代码的影响。我使用 ASCII `null`字符(0)表示所有没有直接映射的 ASCII 键(例如函数键)。退格映射到ASCII退格字符(8表示 `\b` ) `enter` 映射到ASCII新行字符(10表示 `\n`) `tab` 映射到ASCII水平制表符(9表示 `\t` )。
`KeyboardGetChar` 方法需要做以下工作:
1. 检查 `KeyboardAddress` 是否返回 0。如果是则返回0。
2. 调用 `KeyboardGetKeyDown` 最多 6 次。每次:
1. 如果按键时0跳出循环。
2. 调用 `KeyWasDown`。 如果返回是,处理下一个按键。
3. 如果扫描码超过 103进入下一个按键。
4. 调用 `KeyboardGetModifiers`
5. 如果 `shift` 是被按着的,就加载 `KeysShift` 的地址。否则加载 `KeysNormal` 的地址。
6. 从表中读出 ASCII 码值。
7. 如果是 0进行下一个按键否则返回 ASCII 码值并退出。
3. 返回0。
试着自己实现。我的实现展示在下面:
1.
```
.globl KeyboardGetChar
KeyboardGetChar:
ldr r0,=KeyboardAddress
ldr r1,[r0]
teq r1,#0
moveq r0,#0
moveq pc,lr
```
简单的检查我们是否有键盘。
2.
```
push {r4,r5,r6,lr}
kbd .req r4
key .req r6
mov r4,r1
mov r5,#0
keyLoop$:
mov r0,kbd
mov r1,r5
bl KeyboardGetKeyDown
```
r5 will hold the index of the key, r4 holds the keyboard address.
`r5` 将会保存按键的索引, `r4` 保存键盘的地址。
1.
```
teq r0,#0
beq keyLoopBreak$
```
如果扫描码是0它要么意味着有错要么说明没有更多按键了。
2.
```
mov key,r0
bl KeyWasDown
teq r0,#0
bne keyLoopContinue$
```
如果按键已经按下了,那么他就没意思了,我们只想知道按下的按键。
3.
```
cmp key,#104
bge keyLoopContinue$
```
如果一个按键有个超过 104 的扫描码,他将会超出我们的表,所以它是无关的按键。
4.
```
mov r0,kbd
bl KeyboardGetModifiers
```
我们需要知道修饰键来推断字符。
5.
```
tst r0,#0b00100010
ldreq r0,=KeysNormal
ldrne r0,=KeysShift
```
当将字符更改为其移位变体时,我们要同时检测左 `shift` 键和右 `shift` 键。记住,`tst` 指令计算的是逻辑和,然后将其与 0 进行比较,所以当且仅当移位位都为 0 时它才等于0。
1.
```
ldrb r0,[r0,key]
```
现在我们可以从查找表加载按键了。
1.
```
teq r0,#0
bne keyboardGetCharReturn$
keyLoopContinue$:
add r5,#1
cmp r5,#6
blt keyLoop$
```
如果查找码包含一个 0我们必须继续。为了继续我们要增加索引并检查是否到 6 次了。
1.
```
keyLoopBreak$:
mov r0,#0
keyboardGetCharReturn$:
pop {r4,r5,r6,pc}
.unreq kbd
.unreq key
```
在这里我们返回我们的按键,如果我们到达 `keyLoopBreak$` 然后我们就知道这里没有按键被握住所以返回0。
### 8 记事本操作系统
现在我们有了 `KeyboardGetChar` 方法,可以创建一个操作系统,只输入用户对着屏幕所写的内容。为了简单起见,我们将忽略所有不寻常的键。在 `main.s` ,删除`bl SetGraphicsAddress` 之后的所有代码。调用 `UsbInitialise`,将 `r4` 和 `r5` 设置为 0然后循环执行以下命令:
1. 调用 `KeyboardUpdate`
2. 调用 `KeyboardGetChar`
3. 如果返回 0跳转到步骤1
4. 复制 `r4` 和 `r5` 到 `r1` 和 `r2` ,然后调用 `DrawCharacter`
5. 把 `r0` 加到 `r4`
6. 如果 `r4` 是 1024将 `r1` 加到 `r5`,然后设置 `r4` 为 0。
7. 如果 `r5` 是 768设置 `r5` 为0
8. 跳转到步骤1
现在编译这个,然后在 PI 上测试。您几乎可以立即开始在屏幕上输入文本。如果没有,请参阅我们的故障排除页面。
当它工作时,祝贺您,您已经实现了与计算机的接口。现在您应该开始意识到,您几乎已经拥有了一个原始的操作系统。现在,您可以与计算机交互,发出命令,并在屏幕上接收反馈。在下一篇教程[输入02][3]中,我们将研究如何生成一个全文本终端,用户在其中输入命令,然后计算机执行这些命令。
--------------------------------------------------------------------------------
via: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/input01.html
作者:[Alex Chadwick][a]
选题:[lujun9972][b]
译者:[ezio](https://github.com/oska874)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.cl.cam.ac.uk
[b]: https://github.com/lujun9972
[1]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/downloads.html
[2]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/downloads/hut1_12v2.pdf
[3]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/input02.html

View File

@@ -0,0 +1,121 @@
[#]: collector: (lujun9972)
[#]: translator: (geekpi)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (How To Get Flatpak Apps And Games Built With OpenGL To Work With Proprietary Nvidia Graphics Drivers)
[#]: via: (https://www.linuxuprising.com/2018/06/how-to-get-flatpak-apps-and-games-built.html)
[#]: author: (Logix https://plus.google.com/118280394805678839070)
如何使得支持 OpenGL 的 Flatpak 应用和游戏在专有 Nvidia 图形驱动下工作
======
**一些支持 OpenGL 并打包为 Flatpak 的应用和游戏无法使用专有 Nvidia 驱动启动。本文将介绍如何在不安装开源驱动Nouveau的情况下启动这些 Flatpak 应用或游戏。**
这有个例子。我在我的 Ubuntu 18.04 桌面上使用专有的 Nvidia 驱动程序 `nvidia-driver-390`),当我尝试启动最新版本时:
```
$ /usr/bin/flatpak run --branch=stable --arch=x86_64 --command=krita --file-forwarding org.kde.krita
Gtk-Message: Failed to load module "canberra-gtk-module"
Gtk-Message: Failed to load module "canberra-gtk-module"
libGL error: No matching fbConfigs or visuals found
libGL error: failed to load driver: swrast
Could not initialize GLX
```
要修复使用 OpenGL 和专有 Nvidia 图形驱动时无法启动的 Flatpak 游戏和应用,你需要为已安装的专有驱动安装运行时。以下是步骤。
**1\. 如果尚未添加 FlatHub 仓库,请添加它。你可以在[此处][1]找到针对 Linux 发行版的说明。**
**2. 现在,你需要确定系统上安装的专有 Nvidia 驱动的确切版本。**
_这一步取决于你使用的 Linux 发行版,我无法涵盖所有​​情况。下面的说明是面向 Ubuntu以及 Ubuntu 风格的版本),但希望你可以自己弄清楚系统上安装的 Nvidia 驱动版本._
要在 Ubuntu 中执行此操作,请打开 `SoftwareUpdates`,切换到 `Additional Drivers` 选项卡并记下 Nvidia 驱动包的名称。
比如,你可以看到我的是 `nvidia-driver-390`
![](https://1.bp.blogspot.com/-FAfjtGNeUJc/WzYXMYTFBcI/AAAAAAAAAx0/xUhIO83IAjMuK4Hn0jFUYKJhSKw8y559QCLcBGAs/s1600/additional-drivers-nvidia-ubuntu.png)
这里还没完成。我们只是找到了 Nvidia 驱动的主要版本,但我们还需要知道次要版本。要获得我们下一步所需的确切 Nvidia 驱动版本,请运行此命令(应该适用于任何基于 Debian 的 Linux 发行版,如 Ubuntu、Linux Mint 等):
```
apt-cache policy NVIDIA-PACKAGE-NAME
```
NVIDIA-PACKAGE-NAME 是 `Software & Updates` 中列出的 Nvidia 驱动包名称。例如,要查看 `nvidia-driver-390` 包的确切安装版本,请运行以下命令:
```
$ apt-cache policy nvidia-driver-390
nvidia-driver-390:
Installed: 390.48-0ubuntu3
Candidate: 390.48-0ubuntu3
Version table:
* 390.48-0ubuntu3 500
500 http://ro.archive.ubuntu.com/ubuntu bionic/restricted amd64 Packages
100 /var/lib/dpkg/status
```
在这个命令的输出中,查找 `Installed` 部分并记下版本号(不包括 `-0ubuntu3` 之类)。现在我们知道了已安装的 Nvidia 驱动的确切版本(我例子中的是 `390.48`)。记住它,因为下一步我们需要。
**3\. 最后,你可以从 FlatHub 为你已安装的专有 Nvidia 图形驱动安装运行时。**
要列出 FlatHub 上所有可用的 Nvidia 运行时包,你可以使用以下命令:
```
flatpak remote-ls flathub | grep nvidia
```
幸运地是 FlatHub 上提供这个 Nvidia 驱动的运行时。你现在可以使用以下命令继续安装运行时:
* 针对 64 位系统:
```
flatpak install flathub org.freedesktop.Platform.GL.nvidia-MAJORVERSION-MINORVERSION
```
将 MAJORVERSION 替换为 Nvidia 驱动的主要版本(在上面的示例中为 390将 MINORVERSION 替换为次要版本步骤2我例子中的为 48
例如,要为 Nvidia 图形驱动版本 390.48 安装运行时,你必须使用以下命令:
```
flatpak install flathub org.freedesktop.Platform.GL.nvidia-390-48
```
* 对于 32 位系统(或能够在 64 位上运行 32 位的应用或游戏),使用以下命令安装 32 位运行时:
```
flatpak install flathub org.freedesktop.Platform.GL32.nvidia-MAJORVERSION-MINORVERSION
```
再说一次,将 MAJORVERSION 替换为 Nvidia 驱动的主要版本(在上面的示例中为 390将 MINORVERSION 替换为次要版本步骤2我例子中的为 48
比如,要为 Nvidia 图形驱动版本 390.48 安装 32 位运行时,你需要使用以下命令:
```
flatpak install flathub org.freedesktop.Platform.GL32.nvidia-390-48
```
以上就是你要运行支持 OpenGL 的 Flatpak 的应用或游戏的方法。
--------------------------------------------------------------------------------
via: https://www.linuxuprising.com/2018/06/how-to-get-flatpak-apps-and-games-built.html
作者:[Logix][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[geekpi](https://github.com/geekpi)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://plus.google.com/118280394805678839070
[1]:https://flatpak.org/setup/
[2]:https://www.linuxuprising.com/2018/06/free-painting-software-krita-410.html
[3]:https://www.linuxuprising.com/2018/06/winepak-is-flatpak-repository-for.html
[4]:https://github.com/winepak/applications/issues/23
[5]:https://github.com/flatpak/flatpak/issues/138

View File

@@ -0,0 +1,147 @@
[#]: collector: "lujun9972"
[#]: translator: "zero-mk "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
[#]: subject: "Top Hex Editors for Linux"
[#]: via: "https://itsfoss.com/hex-editors-linux"
[#]: author: "Ankush Das https://itsfoss.com/author/ankush/"
Top Hex Editors for Linux
======
十六进制编辑器可以让你以十六进制的形式查看/编辑文件的二进制数据,因此其被命名为“十六进制”编辑器。说实话,并不是每个人都需要它。只有必须处理二进制数据的特定用户组才会使用到它。
如果您不知道,它是什么,让我举个例子。假设您拥有游戏的配置文件,您可以使用十六进制编辑器打开它们并更改某些值以获得更多的弹药/分数等等。 想要了解有关Hex编辑器的更多信息你可以参阅 [Wikipedia page][1]。
如果你已经知道它用来干什么了 —— 让我们来看看Linux最好的Hex编辑器。
### 5个最好的十六进制编辑器
![Best Hex Editors for Linux][2]
**注意:**提到的十六进制编辑器没有特定的排名顺序。
#### 1\. Bless Hex Editor
![bless hex editor][3]
**主要特点:**
* 编辑裸设备Raw disk
* 多级撤消/重做操作
* 多个标签
* 转换表
* 支持插件扩展功能
Bless是Linux上最流行的Hex编辑器之一。您可以在AppCenter或软件中心中找到它。 如果不是这种情况,您可以查看他们的 [GitHub page][4] 获取构建和相关的说明。
它可以轻松处理编辑大文件而不会降低速度——因此它是一个快速的十六进制编辑器。
#### 2\. GNOME Hex Editor
![gnome hex editor][5]
**主要特点:**
* 以 十六进制/Ascii格式 查看/编辑
* 编辑大文件
*
另一个神奇的十六进制编辑器-专门为GNOME量身定做的。 我个人用的是 Elementary OS, 所以我可以在 软件中心AppCenter找到它.。您也可以在软件中心找到它。如果没有,请参考 [GitHub page][6] 获取源代码。
您可以使用此编辑器以十六进制或ASCII格式 查看/编辑 文件。用户界面非常简单——正如您在上面的图像中看到的那样。
#### 3\. Okteta
![okteta][7]
**主要特点:**
* 可自定义的数据视图
* 多个选项卡
* 字符编码:支持Qt、EBCDIC的所有8位编码
* 解码表列出常见的简单数据类型
Okteta是一个简单的十六进制编辑器没有那么奇特的功能。虽然它可以处理大部分任务。它有一个单独的模块你可以使用它嵌入其他程序来查看/编辑文件。
与上述所有编辑器类似您也可以在应用中心App Center和软件中心Software Center上找到列出的编辑器。
#### 4\. wxHexEditor
![wxhexeditor][8]
**主要特点:**
* 轻松处理大文件
* 支持x86反汇编
* **** Sector Indication **** on Disk devices
* 支持自定义十六进制面板格式和颜色
这很有趣。它主要是一个十六进制编辑器但您也可以将其用作低级磁盘编辑器。例如如果您的硬盘有问题可以使用此编辑器编辑RAW格式原始数据镜像文件在十六进制中的扇区并修复它。
你可以在你的应用中心App Center和软件中心Software Center找到它。 如果不是, [Sourceforge][9] 是个正确的选择。
#### 5\. Hexedit (命令行工具)
![hexedit][10]
**主要特点:**
* 运行在命令行终端上
* 它又快又简单
如果您想在终端上工作可以继续通过控制台安装hexedit。它是我最喜欢的命令行Linux十六进制编辑器。
当你启动它时,你必须指定要打开的文件的位置,然后它会为你打开它。
要安装它,只需输入:
```
sudo apt install hexedit
```
### 结束
十六进制编辑器可以方便地进行实验和学习。如果你是一个有经验的人你应该选择一个有更多功能的——GUI。 尽管这一切都取决于个人喜好。
你认为十六进制编辑器的有用性如何?你用哪一个?我们没有列出你最喜欢的吗?请在评论中告诉我们!
![][11]
--------------------------------------------------------------------------------
via: https://itsfoss.com/hex-editors-linux
作者:[Ankush Das][a]
选题:[lujun9972][b]
译者:[zero-mk](https://github.com/zero-mk)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/ankush/
[b]: https://github.com/lujun9972
[1]: https://en.wikipedia.org/wiki/Hex_editor
[2]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/01/Linux-hex-editors-800x450.jpeg?resize=800%2C450&ssl=1
[3]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/01/bless-hex-editor.jpg?ssl=1
[4]: https://github.com/bwrsandman/Bless
[5]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/01/ghex-hex-editor.jpg?ssl=1
[6]: https://github.com/GNOME/ghex
[7]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/01/okteta-hex-editor-800x466.jpg?resize=800%2C466&ssl=1
[8]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/01/wxhexeditor.jpg?ssl=1
[9]: https://sourceforge.net/projects/wxhexeditor/
[10]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/01/hexedit-console.jpg?resize=800%2C566&ssl=1
[11]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/01/Linux-hex-editors.jpeg?fit=800%2C450&ssl=1