1 Star 0 Fork 0

Ezra / Gole 1 Pro Linux Fix

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

高乐 Gole 1 Pro 安装 Linux 及后续问题修复

1. 免责声明

Caution

本文内容仅为交流目的,不保证在任何情况下均可达到预期效果,同时所涉及操作存在一定风险,因此造成的任何损失本人概不负责,请在继续操作前慎重考虑。

此外,请务必对数据进行备份,以免造成不必要的损失。

2. 写在前面

gole-1-pro.jpg

最近入手了一台高乐 Gole 1 Pro 小主机,自带了 5.5 英寸触摸屏和电池,十分小巧便携。

由于小主机没有自带风扇,所以为了降低发热,我分出 60GB 安装了 Kubuntu。其实系统的安装过程并没有什么特别,但安装之后存在一些重要的问题,需要手动解决,记录如下文。

Linux 下具体的问题表现为:

  • 没有 WiFi

  • 没有声音,但耳机可用

  • 始终显示 “未在充电”

  • 界面是旋转显示的状态

3. 问题修复

相关文件和包均已上传到 gitee 仓库:

sudo apt install git
git clone https://gitee.com/meniny/gole-1-pro-linux-fix.git
cd gole-1-pro-linux-fix/
Caution

虽然已经附带离线的内核以及网卡驱动、蓝牙驱动源代码等,但并没有附带编译工具、ALSA 的离线包,建议通过网线或 Linux 免驱的外置无线网卡连接到网络。

淘宝可以很容易找到 COMFAST CF-WU810N 外置无线网卡,大概不到 20 元。

3.1. 画面旋转

首先是屏幕旋转的问题,登录后桌面的旋转可以在设置中的显示设置中进行配置,各种桌面环境中都大同小异,这里就不赘述了。

比较重要的是登录界面旋转和触摸屏旋转。

3.1.1. 登录界面

由于我使用的是 Kubuntu,因此默认使用 sddm 作为 Display Manager

那么,首先我们确定一下显示器的名称:

xrandr

输出的结果显示:

Screen 0: minimum 320 x 200, current 1280 x 720, maximum 16384 x 16384
DSI-1 connected primary 1280x720+0+0 right (normal left inverted right x axis y axis) 0mm x 0mm
   720x1280      60.00*+
   1280x720      60.00
   960x720       60.00
...

这里记录 DSI-1 即可,接下来编辑 sddm 配置来旋转登录界面:

sudo nano /etc/sddm.conf

加入下面的内容,如果 [X11] 已经存在,则加入到已存在的组中即可:

[X11]
DisplayCommand=/usr/share/sddm/scripts/Xsetup

继续编辑 /usr/share/sddm/scripts/Xsetup 文件:

sudo nano /usr/share/sddm/scripts/Xsetup

加入下面的内容:

xrandr --output DSI-1 --rotate right

安装完成之后需要重启系统生效。

其他 DM 的旋转方法其实也大同小异,可以到 Google 搜索,例如 rotate lightdm, rotate gdm 等。

3.1.2. 触屏操控

接下来,你会发现触摸屏的操作是不正确的,点击与实际响应的位置不一致。

那么首先我们确认一下触屏设备的名称:

xinput -list

可以很明显的找到触屏设备,也即 Goodix Capacitive TouchScreen

⎡ Virtual core pointer                          id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ BY Tech Air60                             id=9    [slave  pointer  (2)]
⎜   ↳ Logitech MX Master 3                      id=11   [slave  pointer  (2)]
⎜   ↳ Telink Wireless Receiver Mouse            id=14   [slave  pointer  (2)]
⎜   ↳ Telink Wireless Receiver Consumer Control id=17   [slave  pointer  (2)]
⎜   ↳ Goodix Capacitive TouchScreen             id=20   [slave  pointer  (2)]
⎣ Virtual core keyboard                         id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    ↳ Power Button                              id=6    [slave  keyboard (3)]
    ↳ Video Bus                                 id=7    [slave  keyboard (3)]
    ↳ Telink Wireless Receiver System Control   id=8    [slave  keyboard (3)]
    ↳ BY Tech Air60                             id=10   [slave  keyboard (3)]
    ↳ Logitech MX Master 3                      id=12   [slave  keyboard (3)]
    ↳ Intel HID events                          id=13   [slave  keyboard (3)]
    ↳ Intel HID 5 button array                  id=15   [slave  keyboard (3)]
    ↳ Telink Wireless Receiver                  id=16   [slave  keyboard (3)]
    ↳ Telink Wireless Receiver Consumer Control id=18   [slave  keyboard (3)]
    ↳ BY Tech Air60                             id=19   [slave  keyboard (3)]
    ↳ Goodix Capacitive TouchScreen             id=21   [slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard              id=22   [slave  keyboard (3)]

接下来我们需要编辑 ~/.profile 文件:

nano ~/.profile

在文件末尾加入下面的命令:

# Rotate TouchScreen to Right
xrandr -o right
xinput set-prop 'pointer:Goodix Capacitive TouchScreen' 'Coordinate Transformation Matrix' 0 1 0 -1 0 1 0 0 1

保存后,执行 source ~/.profile 即可生效。

如果有兴趣,可以阅读 Ubuntu Wiki 文档 了解其背后的逻辑。

横竖切换

现在触摸屏可以正常工作了。如果希望随时切换横竖屏的话,我们需要创建两个脚本:

nano ~/landscape.sh
#!/bin/sh
# Rotate TouchScreen to Right
xrandr -o right
xinput set-prop 'pointer:Goodix Capacitive TouchScreen' 'Coordinate Transformation Matrix' 0 1 0 -1 0 1 0 0 1
nano ~/portrait.sh
#!/bin/sh
# Rotate TouchScreen back to Normal
xrandr -o normal
xinput set-prop 'pointer:Goodix Capacitive TouchScreen' 'Coordinate Transformation Matrix' 0 0 0 0 0 0 0 0 0

并通过 chmod +x ~/landscape.sh/chmod +x ~/portrait.sh 赋予执行权限,以后只需要根据需要运行这两个脚本中的一个,就可以进行横竖屏切换了。

更进一步的,你还可以创建两个图标方便操作:

nano ~/Desktop/landscape.desktop
[Desktop Entry]
Name=Landscape
Comment=Rotate the screen of Gole 1 Pro to landscape
Exec=bash -c 'xrandr -o right; xinput set-prop "pointer:Goodix Capacitive TouchScreen" "Coordinate Transformation Matrix" 0 1 0 -1 0 1 0 0 1'
Icon=utilities-terminal
Terminal=true
Type=Application
Categories=Application;
nano ~/Desktop/portrait.desktop
[Desktop Entry]
Name=Portrait
Comment=Rotate the screen of Gole 1 Pro to portrait
Exec=bash -c 'xrandr -o normal; xinput set-prop "pointer:Goodix Capacitive TouchScreen" "Coordinate Transformation Matrix" 0 0 0 0 0 0 0 0 0'
Icon=utilities-terminal
Terminal=true
Type=Application
Categories=Application;

并通过 chmod +x ~/Desktop/landscape.desktop/chmod +x ~/Desktop/portrait.desktop 赋予执行权限,以后只需要根据需要点击桌面上的图标,就可以进行横竖屏切换了。

tsicons.jpg

3.2. 内核回退

Caution

截止至本文完成时,最新的稳定内核是 6.2.0,但是网卡驱动并没有找到能5.18 以上内核运行正常的版本,所以只好回退内核到 5.15.0-79 版本。

sudo apt update
sudo apt --fix-missing install linux-headers-5.15.0-79_5.15.0-79.86_all.deb linux-headers-5.15.0-79-generic linux-image-5.15.0-79-generic linux-modules-5.15.0-79-generic linux-modules-extra-5.15.0-79-generic
Note

如果你现在没有网络,或者无法在 Ubuntu 仓库找到对应的包,可以直接安装 gitee 仓库中的相关包:

sudo dpkg -i linux-headers-5.15.0-79-generic_5.15.0-79.86_amd64.deb linux-image-5.15.0-79-generic_5.15.0-79.86_amd64.deb linux-modules-5.15.0-79-generic_5.15.0-79.86_amd64.deb linux-modules-extra-5.15.0-79-generic_5.15.0-79.86_amd64.deb

安装完成之后需要重启系统生效,并且在 GRUB 界面选择 Ubuntu, with kernel 5.15.0-79-generic 启动。

3.3. GRUB

3.3.1. 默认内核

方便起见可以直接修改 /etc/default/grub 通过 GRUB_DEFAULT=0 来控制默认的内核。

sudo nano /etc/default/grub

如果你的情况和我一样,在默认内核的基础上安装了上述的内核,那么 5.15.0-79-generic 很可能是 GRUB 菜单中 第 2 项的第 3 个子项。那么我们需要将 GRUB_DEFAULT=0 改为 GRUB_DEFAULT='1>2',因为所有的序列都是从 0 开始编号的。

完成后务必要执行 sudo update-grub 进行更新。

如果后续安装了新内核,最好确认一下是否需要更改默认内核。

grub.jpg

3.3.2. 终端旋转

类似的,我们还需要修改 GRUB_CMDLINE_LINUX_DEFAULTGRUB_CMDLINE_LINUXGRUB_GFXMODE 来旋转开关机时的终端界面:

GRUB_CMDLINE_LINUX_DEFAULT="video=efifb fbcon=rotate_all:1 quiet"
GRUB_CMDLINE_LINUX="video=efifb fbcon=rotate_all:1 quiet splash"

GRUB_GFXMODE=1280x720,auto

完成后需要执行 sudo update-grub重启系统生效。

3.4. 充电状态

如果充电状态或电量显示出现异常,需要安装 `linux-hwe-5.15-headers-5.15.0-79:

sudo apt install linux-hwe-5.15-headers-5.15.0-79
Note

如果你现在没有网络,或者无法在 Ubuntu 仓库找到对应的包,可以直接安装 gitee 仓库中的相关包:

sudo dpkg -i linux-hwe-5.15-headers-5.15.0-79_5.15.0-79.86~20.04.2_all.deb

安装完成之后需要重启系统生效,并且在 GRUB 界面选择 Ubuntu, with kernel 5.15.0-79-generic 启动。

3.5. 无线网络

由于驱动需要自己 make,所以我们需要安装依赖:

sudo apt --fix-missing install gcc bc make build-essential

接下来安装 rtl8852BE_WiFi_linux_v1.19.7.0-18-gee24b6aac.20230614_PC

cd rtl8852BE_WiFi_linux_v1.19.7.0-18-gee24b6aac.20230614_PC/
make -j8
sudo make install
sudo modprobe 8852be

安装完成之后需要重启系统生效,并且在 GRUB 界面选择 Ubuntu, with kernel 5.15.0-79-generic 启动。

3.6. 蓝牙扫描

你可能已经发现,此时蓝牙出现了异常,不能扫描甚至不能启动。现在我们来解决这个问题

#相对与刚才的网卡驱动目录
cd ../rtl8852be_bt
make
sudo make install
sudo modprobe btusb

安装完成之后需要重启系统生效,并且在 GRUB 界面选择 Ubuntu, with kernel 5.15.0-79-generic 启动。

3.7. 声音播放

当然,首先要确定驱动是否安装正常:

inxi -A

如果音频设备的 driver 显示 snd_hda_intel 则正常。

Audio:
  Device-1: Intel Celeron/Pentium Silver Processor High Definition Audio
    driver: snd_hda_intel
  Sound Server-1: ALSA v: k5.15.0-79-generic running: yes
  Sound Server-2: PulseAudio v: 15.99.1 running: yes
  Sound Server-3: PipeWire v: 0.3.48 running: yes

如果没有 inxi 可以通过 sudo apt install inxi 进行安装。

接下来安装 ALSA 相关工具:

sudo apt --fix-missing install alsa-base alsa-utils alsa-tools alsa-tools-gui alsamixergui

通过 aplay -l 可以看到我们的音频设备是 Realtek ALC269VB Analog

**** PLAYBACK 硬體裝置清單 ****
card 0: PCH [HDA Intel PCH], device 0: ALC269VB Analog [ALC269VB Analog]
  子设备: 1/1
  子设备 #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 3: HDMI 0 [HDMI 0]
  子设备: 1/1
  子设备 #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 7: HDMI 1 [HDMI 1]
  子设备: 1/1
  子设备 #0: subdevice #0
...

启动 HDAJackRetask

hdajackretask

在出现的 HDAJackRetask 程序界面中:

  • 最上方 Select a codec 处选择 Realtek ALC269VB

  • 勾选 Internel Speaker 一栏的 Override

  • 选择 Line Out (Front)

  • 点击 Install boot override

hdajackretask.jpg

安装完成之后需要重启系统生效,并且在 GRUB 界面选择 Ubuntu, with kernel 5.15.0-79-generic 启动。

Note

如果仍旧存在问题,可以尝试手动执行 sudo alsa force-reload

4. 扩展 TLDR;

至此,在 Linux (Kubuntu with kernel 5.15.0-79-generic) 环境下的网络、蓝牙、音频、画面等问题已经全部解决。

后续,如果感兴趣的话,在理论上你也可以手动编译内核,并加入正确的驱动。

可以通过以下页面获取资源:

Makefile 示例:

obj-m += thedriver.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

5. 其它

5.1. 自动登录

由于 Linux 系统可能没有自带屏幕触摸键盘,因此最好设置用户自动登录,以便在没有键盘的时候也可以登入系统。

5.2. 屏幕键盘

可以通过 sudo apt install onboard 安装 Onboard 屏幕键盘并设置开机启动,不过,它似乎并不能在登录界面使用。

onboard.jpg

5.3. 便携键鼠

日本品牌 SANWA400-SKB070 折叠键盘是个不错的选择,支持三个蓝牙连接,且自带了一个小型触控板。折叠后仅与一台 iPhone 14 尺寸相当。

当然,缺点也有,这个键盘没有 F1~F12 功能键,也没有 Escape 键,如果比较介意的话你也可以选择 GSKBBT30BK

sanwa.jpg

另一个推荐是 RII k06 迷你键盘,长度与 Gole 1 Pro 相当,支持蓝牙及 2.4G 双模式,自带触摸板,而且按键齐全。

rii.jpg

5.3.1. 键盘隐射

题外话,对于没有 Escape 键的问题,可以通过键盘映射来解决,在 Linux 中可以使用 Input RemapperWindows 中可以使用 PowerToymacOS 中可以使用 Karabiner Elements


Made with ♡ in Shenzhen

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="generator" content="Asciidoctor 2.0.20"> <meta name="author" content="Ezra"> <title>高乐 Gole 1 Pro 安装 Linux 及后续问题修复</title> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700"> <style> /*! Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */ /* Uncomment the following line when using as a custom stylesheet */ /* @import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700"; */ html{font-family:sans-serif;-webkit-text-size-adjust:100%} a{background:none} a:focus{outline:thin dotted} a:active,a:hover{outline:0} h1{font-size:2em;margin:.67em 0} b,strong{font-weight:bold} abbr{font-size:.9em} abbr[title]{cursor:help;border-bottom:1px dotted #dddddf;text-decoration:none} dfn{font-style:italic} hr{height:0} mark{background:#ff0;color:#000} code,kbd,pre,samp{font-family:monospace;font-size:1em} pre{white-space:pre-wrap} q{quotes:"\201C" "\201D" "\2018" "\2019"} small{font-size:80%} sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline} sup{top:-.5em} sub{bottom:-.25em} img{border:0} svg:not(:root){overflow:hidden} figure{margin:0} audio,video{display:inline-block} audio:not([controls]){display:none;height:0} fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em} legend{border:0;padding:0} button,input,select,textarea{font-family:inherit;font-size:100%;margin:0} button,input{line-height:normal} button,select{text-transform:none} button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer} button[disabled],html input[disabled]{cursor:default} input[type=checkbox],input[type=radio]{padding:0} button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0} textarea{overflow:auto;vertical-align:top} table{border-collapse:collapse;border-spacing:0} *,::before,::after{box-sizing:border-box} html,body{font-size:100%} body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;line-height:1;position:relative;cursor:auto;-moz-tab-size:4;-o-tab-size:4;tab-size:4;word-wrap:anywhere;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased} a:hover{cursor:pointer} img,object,embed{max-width:100%;height:auto} object,embed{height:100%} img{-ms-interpolation-mode:bicubic} .left{float:left!important} .right{float:right!important} .text-left{text-align:left!important} .text-right{text-align:right!important} .text-center{text-align:center!important} .text-justify{text-align:justify!important} .hide{display:none} img,object,svg{display:inline-block;vertical-align:middle} textarea{height:auto;min-height:50px} select{width:100%} .subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em} div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0} a{color:#2156a5;text-decoration:underline;line-height:inherit} a:hover,a:focus{color:#1d4b8f} a img{border:0} p{line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility} p aside{font-size:.875em;line-height:1.35;font-style:italic} h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em} h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0} h1{font-size:2.125em} h2{font-size:1.6875em} h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em} h4,h5{font-size:1.125em} h6{font-size:1em} hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em} em,i{font-style:italic;line-height:inherit} strong,b{font-weight:bold;line-height:inherit} small{font-size:60%;line-height:inherit} code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)} ul,ol,dl{line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit} ul,ol{margin-left:1.5em} ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0} ul.circle{list-style-type:circle} ul.disc{list-style-type:disc} ul.square{list-style-type:square} ul.circle ul:not([class]),ul.disc ul:not([class]),ul.square ul:not([class]){list-style:inherit} ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0} dl dt{margin-bottom:.3125em;font-weight:bold} dl dd{margin-bottom:1.25em} blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd} blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)} @media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2} h1{font-size:2.75em} h2{font-size:2.3125em} h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em} h4{font-size:1.4375em}} table{background:#fff;margin-bottom:1.25em;border:1px solid #dedede;word-wrap:normal} table thead,table tfoot{background:#f7f8f7} table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left} table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)} table tr.even,table tr.alt{background:#f8f8f7} table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{line-height:1.6} h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em} h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400} .center{margin-left:auto;margin-right:auto} .stretch{width:100%} .clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table} .clearfix::after,.float-group::after{clear:both} :not(pre).nobreak{word-wrap:normal} :not(pre).nowrap{white-space:nowrap} :not(pre).pre-wrap{white-space:pre-wrap} :not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed} pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed} pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit} pre>code{display:block} pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal} em em{font-style:normal} strong strong{font-weight:400} .keyseq{color:rgba(51,51,51,.8)} kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 0 rgba(0,0,0,.2),inset 0 0 0 .1em #fff;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap} .keyseq kbd:first-child{margin-left:0} .keyseq kbd:last-child{margin-right:0} .menuseq,.menuref{color:#000} .menuseq b:not(.caret),.menuref{font-weight:inherit} .menuseq{word-spacing:-.02em} .menuseq b.caret{font-size:1.25em;line-height:.8} .menuseq i.caret{font-weight:bold;text-align:center;width:.45em} b.button::before,b.button::after{position:relative;top:-1px;font-weight:400} b.button::before{content:"[";padding:0 3px 0 2px} b.button::after{content:"]";padding:0 2px 0 3px} p a>code:hover{color:rgba(0,0,0,.9)} #header,#content,#footnotes,#footer{width:100%;margin:0 auto;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em} #header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table} #header::after,#content::after,#footnotes::after,#footer::after{clear:both} #content{margin-top:1.25em} #content::before{content:none} #header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0} #header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf} #header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px} #header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap} #header .details span:first-child{margin-left:-.125em} #header .details span.email a{color:rgba(0,0,0,.85)} #header .details br{display:none} #header .details br+span::before{content:"\00a0\2013\00a0"} #header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)} #header .details br+span#revremark::before{content:"\00a0|\00a0"} #header #revnumber{text-transform:capitalize} #header #revnumber::after{content:"\00a0"} #content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem} #toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em} #toc>ul{margin-left:.125em} #toc ul.sectlevel0>li>a{font-style:italic} #toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0} #toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none} #toc li{line-height:1.3334;margin-top:.3334em} #toc a{text-decoration:none} #toc a:active{text-decoration:underline} #toctitle{color:#7a2518;font-size:1.2em} @media screen and (min-width:768px){#toctitle{font-size:1.375em} body.toc2{padding-left:15em;padding-right:0} #toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto} #toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em} #toc.toc2>ul{font-size:.9em;margin-bottom:0} #toc.toc2 ul ul{margin-left:0;padding-left:1em} #toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em} body.toc2.toc-right{padding-left:0;padding-right:15em} body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}} @media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0} #toc.toc2{width:20em} #toc.toc2 #toctitle{font-size:1.375em} #toc.toc2>ul{font-size:.95em} #toc.toc2 ul ul{padding-left:1.25em} body.toc2.toc-right{padding-left:0;padding-right:20em}} #content #toc{border:1px solid #e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;border-radius:4px} #content #toc>:first-child{margin-top:0} #content #toc>:last-child{margin-bottom:0} #footer{max-width:none;background:rgba(0,0,0,.8);padding:1.25em} #footer-text{color:hsla(0,0%,100%,.8);line-height:1.44} #content{margin-bottom:.625em} .sect1{padding-bottom:.625em} @media screen and (min-width:768px){#content{margin-bottom:1.25em} .sect1{padding-bottom:1.25em}} .sect1:last-child{padding-bottom:0} .sect1+.sect1{border-top:1px solid #e7e7e9} #content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400} #content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em} #content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible} #content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none} #content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221} details,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em} details{margin-left:1.25rem} details>summary{cursor:pointer;display:block;position:relative;line-height:1.6;margin-bottom:.625rem;outline:none;-webkit-tap-highlight-color:transparent} details>summary::-webkit-details-marker{display:none} details>summary::before{content:"";border:solid transparent;border-left:solid;border-width:.3em 0 .3em .5em;position:absolute;top:.5em;left:-1.25rem;transform:translateX(15%)} details[open]>summary::before{border:solid transparent;border-top:solid;border-width:.5em .3em 0;transform:translateY(15%)} details>summary::after{content:"";width:1.25rem;height:1em;position:absolute;top:.3em;left:-1.25rem} .admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic} table.tableblock.fit-content>caption.title{white-space:nowrap;width:0} .paragraph.lead>p,#preamble>.sectionbody>[class=paragraph]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)} .admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%} .admonitionblock>table td.icon{text-align:center;width:80px} .admonitionblock>table td.icon img{max-width:none} .admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase} .admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere} .admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0} .exampleblock>.content{border:1px solid #e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;border-radius:4px} .sidebarblock{border:1px solid #dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;border-radius:4px} .sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center} .exampleblock>.content>:first-child,.sidebarblock>.content>:first-child{margin-top:0} .exampleblock>.content>:last-child,.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0} .literalblock pre,.listingblock>.content>pre{border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em} @media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}} @media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}} .literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class=highlight],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8} .literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)} .listingblock>.content{position:relative} .listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5} .listingblock:hover code[data-lang]::before{display:block} .listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5} .listingblock.terminal pre .command:not([data-prompt])::before{content:"$"} .listingblock pre.highlightjs{padding:0} .listingblock pre.highlightjs>code{padding:1em;border-radius:4px} .listingblock pre.prettyprint{border-width:0} .prettyprint{background:#f7f7f8} pre.prettyprint .linenums{line-height:1.45;margin-left:2em} pre.prettyprint li{background:none;list-style-type:inherit;padding-left:0} pre.prettyprint li code[data-lang]::before{opacity:1} pre.prettyprint li:not(:first-child) code[data-lang]::before{display:none} table.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none} table.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal} table.linenotable td.code{padding-left:.75em} table.linenotable td.linenos,pre.pygments .linenos{border-right:1px solid;opacity:.35;padding-right:.5em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none} pre.pygments span.linenos{display:inline-block;margin-right:.75em} .quoteblock{margin:0 1em 1.25em 1.5em;display:table} .quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em} .quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify} .quoteblock blockquote{margin:0;padding:0;border:0} .quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)} .quoteblock blockquote>.paragraph:last-child p{margin-bottom:0} .quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right} .verseblock{margin:0 1em 1.25em} .verseblock pre{font-family:"Open Sans","DejaVu Sans",sans-serif;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility} .verseblock pre strong{font-weight:400} .verseblock .attribution{margin-top:1.25rem;margin-left:.5ex} .quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic} .quoteblock .attribution br,.verseblock .attribution br{display:none} .quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)} .quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none} .quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0} .quoteblock.abstract{margin:0 1em 1.25em;display:block} .quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center} .quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf} .quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0} .quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem} .quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;font-size:.85rem;text-align:left;margin-right:0} p.tableblock:last-child{margin-bottom:0} td.tableblock>.content{margin-bottom:1.25em;word-wrap:anywhere} td.tableblock>.content>:last-child{margin-bottom:-1.25em} table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede} table.grid-all>*>tr>*{border-width:1px} table.grid-cols>*>tr>*{border-width:0 1px} table.grid-rows>*>tr>*{border-width:1px 0} table.frame-all{border-width:1px} table.frame-ends{border-width:1px 0} table.frame-sides{border-width:0 1px} table.frame-none>colgroup+*>:first-child>*,table.frame-sides>colgroup+*>:first-child>*{border-top-width:0} table.frame-none>:last-child>:last-child>*,table.frame-sides>:last-child>:last-child>*{border-bottom-width:0} table.frame-none>*>tr>:first-child,table.frame-ends>*>tr>:first-child{border-left-width:0} table.frame-none>*>tr>:last-child,table.frame-ends>*>tr>:last-child{border-right-width:0} table.stripes-all>*>tr,table.stripes-odd>*>tr:nth-of-type(odd),table.stripes-even>*>tr:nth-of-type(even),table.stripes-hover>*>tr:hover{background:#f8f8f7} th.halign-left,td.halign-left{text-align:left} th.halign-right,td.halign-right{text-align:right} th.halign-center,td.halign-center{text-align:center} th.valign-top,td.valign-top{vertical-align:top} th.valign-bottom,td.valign-bottom{vertical-align:bottom} th.valign-middle,td.valign-middle{vertical-align:middle} table thead th,table tfoot th{font-weight:bold} tbody tr th{background:#f7f8f7} tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold} p.tableblock>code:only-child{background:none;padding:0} p.tableblock{font-size:1em} ol{margin-left:1.75em} ul li ol{margin-left:1.5em} dl dd{margin-left:1.125em} dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0} li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em} ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none} ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em} ul.unstyled,ol.unstyled{margin-left:0} li>p:empty:only-child::before{content:"";display:inline-block} ul.checklist>li>p:first-child{margin-left:-1em} ul.checklist>li>p:first-child>.fa-square-o:first-child,ul.checklist>li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em} ul.checklist>li>p:first-child>input[type=checkbox]:first-child{margin-right:.25em} ul.inline{display:flex;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em} ul.inline>li{margin-left:1.25em} .unstyled dl dt{font-weight:400;font-style:normal} ol.arabic{list-style-type:decimal} ol.decimal{list-style-type:decimal-leading-zero} ol.loweralpha{list-style-type:lower-alpha} ol.upperalpha{list-style-type:upper-alpha} ol.lowerroman{list-style-type:lower-roman} ol.upperroman{list-style-type:upper-roman} ol.lowergreek{list-style-type:lower-greek} .hdlist>table,.colist>table{border:0;background:none} .hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none} td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em} td.hdlist1{font-weight:bold;padding-bottom:1.25em} td.hdlist2{word-wrap:anywhere} .literalblock+.colist,.listingblock+.colist{margin-top:-.5em} .colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top} .colist td:not([class]):first-child img{max-width:none} .colist td:not([class]):last-child{padding:.25em 0} .thumb,.th{line-height:0;display:inline-block;border:4px solid #fff;box-shadow:0 0 0 1px #ddd} .imageblock.left{margin:.25em .625em 1.25em 0} .imageblock.right{margin:.25em 0 1.25em .625em} .imageblock>.title{margin-bottom:0} .imageblock.thumb,.imageblock.th{border-width:6px} .imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em} .image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0} .image.left{margin-right:.625em} .image.right{margin-left:.625em} a.image{text-decoration:none;display:inline-block} a.image object{pointer-events:none} sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super} sup.footnote a,sup.footnoteref a{text-decoration:none} sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline} #footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em} #footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0} #footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em} #footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em} #footnotes .footnote:last-of-type{margin-bottom:0} #content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0} div.unbreakable{page-break-inside:avoid} .big{font-size:larger} .small{font-size:smaller} .underline{text-decoration:underline} .overline{text-decoration:overline} .line-through{text-decoration:line-through} .aqua{color:#00bfbf} .aqua-background{background:#00fafa} .black{color:#000} .black-background{background:#000} .blue{color:#0000bf} .blue-background{background:#0000fa} .fuchsia{color:#bf00bf} .fuchsia-background{background:#fa00fa} .gray{color:#606060} .gray-background{background:#7d7d7d} .green{color:#006000} .green-background{background:#007d00} .lime{color:#00bf00} .lime-background{background:#00fa00} .maroon{color:#600000} .maroon-background{background:#7d0000} .navy{color:#000060} .navy-background{background:#00007d} .olive{color:#606000} .olive-background{background:#7d7d00} .purple{color:#600060} .purple-background{background:#7d007d} .red{color:#bf0000} .red-background{background:#fa0000} .silver{color:#909090} .silver-background{background:#bcbcbc} .teal{color:#006060} .teal-background{background:#007d7d} .white{color:#bfbfbf} .white-background{background:#fafafa} .yellow{color:#bfbf00} .yellow-background{background:#fafa00} span.icon>.fa{cursor:default} a span.icon>.fa{cursor:inherit} .admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default} .admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c} .admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111} .admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900} .admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400} .admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000} .conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);border-radius:50%;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold} .conum[data-value] *{color:#fff!important} .conum[data-value]+b{display:none} .conum[data-value]::after{content:attr(data-value)} pre .conum[data-value]{position:relative;top:-.125em} b.conum *{color:inherit!important} .conum:not([data-value]):empty{display:none} dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility} h1,h2,p,td.content,span.alt,summary{letter-spacing:-.01em} p strong,td.content strong,div.footnote strong{letter-spacing:-.005em} p,blockquote,dt,td.content,td.hdlist1,span.alt,summary{font-size:1.0625rem} p{margin-bottom:1.25rem} .sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em} .exampleblock>.content{background:#fffef7;border-color:#e0e0dc;box-shadow:0 1px 4px #e0e0dc} .print-only{display:none!important} @page{margin:1.25cm .75cm} @media print{*{box-shadow:none!important;text-shadow:none!important} html{font-size:80%} a{color:inherit!important;text-decoration:underline!important} a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important} a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em} abbr[title]{border-bottom:1px dotted} abbr[title]::after{content:" (" attr(title) ")"} pre,blockquote,tr,img,object,svg{page-break-inside:avoid} thead{display:table-header-group} svg{max-width:100%} p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3} h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid} #header,#content,#footnotes,#footer{max-width:none} #toc,.sidebarblock,.exampleblock>.content{background:none!important} #toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important} body.book #header{text-align:center} body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em} body.book #header .details{border:0!important;display:block;padding:0!important} body.book #header .details span:first-child{margin-left:0!important} body.book #header .details br{display:block} body.book #header .details br+span::before{content:none!important} body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important} body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always} .listingblock code[data-lang]::before{display:block} #footer{padding:0 .9375em} .hide-on-print{display:none!important} .print-only{display:block!important} .hide-for-print{display:none!important} .show-for-print{display:inherit!important}} @media amzn-kf8,print{#header>h1:first-child{margin-top:1.25rem} .sect1{padding:0!important} .sect1+.sect1{border:0} #footer{background:none} #footer-text{color:rgba(0,0,0,.6);font-size:.9em}} @media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}} </style> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> <style> pre.rouge table td { padding: 5px; } pre.rouge table pre { margin: 0; } pre.rouge, pre.rouge .w { color: #24292f; background-color: #f6f8fa; } pre.rouge .k, pre.rouge .kd, pre.rouge .kn, pre.rouge .kp, pre.rouge .kr, pre.rouge .kt, pre.rouge .kv { color: #cf222e; } pre.rouge .gr { color: #f6f8fa; } pre.rouge .gd { color: #82071e; background-color: #ffebe9; } pre.rouge .nb { color: #953800; } pre.rouge .nc { color: #953800; } pre.rouge .no { color: #953800; } pre.rouge .nn { color: #953800; } pre.rouge .sr { color: #116329; } pre.rouge .na { color: #116329; } pre.rouge .nt { color: #116329; } pre.rouge .gi { color: #116329; background-color: #dafbe1; } pre.rouge .kc { color: #0550ae; } pre.rouge .l, pre.rouge .ld, pre.rouge .m, pre.rouge .mb, pre.rouge .mf, pre.rouge .mh, pre.rouge .mi, pre.rouge .il, pre.rouge .mo, pre.rouge .mx { color: #0550ae; } pre.rouge .sb { color: #0550ae; } pre.rouge .bp { color: #0550ae; } pre.rouge .ne { color: #0550ae; } pre.rouge .nl { color: #0550ae; } pre.rouge .py { color: #0550ae; } pre.rouge .nv, pre.rouge .vc, pre.rouge .vg, pre.rouge .vi, pre.rouge .vm { color: #0550ae; } pre.rouge .o, pre.rouge .ow { color: #0550ae; } pre.rouge .gh { color: #0550ae; font-weight: bold; } pre.rouge .gu { color: #0550ae; font-weight: bold; } pre.rouge .s, pre.rouge .sa, pre.rouge .sc, pre.rouge .dl, pre.rouge .sd, pre.rouge .s2, pre.rouge .se, pre.rouge .sh, pre.rouge .sx, pre.rouge .s1, pre.rouge .ss { color: #0a3069; } pre.rouge .nd { color: #8250df; } pre.rouge .nf, pre.rouge .fm { color: #8250df; } pre.rouge .err { color: #f6f8fa; background-color: #82071e; } pre.rouge .c, pre.rouge .ch, pre.rouge .cd, pre.rouge .cm, pre.rouge .cp, pre.rouge .cpf, pre.rouge .c1, pre.rouge .cs { color: #6e7781; } pre.rouge .gl { color: #6e7781; } pre.rouge .gt { color: #6e7781; } pre.rouge .ni { color: #24292f; } pre.rouge .si { color: #24292f; } pre.rouge .ge { color: #24292f; font-style: italic; } pre.rouge .gs { color: #24292f; font-weight: bold; } </style> </head> <body class="article toc2 toc-left"> <div id="header"> <h1>高乐 <code>Gole 1 Pro</code> 安装 Linux 及后续问题修复</h1> <div class="details"> <span id="author" class="author">Ezra</span><br> <span id="email" class="email"><a href="mailto:ezra@hotodogo.com">ezra@hotodogo.com</a></span><br> <span id="revnumber"> 1.0.3,</span> <span id="revdate">August 24th, 2023</span> </div> <div id="toc" class="toc2"> <div id="toctitle">索引</div> <ul class="sectlevel1"> <li><a href="#_免责声明">1. 免责声明</a></li> <li><a href="#_写在前面">2. 写在前面</a></li> <li><a href="#_问题修复">3. 问题修复</a> <ul class="sectlevel2"> <li><a href="#_画面旋转">3.1. 画面旋转</a> <ul class="sectlevel3"> <li><a href="#_登录界面">3.1.1. 登录界面</a></li> <li><a href="#_触屏操控">3.1.2. 触屏操控</a> <ul class="sectlevel4"> <li><a href="#_横竖切换">横竖切换</a></li> </ul> </li> </ul> </li> <li><a href="#_内核回退">3.2. 内核回退</a></li> <li><a href="#_grub">3.3. GRUB</a> <ul class="sectlevel3"> <li><a href="#_默认内核">3.3.1. 默认内核</a></li> <li><a href="#_终端旋转">3.3.2. 终端旋转</a></li> </ul> </li> <li><a href="#_充电状态">3.4. 充电状态</a></li> <li><a href="#_无线网络">3.5. 无线网络</a></li> <li><a href="#_蓝牙扫描">3.6. 蓝牙扫描</a></li> <li><a href="#_声音播放">3.7. 声音播放</a></li> </ul> </li> <li><a href="#_扩展_tldr">4. 扩展 TLDR;</a></li> <li><a href="#_其它">5. 其它</a> <ul class="sectlevel2"> <li><a href="#_自动登录">5.1. 自动登录</a></li> <li><a href="#_屏幕键盘">5.2. 屏幕键盘</a></li> <li><a href="#_便携键鼠">5.3. 便携键鼠</a> <ul class="sectlevel3"> <li><a href="#_键盘隐射">5.3.1. 键盘隐射</a></li> </ul> </li> </ul> </li> </ul> </div> </div> <div id="content"> <div id="preamble"> <div class="sectionbody"> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> <div class="paragraph"> <p>See <a href="https://hotodogo.com/blog/post/name/gole-1-pro-linux-fix/">https://hotodogo.com/blog/post/name/gole-1-pro-linux-fix/</a> for more information.</p> </div> </td> </tr> </table> </div> </div> </div> <div class="sect1"> <h2 id="_免责声明"><a class="anchor" href="#_免责声明"></a><a class="link" href="#_免责声明">1. 免责声明</a></h2> <div class="sectionbody"> <div class="admonitionblock caution"> <table> <tr> <td class="icon"> <i class="fa icon-caution" title="Caution"></i> </td> <td class="content"> <div class="paragraph"> <p>本文内容仅为交流目的,不保证在任何情况下均可达到预期效果,同时所涉及操作存在一定风险,因此造成的任何损失本人概不负责,请在继续操作前慎重考虑。</p> </div> <div class="paragraph"> <p>此外,请务必对数据进行备份,以免造成不必要的损失。</p> </div> </td> </tr> </table> </div> </div> </div> <div class="sect1"> <h2 id="_写在前面"><a class="anchor" href="#_写在前面"></a><a class="link" href="#_写在前面">2. 写在前面</a></h2> <div class="sectionbody"> <div class="imageblock"> <div class="content"> <img src="gole-1-pro.jpg" alt="gole-1-pro.jpg" width="75%"> </div> </div> <div class="paragraph"> <p>最近入手了一台高乐 <code>Gole 1 Pro</code> 小主机,自带了 5.5 英寸触摸屏和电池,十分小巧便携。</p> </div> <div class="paragraph"> <p>由于小主机没有自带风扇,所以为了降低发热,我分出 60GB 安装了 <code>Kubuntu</code>。其实系统的安装过程并没有什么特别,但安装之后存在一些重要的问题,需要手动解决,记录如下文。</p> </div> <div class="quoteblock"> <blockquote> <div class="paragraph"> <p>Linux 下具体的问题表现为:</p> </div> <div class="ulist"> <ul> <li> <p>没有 <code>WiFi</code></p> </li> <li> <p>没有声音,但耳机可用</p> </li> <li> <p>始终显示 <code>“未在充电”</code></p> </li> <li> <p>界面是旋转显示的状态</p> </li> </ul> </div> </blockquote> </div> </div> </div> <div class="sect1"> <h2 id="_问题修复"><a class="anchor" href="#_问题修复"></a><a class="link" href="#_问题修复">3. 问题修复</a></h2> <div class="sectionbody"> <div class="paragraph"> <p>相关文件和包均已上传到 <code>gitee</code> 仓库:</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh"><span class="nb">sudo </span>apt <span class="nb">install </span>git git clone https://gitee.com/meniny/gole-1-pro-linux-fix.git <span class="nb">cd </span>gole-1-pro-linux-fix/</code></pre> </div> </div> <div class="admonitionblock caution"> <table> <tr> <td class="icon"> <i class="fa icon-caution" title="Caution"></i> </td> <td class="content"> <div class="paragraph"> <p>虽然已经附带离线的内核以及网卡驱动、蓝牙驱动源代码等,但并没有附带编译工具、<code>ALSA</code> 的离线包,建议通过网线或 <code>Linux</code> 免驱的外置无线网卡连接到网络。</p> </div> <div class="paragraph"> <p>淘宝可以很容易找到 <code>COMFAST CF-WU810N</code> 外置无线网卡,大概不到 20 元。</p> </div> </td> </tr> </table> </div> <div class="sect2"> <h3 id="_画面旋转"><a class="anchor" href="#_画面旋转"></a><a class="link" href="#_画面旋转">3.1. 画面旋转</a></h3> <div class="paragraph"> <p>首先是屏幕旋转的问题,登录后桌面的旋转可以在设置中的显示设置中进行配置,各种桌面环境中都大同小异,这里就不赘述了。</p> </div> <div class="paragraph"> <p>比较重要的是登录界面旋转和触摸屏旋转。</p> </div> <div class="sect3"> <h4 id="_登录界面"><a class="anchor" href="#_登录界面"></a><a class="link" href="#_登录界面">3.1.1. 登录界面</a></h4> <div class="paragraph"> <p>由于我使用的是 <code>Kubuntu</code>,因此默认使用 <code>sddm</code> 作为 <code>Display Manager</code>。</p> </div> <div class="paragraph"> <p>那么,首先我们确定一下显示器的名称:</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh">xrandr</code></pre> </div> </div> <div class="paragraph"> <p>输出的结果显示:</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh">Screen 0: minimum 320 x 200, current 1280 x 720, maximum 16384 x 16384 DSI-1 connected primary 1280x720+0+0 right <span class="o">(</span>normal left inverted right x axis y axis<span class="o">)</span> 0mm x 0mm 720x1280 60.00<span class="k">*</span>+ 1280x720 60.00 960x720 60.00 ...</code></pre> </div> </div> <div class="paragraph"> <p>这里记录 <code>DSI-1</code> 即可,接下来编辑 <code>sddm</code> 配置来旋转登录界面:</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh"><span class="nb">sudo </span>nano /etc/sddm.conf</code></pre> </div> </div> <div class="paragraph"> <p>加入下面的内容,如果 <code>[X11]</code> 已经存在,则加入到已存在的组中即可:</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh"><span class="o">[</span>X11] <span class="nv">DisplayCommand</span><span class="o">=</span>/usr/share/sddm/scripts/Xsetup</code></pre> </div> </div> <div class="paragraph"> <p>继续编辑 <code>/usr/share/sddm/scripts/Xsetup</code> 文件:</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh"><span class="nb">sudo </span>nano /usr/share/sddm/scripts/Xsetup</code></pre> </div> </div> <div class="paragraph"> <p>加入下面的内容:</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh">xrandr <span class="nt">--output</span> DSI-1 <span class="nt">--rotate</span> right</code></pre> </div> </div> <div class="paragraph"> <p>安装完成之后需要<strong>重启系统</strong>生效。</p> </div> <div class="quoteblock"> <blockquote> <div class="paragraph"> <p>其他 <code>DM</code> 的旋转方法其实也大同小异,可以到 <code>Google</code> 搜索,例如 <code>rotate lightdm</code>, <code>rotate gdm</code> 等。</p> </div> </blockquote> </div> </div> <div class="sect3"> <h4 id="_触屏操控"><a class="anchor" href="#_触屏操控"></a><a class="link" href="#_触屏操控">3.1.2. 触屏操控</a></h4> <div class="paragraph"> <p>接下来,你会发现触摸屏的操作是不正确的,点击与实际响应的位置不一致。</p> </div> <div class="paragraph"> <p>那么首先我们确认一下触屏设备的名称:</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh">xinput <span class="nt">-list</span></code></pre> </div> </div> <div class="paragraph"> <p>可以很明显的找到触屏设备,也即 <code>Goodix Capacitive TouchScreen</code>:</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh">⎡ Virtual core pointer <span class="nb">id</span><span class="o">=</span>2 <span class="o">[</span>master pointer <span class="o">(</span>3<span class="o">)]</span> ⎜ ↳ Virtual core XTEST pointer <span class="nb">id</span><span class="o">=</span>4 <span class="o">[</span>slave pointer <span class="o">(</span>2<span class="o">)]</span> ⎜ ↳ BY Tech Air60 <span class="nb">id</span><span class="o">=</span>9 <span class="o">[</span>slave pointer <span class="o">(</span>2<span class="o">)]</span> ⎜ ↳ Logitech MX Master 3 <span class="nb">id</span><span class="o">=</span>11 <span class="o">[</span>slave pointer <span class="o">(</span>2<span class="o">)]</span> ⎜ ↳ Telink Wireless Receiver Mouse <span class="nb">id</span><span class="o">=</span>14 <span class="o">[</span>slave pointer <span class="o">(</span>2<span class="o">)]</span> ⎜ ↳ Telink Wireless Receiver Consumer Control <span class="nb">id</span><span class="o">=</span>17 <span class="o">[</span>slave pointer <span class="o">(</span>2<span class="o">)]</span> ⎜ ↳ Goodix Capacitive TouchScreen <span class="nb">id</span><span class="o">=</span>20 <span class="o">[</span>slave pointer <span class="o">(</span>2<span class="o">)]</span> ⎣ Virtual core keyboard <span class="nb">id</span><span class="o">=</span>3 <span class="o">[</span>master keyboard <span class="o">(</span>2<span class="o">)]</span> ↳ Virtual core XTEST keyboard <span class="nb">id</span><span class="o">=</span>5 <span class="o">[</span>slave keyboard <span class="o">(</span>3<span class="o">)]</span> ↳ Power Button <span class="nb">id</span><span class="o">=</span>6 <span class="o">[</span>slave keyboard <span class="o">(</span>3<span class="o">)]</span> ↳ Video Bus <span class="nb">id</span><span class="o">=</span>7 <span class="o">[</span>slave keyboard <span class="o">(</span>3<span class="o">)]</span> ↳ Telink Wireless Receiver System Control <span class="nb">id</span><span class="o">=</span>8 <span class="o">[</span>slave keyboard <span class="o">(</span>3<span class="o">)]</span> ↳ BY Tech Air60 <span class="nb">id</span><span class="o">=</span>10 <span class="o">[</span>slave keyboard <span class="o">(</span>3<span class="o">)]</span> ↳ Logitech MX Master 3 <span class="nb">id</span><span class="o">=</span>12 <span class="o">[</span>slave keyboard <span class="o">(</span>3<span class="o">)]</span> ↳ Intel HID events <span class="nb">id</span><span class="o">=</span>13 <span class="o">[</span>slave keyboard <span class="o">(</span>3<span class="o">)]</span> ↳ Intel HID 5 button array <span class="nb">id</span><span class="o">=</span>15 <span class="o">[</span>slave keyboard <span class="o">(</span>3<span class="o">)]</span> ↳ Telink Wireless Receiver <span class="nb">id</span><span class="o">=</span>16 <span class="o">[</span>slave keyboard <span class="o">(</span>3<span class="o">)]</span> ↳ Telink Wireless Receiver Consumer Control <span class="nb">id</span><span class="o">=</span>18 <span class="o">[</span>slave keyboard <span class="o">(</span>3<span class="o">)]</span> ↳ BY Tech Air60 <span class="nb">id</span><span class="o">=</span>19 <span class="o">[</span>slave keyboard <span class="o">(</span>3<span class="o">)]</span> ↳ Goodix Capacitive TouchScreen <span class="nb">id</span><span class="o">=</span>21 <span class="o">[</span>slave keyboard <span class="o">(</span>3<span class="o">)]</span> ↳ AT Translated Set 2 keyboard <span class="nb">id</span><span class="o">=</span>22 <span class="o">[</span>slave keyboard <span class="o">(</span>3<span class="o">)]</span></code></pre> </div> </div> <div class="paragraph"> <p>接下来我们需要编辑 <code>~/.profile</code> 文件:</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh">nano ~/.profile</code></pre> </div> </div> <div class="paragraph"> <p>在文件末尾加入下面的命令:</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh"><span class="c"># Rotate TouchScreen to Right</span> xrandr <span class="nt">-o</span> right xinput set-prop <span class="s1">'pointer:Goodix Capacitive TouchScreen'</span> <span class="s1">'Coordinate Transformation Matrix'</span> 0 1 0 <span class="nt">-1</span> 0 1 0 0 1</code></pre> </div> </div> <div class="paragraph"> <p>保存后,执行 <code>source ~/.profile</code> 即可生效。</p> </div> <div class="quoteblock"> <blockquote> <div class="paragraph"> <p>如果有兴趣,可以阅读 <a href="https://wiki.ubuntu.com/X/InputCoordinateTransformation">Ubuntu Wiki 文档</a> 了解其背后的逻辑。</p> </div> </blockquote> </div> <div class="sect4"> <h5 id="_横竖切换"><a class="anchor" href="#_横竖切换"></a><a class="link" href="#_横竖切换">横竖切换</a></h5> <div class="paragraph"> <p>现在触摸屏可以正常工作了。如果希望随时切换横竖屏的话,我们需要创建两个脚本:</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh">nano ~/landscape.sh</code></pre> </div> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh"><span class="c">#!/bin/sh</span> <span class="c"># Rotate TouchScreen to Right</span> xrandr <span class="nt">-o</span> right xinput set-prop <span class="s1">'pointer:Goodix Capacitive TouchScreen'</span> <span class="s1">'Coordinate Transformation Matrix'</span> 0 1 0 <span class="nt">-1</span> 0 1 0 0 1</code></pre> </div> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh">nano ~/portrait.sh</code></pre> </div> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh"><span class="c">#!/bin/sh</span> <span class="c"># Rotate TouchScreen back to Normal</span> xrandr <span class="nt">-o</span> normal xinput set-prop <span class="s1">'pointer:Goodix Capacitive TouchScreen'</span> <span class="s1">'Coordinate Transformation Matrix'</span> 0 0 0 0 0 0 0 0 0</code></pre> </div> </div> <div class="paragraph"> <p>并通过 <code>chmod +x ~/landscape.sh</code>/<code>chmod +x ~/portrait.sh</code> 赋予执行权限,以后只需要根据需要运行这两个脚本中的一个,就可以进行横竖屏切换了。</p> </div> <div class="paragraph"> <p>更进一步的,你还可以创建两个图标方便操作:</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh">nano ~/Desktop/landscape.desktop</code></pre> </div> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh"><span class="o">[</span>Desktop Entry] <span class="nv">Name</span><span class="o">=</span>Landscape <span class="nv">Comment</span><span class="o">=</span>Rotate the screen of Gole 1 Pro to landscape <span class="nv">Exec</span><span class="o">=</span>bash <span class="nt">-c</span> <span class="s1">'xrandr -o right; xinput set-prop "pointer:Goodix Capacitive TouchScreen" "Coordinate Transformation Matrix" 0 1 0 -1 0 1 0 0 1'</span> <span class="nv">Icon</span><span class="o">=</span>utilities-terminal <span class="nv">Terminal</span><span class="o">=</span><span class="nb">true </span><span class="nv">Type</span><span class="o">=</span>Application <span class="nv">Categories</span><span class="o">=</span>Application<span class="p">;</span></code></pre> </div> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh">nano ~/Desktop/portrait.desktop</code></pre> </div> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh"><span class="o">[</span>Desktop Entry] <span class="nv">Name</span><span class="o">=</span>Portrait <span class="nv">Comment</span><span class="o">=</span>Rotate the screen of Gole 1 Pro to portrait <span class="nv">Exec</span><span class="o">=</span>bash <span class="nt">-c</span> <span class="s1">'xrandr -o normal; xinput set-prop "pointer:Goodix Capacitive TouchScreen" "Coordinate Transformation Matrix" 0 0 0 0 0 0 0 0 0'</span> <span class="nv">Icon</span><span class="o">=</span>utilities-terminal <span class="nv">Terminal</span><span class="o">=</span><span class="nb">true </span><span class="nv">Type</span><span class="o">=</span>Application <span class="nv">Categories</span><span class="o">=</span>Application<span class="p">;</span></code></pre> </div> </div> <div class="paragraph"> <p>并通过 <code>chmod +x ~/Desktop/landscape.desktop</code>/<code>chmod +x ~/Desktop/portrait.desktop</code> 赋予执行权限,以后只需要根据需要点击桌面上的图标,就可以进行横竖屏切换了。</p> </div> <div class="imageblock"> <div class="content"> <img src="tsicons.jpg" alt="tsicons.jpg" width="30%"> </div> </div> </div> </div> </div> <div class="sect2"> <h3 id="_内核回退"><a class="anchor" href="#_内核回退"></a><a class="link" href="#_内核回退">3.2. 内核回退</a></h3> <div class="admonitionblock caution"> <table> <tr> <td class="icon"> <i class="fa icon-caution" title="Caution"></i> </td> <td class="content"> <div class="paragraph"> <p>截止至本文完成时,最新的稳定内核是 <code>6.2.0</code>,但是网卡驱动并没有找到能<a href="https://github.com/lwfinger/rtw89">在 <code>5.18</code> 以上内核运行</a>正常的版本,所以只好回退内核到 <code>5.15.0-79</code> 版本。</p> </div> </td> </tr> </table> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh"><span class="nb">sudo </span>apt update <span class="nb">sudo </span>apt <span class="nt">--fix-missing</span> <span class="nb">install </span>linux-headers-5.15.0-79_5.15.0-79.86_all.deb linux-headers-5.15.0-79-generic linux-image-5.15.0-79-generic linux-modules-5.15.0-79-generic linux-modules-extra-5.15.0-79-generic</code></pre> </div> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> <div class="paragraph"> <p>如果你现在没有网络,或者无法在 <code>Ubuntu</code> 仓库找到对应的包,可以直接安装 <code>gitee</code> 仓库中的相关包:</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh"><span class="nb">sudo </span>dpkg <span class="nt">-i</span> linux-headers-5.15.0-79-generic_5.15.0-79.86_amd64.deb linux-image-5.15.0-79-generic_5.15.0-79.86_amd64.deb linux-modules-5.15.0-79-generic_5.15.0-79.86_amd64.deb linux-modules-extra-5.15.0-79-generic_5.15.0-79.86_amd64.deb</code></pre> </div> </div> </td> </tr> </table> </div> <div class="paragraph"> <p>安装完成之后需要<strong>重启系统</strong>生效,并且<strong>在 GRUB 界面选择 Ubuntu, with kernel 5.15.0-79-generic</strong> 启动。</p> </div> </div> <div class="sect2"> <h3 id="_grub"><a class="anchor" href="#_grub"></a><a class="link" href="#_grub">3.3. GRUB</a></h3> <div class="sect3"> <h4 id="_默认内核"><a class="anchor" href="#_默认内核"></a><a class="link" href="#_默认内核">3.3.1. 默认内核</a></h4> <div class="paragraph"> <p>方便起见可以直接修改 <code>/etc/default/grub</code> 通过 <code>GRUB_DEFAULT=0</code> 来控制默认的内核。</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh"><span class="nb">sudo </span>nano /etc/default/grub</code></pre> </div> </div> <div class="paragraph"> <p>如果你的情况和我一样,在默认内核的基础上安装了上述的内核,那么 <code>5.15.0-79-generic</code> 很可能是 <code>GRUB</code> 菜单中 <span class="underline">第 2 项的第 3 个子项</span>。那么我们需要将 <code>GRUB_DEFAULT=0</code> 改为 <code>GRUB_DEFAULT='1&gt;2'</code>,因为所有的序列都是从 <code>0</code> 开始编号的。</p> </div> <div class="paragraph"> <p>完成后<strong>务必</strong>要执行 <code>sudo update-grub</code> 进行更新。</p> </div> <div class="paragraph"> <p>如果后续安装了新内核,最好确认一下是否需要更改默认内核。</p> </div> <div class="paragraph"> <p><span class="image"><img src="grub.jpg" alt="grub.jpg" width="50%"></span></p> </div> </div> <div class="sect3"> <h4 id="_终端旋转"><a class="anchor" href="#_终端旋转"></a><a class="link" href="#_终端旋转">3.3.2. 终端旋转</a></h4> <div class="paragraph"> <p>类似的,我们还需要修改 <code>GRUB_CMDLINE_LINUX_DEFAULT</code>、<code>GRUB_CMDLINE_LINUX</code>、<code>GRUB_GFXMODE</code> 来旋转开关机时的终端界面:</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh"><span class="nv">GRUB_CMDLINE_LINUX_DEFAULT</span><span class="o">=</span><span class="s2">"video=efifb fbcon=rotate_all:1 quiet"</span> <span class="nv">GRUB_CMDLINE_LINUX</span><span class="o">=</span><span class="s2">"video=efifb fbcon=rotate_all:1 quiet splash"</span> <span class="nv">GRUB_GFXMODE</span><span class="o">=</span>1280x720,auto</code></pre> </div> </div> <div class="paragraph"> <p>完成后需要执行 <code>sudo update-grub</code> 并<strong>重启系统</strong>生效。</p> </div> </div> </div> <div class="sect2"> <h3 id="_充电状态"><a class="anchor" href="#_充电状态"></a><a class="link" href="#_充电状态">3.4. 充电状态</a></h3> <div class="paragraph"> <p>如果充电状态或电量显示出现异常,需要安装 `linux-hwe-5.15-headers-5.15.0-79:</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh"><span class="nb">sudo </span>apt <span class="nb">install </span>linux-hwe-5.15-headers-5.15.0-79</code></pre> </div> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> <div class="paragraph"> <p>如果你现在没有网络,或者无法在 <code>Ubuntu</code> 仓库找到对应的包,可以直接安装 <code>gitee</code> 仓库中的相关包:</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh"><span class="nb">sudo </span>dpkg <span class="nt">-i</span> linux-hwe-5.15-headers-5.15.0-79_5.15.0-79.86~20.04.2_all.deb</code></pre> </div> </div> </td> </tr> </table> </div> <div class="paragraph"> <p>安装完成之后需要<strong>重启系统</strong>生效,并且<strong>在 GRUB 界面选择 Ubuntu, with kernel 5.15.0-79-generic</strong> 启动。</p> </div> </div> <div class="sect2"> <h3 id="_无线网络"><a class="anchor" href="#_无线网络"></a><a class="link" href="#_无线网络">3.5. 无线网络</a></h3> <div class="paragraph"> <p>由于驱动需要自己 <code>make</code>,所以我们需要安装依赖:</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh"><span class="nb">sudo </span>apt <span class="nt">--fix-missing</span> <span class="nb">install </span>gcc bc make build-essential</code></pre> </div> </div> <div class="paragraph"> <p>接下来安装 <code>rtl8852BE_WiFi_linux_v1.19.7.0-18-gee24b6aac.20230614_PC</code>:</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh"><span class="nb">cd </span>rtl8852BE_WiFi_linux_v1.19.7.0-18-gee24b6aac.20230614_PC/ make <span class="nt">-j8</span> <span class="nb">sudo </span>make <span class="nb">install sudo </span>modprobe 8852be</code></pre> </div> </div> <div class="paragraph"> <p>安装完成之后需要<strong>重启系统</strong>生效,并且<strong>在 GRUB 界面选择 Ubuntu, with kernel 5.15.0-79-generic</strong> 启动。</p> </div> </div> <div class="sect2"> <h3 id="_蓝牙扫描"><a class="anchor" href="#_蓝牙扫描"></a><a class="link" href="#_蓝牙扫描">3.6. 蓝牙扫描</a></h3> <div class="paragraph"> <p>你可能已经发现,此时蓝牙出现了异常,不能扫描甚至不能启动。现在我们来<a href="https://github.com/HRex39/rtl8852be_bt.git">解决这个问题</a>:</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh"><span class="c">#相对与刚才的网卡驱动目录</span> <span class="nb">cd</span> ../rtl8852be_bt make <span class="nb">sudo </span>make <span class="nb">install sudo </span>modprobe btusb</code></pre> </div> </div> <div class="paragraph"> <p>安装完成之后需要<strong>重启系统</strong>生效,并且<strong>在 GRUB 界面选择 Ubuntu, with kernel 5.15.0-79-generic</strong> 启动。</p> </div> </div> <div class="sect2"> <h3 id="_声音播放"><a class="anchor" href="#_声音播放"></a><a class="link" href="#_声音播放">3.7. 声音播放</a></h3> <div class="paragraph"> <p>当然,首先要确定驱动是否安装正常:</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh">inxi <span class="nt">-A</span></code></pre> </div> </div> <div class="paragraph"> <p>如果音频设备的 <code>driver</code> 显示 <code>snd_hda_intel</code> 则正常。</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh">Audio: Device-1: Intel Celeron/Pentium Silver Processor High Definition Audio driver: snd_hda_intel Sound Server-1: ALSA v: k5.15.0-79-generic running: <span class="nb">yes </span>Sound Server-2: PulseAudio v: 15.99.1 running: <span class="nb">yes </span>Sound Server-3: PipeWire v: 0.3.48 running: <span class="nb">yes</span></code></pre> </div> </div> <div class="quoteblock"> <blockquote> <div class="paragraph"> <p>如果没有 <code>inxi</code> 可以通过 <code>sudo apt install inxi</code> 进行安装。</p> </div> </blockquote> </div> <div class="paragraph"> <p>接下来安装 <code>ALSA</code> 相关工具:</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh"><span class="nb">sudo </span>apt <span class="nt">--fix-missing</span> <span class="nb">install </span>alsa-base alsa-utils alsa-tools alsa-tools-gui alsamixergui</code></pre> </div> </div> <div class="paragraph"> <p>通过 <code>aplay -l</code> 可以看到我们的音频设备是 <code>Realtek ALC269VB Analog</code>。</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh"><span class="k">****</span> PLAYBACK 硬體裝置清單 <span class="k">****</span> card 0: PCH <span class="o">[</span>HDA Intel PCH], device 0: ALC269VB Analog <span class="o">[</span>ALC269VB Analog] 子设备: 1/1 子设备 <span class="c">#0: subdevice #0</span> card 0: PCH <span class="o">[</span>HDA Intel PCH], device 3: HDMI 0 <span class="o">[</span>HDMI 0] 子设备: 1/1 子设备 <span class="c">#0: subdevice #0</span> card 0: PCH <span class="o">[</span>HDA Intel PCH], device 7: HDMI 1 <span class="o">[</span>HDMI 1] 子设备: 1/1 子设备 <span class="c">#0: subdevice #0</span> ...</code></pre> </div> </div> <div class="paragraph"> <p>启动 <code>HDAJackRetask</code>:</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh">hdajackretask</code></pre> </div> </div> <div class="paragraph"> <p>在出现的 <code>HDAJackRetask</code> 程序界面中:</p> </div> <div class="ulist"> <ul> <li> <p>最上方 <code>Select a codec</code> 处选择 <code>Realtek ALC269VB</code></p> </li> <li> <p>勾选 <code>Internel Speaker</code> 一栏的 <code>Override</code></p> </li> <li> <p>选择 <code>Line Out (Front)</code> 项</p> </li> <li> <p>点击 <code>Install boot override</code></p> </li> </ul> </div> <div class="imageblock"> <div class="content"> <img src="hdajackretask.jpg" alt="hdajackretask.jpg" width="50%"> </div> </div> <div class="paragraph"> <p>安装完成之后需要<strong>重启系统</strong>生效,并且<strong>在 GRUB 界面选择 Ubuntu, with kernel 5.15.0-79-generic</strong> 启动。</p> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> <div class="paragraph"> <p>如果仍旧存在问题,可以尝试手动执行 <code>sudo alsa force-reload</code>。</p> </div> </td> </tr> </table> </div> </div> </div> </div> <div class="sect1"> <h2 id="_扩展_tldr"><a class="anchor" href="#_扩展_tldr"></a><a class="link" href="#_扩展_tldr">4. 扩展 TLDR;</a></h2> <div class="sectionbody"> <div class="paragraph"> <p>至此,在 <code>Linux</code> (<code>Kubuntu with kernel 5.15.0-79-generic</code>) 环境下的网络、蓝牙、音频、画面等问题已经全部解决。</p> </div> <div class="paragraph"> <p>后续,如果感兴趣的话,在理论上你也可以手动编译内核,并加入正确的驱动。</p> </div> <div class="paragraph"> <p>可以通过以下页面获取资源:</p> </div> <div class="ulist"> <ul> <li> <p><a href="https://github.com/torvalds/linux/tree/master/drivers">Linux Source Code: drivers</a></p> </li> <li> <p><a href="https://packages.ubuntu.com/">Ubuntu Packages</a></p> </li> </ul> </div> <div class="paragraph"> <p><code>Makefile</code> 示例:</p> </div> <div class="listingblock"> <div class="content"> <pre class="rouge highlight"><code data-lang="sh">obj-m +<span class="o">=</span> thedriver.o all: make <span class="nt">-C</span> /lib/modules/<span class="si">$(</span>shell <span class="nb">uname</span> <span class="nt">-r</span><span class="si">)</span>/build <span class="nv">M</span><span class="o">=</span><span class="si">$(</span>PWD<span class="si">)</span> modules clean: make <span class="nt">-C</span> /lib/modules/<span class="si">$(</span>shell <span class="nb">uname</span> <span class="nt">-r</span><span class="si">)</span>/build <span class="nv">M</span><span class="o">=</span><span class="si">$(</span>PWD<span class="si">)</span> clean</code></pre> </div> </div> </div> </div> <div class="sect1"> <h2 id="_其它"><a class="anchor" href="#_其它"></a><a class="link" href="#_其它">5. 其它</a></h2> <div class="sectionbody"> <div class="sect2"> <h3 id="_自动登录"><a class="anchor" href="#_自动登录"></a><a class="link" href="#_自动登录">5.1. 自动登录</a></h3> <div class="paragraph"> <p>由于 <code>Linux</code> 系统可能没有自带屏幕触摸键盘,因此最好设置用户自动登录,以便在没有键盘的时候也可以登入系统。</p> </div> </div> <div class="sect2"> <h3 id="_屏幕键盘"><a class="anchor" href="#_屏幕键盘"></a><a class="link" href="#_屏幕键盘">5.2. 屏幕键盘</a></h3> <div class="paragraph"> <p>可以通过 <code>sudo apt install onboard</code> 安装 <a href="https://launchpad.net/onboard">Onboard</a> 屏幕键盘并设置开机启动,不过,它似乎并不能在登录界面使用。</p> </div> <div class="paragraph"> <p><span class="image"><img src="onboard.jpg" alt="onboard.jpg" width="50%"></span></p> </div> </div> <div class="sect2"> <h3 id="_便携键鼠"><a class="anchor" href="#_便携键鼠"></a><a class="link" href="#_便携键鼠">5.3. 便携键鼠</a></h3> <div class="paragraph"> <p>日本品牌 <code>SANWA</code> 的 <code>400-SKB070</code> 折叠键盘是个不错的选择,支持三个蓝牙连接,且自带了一个小型触控板。折叠后仅与一台 <code>iPhone 14</code> 尺寸相当。</p> </div> <div class="paragraph"> <p>当然,缺点也有,这个键盘没有 <code>F1~F12</code> 功能键,也没有 <code>Escape</code> 键,如果比较介意的话你也可以选择 <code>GSKBBT30BK</code>。</p> </div> <div class="paragraph"> <p><span class="image"><img src="sanwa.jpg" alt="sanwa.jpg" width="50%"></span></p> </div> <div class="paragraph"> <p>另一个推荐是 <code>RII k06</code> 迷你键盘,长度与 <code>Gole 1 Pro</code> 相当,支持蓝牙及 <code>2.4G</code> 双模式,自带触摸板,而且按键齐全。</p> </div> <div class="paragraph"> <p><span class="image"><img src="rii.jpg" alt="rii.jpg" width="50%"></span></p> </div> <div class="sect3"> <h4 id="_键盘隐射"><a class="anchor" href="#_键盘隐射"></a><a class="link" href="#_键盘隐射">5.3.1. 键盘隐射</a></h4> <div class="paragraph"> <p>题外话,对于没有 <code>Escape</code> 键的问题,可以通过键盘映射来解决,在 <code>Linux</code> 中可以使用 <a href="https://github.com/sezanzeb/input-remapper">Input Remapper</a>,<code>Windows</code> 中可以使用 <a href="https://github.com/microsoft/PowerToys">PowerToy</a>,<code>macOS</code> 中可以使用 <a href="https://karabiner-elements.pqrs.org/">Karabiner Elements</a>。</p> </div> <hr> <div class="paragraph text-center"> <p><span class="small">Made with ♡ in Shenzhen</span></p> </div> </div> </div> </div> </div> </div> </body> </html>

简介

高乐 Gole 1 Pro 安装 Linux (Kubuntu) 及后续问题修复 展开 收起
C 等 3 种语言
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
1
https://gitee.com/meniny/gole-1-pro-linux-fix.git
git@gitee.com:meniny/gole-1-pro-linux-fix.git
meniny
gole-1-pro-linux-fix
Gole 1 Pro Linux Fix
master

搜索帮助