<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Soul Of Free Loop &#187; Chrome</title>
	<atom:link href="https://zohead.com/archives/category/technology/chrome/feed/" rel="self" type="application/rss+xml" />
	<link>https://zohead.com</link>
	<description>Uranus Zhou&#039;s Blog</description>
	<lastBuildDate>Sat, 19 Jul 2025 15:42:46 +0000</lastBuildDate>
	<language>zh-CN</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.8</generator>
	<item>
		<title>Chromebook上使用Zed进行远程编辑</title>
		<link>https://zohead.com/archives/chromebook-zed-remote/</link>
		<comments>https://zohead.com/archives/chromebook-zed-remote/#comments</comments>
		<pubDate>Mon, 24 Oct 2016 17:35:38 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[Chrome]]></category>
		<category><![CDATA[工具]]></category>
		<category><![CDATA[Chromebook]]></category>
		<category><![CDATA[MDwiki]]></category>
		<category><![CDATA[Web服务器]]></category>
		<category><![CDATA[Zed]]></category>
		<category><![CDATA[zedd]]></category>
		<category><![CDATA[zedrem]]></category>
		<category><![CDATA[编辑器]]></category>
		<category><![CDATA[远程]]></category>

		<guid isPermaLink="false">https://zohead.com/?p=1287</guid>
		<description><![CDATA[之前我写过一篇文章介绍 Chromebook 上比较强大的 Zed 编辑器 的上手体验，目前主要用于编辑自己的 MDwiki 知识库 目录。不过本地文件编辑完之后需要用 BTSync 之类的工具同步到 VPS 上，因此还是想把 Zed 的远程编辑功能用起来，而且配合 Zed 自带的 Web Server 功能还能直接本地查看 MDwiki 知识库。 Zed 目前支持 zedrem 和 zedd 这两种远程编辑方式，下面分别介绍一下另，另外也说明了如何使用 Zed 自带的 Web Server。 zedrem 远程编辑 zedrem 是用 Go 语言编写的工具，按照 Zed 官网的介绍一条命令就 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>之前我写过一篇文章介绍 Chromebook 上比较强大的 <a href="https://zohead.com/archives/chromebook-zed/">Zed 编辑器</a> 的上手体验，目前主要用于编辑自己的 <a href="https://zohead.com/archives/wikitten-mdwiki/">MDwiki 知识库</a> 目录。不过本地文件编辑完之后需要用 BTSync 之类的工具同步到 VPS 上，因此还是想把 Zed 的远程编辑功能用起来，而且配合 Zed 自带的 Web Server 功能还能直接本地查看 MDwiki 知识库。</p>
<p>Zed 目前支持 <a href="http://zedapp.org/features/edit-remote-files/">zedrem</a> 和 <a href="http://zedapp.org/zedd">zedd</a> 这两种远程编辑方式，下面分别介绍一下另，另外也说明了如何使用 Zed 自带的 Web Server。</p>
<h2 id="zedrem-远程编辑">zedrem 远程编辑</h2>
<p>zedrem 是用 Go 语言编写的工具，按照 Zed 官网的介绍一条命令就可以安装成功，默认情况下在 VPS 上运行 zedrem 命令之后会自动连接 Zed 服务器注册并返回远程编辑地址，Chrome 应用后续的列举文件、打开文件、保存等操作都会通过 Zed 服务器进行中转，这样可以直接绕过防火墙之类的限制。</p>
<p>zedrem 的使用也非常简单，在 VPS 上运行 zedrem 跟上需要编辑的目录路径（不加目录参数则是直接编辑当前目录）：</p>
<pre class="brush: bash; title: ; notranslate">
root@zoserver:~# ./zedrem wiki-dir
In the Zed application copy and paste following URL to edit:

https://remote.zedapp.org:443/fs/c1e91639eede09e0be43a4cf3f22d036

Press Ctrl-c to quit.
</pre>
<p>看到上面 zedrem 命令给出的地址之后，就可以在 Zed App 的 <strong>选择项目</strong> 界面中选 <strong>Remote Folder</strong>，在出来的 <strong>Open Zedrem Folder</strong> 界面中直接输入上面的地址并点击 <strong>Open</strong> 就可以远程编辑 VPS 上的目录了。</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737442981/zedrem-folder.jpg" alt="打开 Zedrem 文件夹" title="打开 Zedrem 文件夹"></p>
<p>如果你对 zedrem 默认通过 Zed 服务器进行中转的工作机制不放心的话，也可以让 Zed Chrome 应用与 VPS 服务器直接连接，首先在 VPS 上让 zedrem 作为转发服务器运行：</p>
<pre class="brush: bash; title: ; notranslate">
root@zoserver:~# ./zedrem --server
Zedrem server now running on ws://0.0.0.0:7337
</pre>
<p>然后另开一个终端再运行 zedrem 命令并增加 <code>-u</code> 参数指定转发服务器地址，这里可以直接填 VPS 服务器的 IP 地址或者域名：</p>
<pre class="brush: bash; title: ; notranslate">
root@zoserver:~# ./zedrem -u ws://xxx.xxx.xxx.xxx:7337 wiki-dir
In the Zed application copy and paste following URL to edit:

http://xxx.xxx.xxx.xxx:7337/fs/7d6f781a002875f0a9fb57e095f3ddec

Press Ctrl-c to quit.
</pre>
<p>刚才运行 zedrem 转发服务器的终端上也会显示新的客户端已经连接：</p>
<pre class="prettyprint"><code class=" hljs ">Client 7d6f781a002875f0a9fb57e095f3ddec connected</code></pre>
<p>同样 Zed Chrome 应用也只需要输入上面 zedrem 命令给出的地址就可以进行远程编辑操作了，实际使用中也可以直接把 zedrem 的转发服务器模式放在后台运行的。</p>
<p>当然如果你的 Chromebook 和 VPS 的连接速度比较慢（比如在移动宽带网络下连接我的美国 VPS 可能就会比较慢），也可以在别的主机（例如使用另一台香港 VPS）上运行 zedrem 的转发服务器，并通过 <code>-u</code> 参数指定通过新的主机进行转发，这样也可以加快远程编辑的响应速度。</p>
<h2 id="zedd-远程编辑">zedd 远程编辑</h2>
<h3 id="vps-上安装-zedd">VPS 上安装 zedd</h3>
<p>一般使用 zedrem 就能满足普通用户的基本远程编辑需求了，但如果你想实现远程编辑文件之后运行特定的命令等高级的需求（例如我修改的 MDwiki 系统在新增 Wiki 项目之后需要运行命令生成刷新 Wiki 目录文件），zedrem 对这种情况就无能无力了。</p>
<p>不过还好 Zed 也为我们提供了 Zedd 后台程序，Zedd 支持远程执行命令，而且导出远程文件系统的方式也更加高效，Zedd 远程目录也可以在 Chrome 应用的历史项目中直接显示，比较适合 Chromebook 用户。</p>
<p>Zedd 程序是用 Node.js 编写的，安装步骤相对 zedrem 会稍微复杂一点，其详细说明也可以参考 Zed 官方网站，首先 VPS 上需要安装 Node.js 环境，我的 VPS 使用的是 Debian 7 系统，可以通过下面的命令安装（假设你有 VPS 的 root 访问权限，同时也会自动安装必需的 Node.js 的 npm 包管理工具）：</p>
<pre class="brush: bash; title: ; notranslate">
root@zoserver:~# curl -sL https://deb.nodesource.com/setup_4.x | bash -
root@zoserver:~# apt-get install -y nodejs
</pre>
<p>安装完成之后就可以通过 npm 命令安装 Zedd 程序：</p>
<pre class="brush: bash; title: ; notranslate">
root@zoserver:~# npm install -g zedd
</pre>
<h3 id="使用-zedd">使用 zedd</h3>
<p>Zedd 安装好之后可以先看看其运行帮助信息：</p>
<pre class="brush: bash; title: ; notranslate">
root@zoserver:~# zedd --help
Zedd is the Zed daemon used to edit files either locally or remotely using Zed.
Options can be passed in either as environment variables, JSON config in
~/.zeddrc or as command line arguments prefixed with '--':

   user:       username to use for authentication (default: none)
   pass:       password to use for authentication (default: none)
   remote:     bind to 0.0.0.0, requires auth, and disables
               enable-run by default
   port:       port to bind to (default: 7337)
   root:       root directory to expose (default: $HOME)
   enable-run: enable running of external programs in remote mode
   tls-key:    path to TLS key file (enables https)
   tls-cert:   path to TLS certificate file (enables https)
</pre>
<p>默认如果运行 zedd 程序不加任何参数会导出用户的主目录，而且默认也只有 <code>localhost</code> 本地才能访问，导出地址为：</p>
<pre class="prettyprint"><code class=" hljs cs">http:<span class="hljs-comment">//127.0.0.1:7337/</span></code></pre>
<p>当然对于我们要在 Chromebook 上远程编辑 VPS 上的文件就不能这么做了，根据情况可以在 VPS 服务器上运行 zedd 程序时：</p>
<ul>
<li>增加 <code>--remote</code> 参数可以支持外部连接；</li>
<li>增加 <code>--root</code> 参数指定导出的根目录（默认为 <code>$HOME</code> 用户主目录）；</li>
<li>增加 <code>--enable-run</code> 参数可以允许执行外部命令；</li>
<li>另外可以指定 <code>--user</code> 和 <code>--pass</code> 参数配置访问的用户名和密码。</li>
</ul>
<blockquote>
<p><strong>提示</strong></p>
<p>为了 VPS 上文件的安全性考虑，如果你有可用的 SSL 证书的话建议使用 <code>--tls-key</code> 和 <code>--tls-cert</code> 参数，这样可以使用 https 模式替代默认的 http 模式。</p>
</blockquote>
<p>例如我的 VPS 上可以这样运行 zedd 程序：</p>
<pre class="brush: bash; title: ; notranslate">
root@zoserver:~# zedd --remote --enable-run --root wiki-dir --user zeduser --pass zedpass
Zedd is now listening on http://0.0.0.0:7337
Exposed filesystem : /home/root/wiki-dir
Mode               : remote (externally accessible)
Command execution  : enabled
Authentication     : enabled
</pre>
<p>Chromebook 上要使用 Zedd 远程文件夹也比较简单，在选择项目界面中点击 <strong>Zedd Folder</strong> 进入 <strong>Open Zedd Folder</strong> 界面，该界面中就可以输入远程 Zedd 导出地址和用户名、密码：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737442977/zedd-folder.jpg" alt="打开 Zedd 文件夹" title="打开 Zedd 文件夹"></p>
<p>确认之后点击 <strong>Connect</strong> 按钮连接正常的话就可以看到远程的目录树，接着就可以任意选择下面的子目录进行编辑了。</p>
<h3 id="zedd-的外部命令支持">zedd 的外部命令支持</h3>
<p>对于打开的远程 Zedd 文件夹，Zed Chrome 应用是支持运行外部命令的，首先使用 Zed 命令快捷键（默认为 <kbd>Ctrl-Shift-.</kbd>，我的 Chromebook 上改成了 <kbd>Ctrl-Shift-C</kbd>）或者点击 <strong>Tools</strong> -&gt; <strong>Run Command</strong> 菜单项，在弹出的 <strong>Enter command</strong> 中输入 external，Zed 会自动搜索，默认匹配到的两个就是远程执行外部命令用的：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737442973/zedd-command.jpg" alt="Zed 执行外部命令" title="Zed 执行外部命令"></p>
<p>一般使用第一个 <strong>Tools:External:Insert Command Output</strong> 命令，选择该命令会让你输入需要在 VPS 主机上执行的命令及参数，并将远程命令的执行结果插入到当前所打开文件的光标位置。</p>
<p>如果你想要执行的命令有输出又担心影响正在打开的文件（Zed 是编辑区内容有改动就实时保存的），那可以直接打开 Zed 保留的 <code>zed::start</code> 只读文件并执行 Insert Command Output 操作，这样既可以看到远程命令的输出结果又不会改动其它文件的内容。</p>
<p>例如我打开远程 MDwiki 目录之后进行编辑之后需要进行刷新 Wiki 目录文件的操作，这就需要执行我写的 <code>generate-index.sh</code> 脚本。我就可以切换到 <code>zed::start</code> 文件并执行 <code>generate-index.sh</code> 远程命令并查看输出结果。当然如果你不关心输出结果，也可以不管当前打开的是什么文件，直接执行命令并附加 <code>&gt;/dev/null</code> 以忽略输出：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737442975/zedd-external-program.jpg" alt="忽略外部命令输出" title="忽略外部命令输出"></p>
<p>这样配置之后我就能实现不经远程登录或同步 VPS 就能直接远程编辑 MDwiki 知识库的需求了，而且编辑完成之后直接在 Chromebook 上执行外部命令就能更新 Wiki 目录。</p>
<h2 id="使用-zed-自带-web-server">使用 Zed 自带 Web Server</h2>
<p>由于我的 VPS 上的 MDwiki 目录同时也开启了 BTSync 同步，需要时也可以将远程的 Wiki 目录同步到本地，同步到 Chromebook 之后也可以使用 Zed 自带的 Web Server 功能本地查看 MDwiki 知识库。</p>
<p>Zed 打开 MDwiki 目录之后同样使用命令快捷键运行命令，输入 static server 进行搜索，就会匹配 Zed 自带 Web Server 的几个命令：</p>
<ul>
<li>Tools:Static Server:Stop</li>
<li>Tools:Static Server:Start</li>
<li>Tools:Static Server:Generate Full Site</li>
</ul>
<p>选择第二个 <code>Tools:Static Server:Start</code> 命令启动 Zed 自带静态 Web Server，Zed 会自动打开新 Chrome 标签页显示 MDwiki 知识库，如果当前打开的项目目录下没有 <code>index.html</code> 或者 <code>default.html</code> 等文件则会自动显示文件列表。不再需要查看 Wiki 知识库时选择 <code>Tools:Static Server:Stop</code> 命令停止 Web Server 即可。</p>
<p>不过我在使用 Zed 自带 Web Server 时发现其存在不支持中文等非 ANSI 路径名以及包含特殊符号的文件名的问题，默认的文件列表页显示中文文件名同样不正确，因此我检出了 Zed 官方的 staticserver 包进行了修正，并在 GitHub 上新创建了一个仓库：</p>
<p><a href="https://github.com/zohead/staticserver">https://github.com/zohead/staticserver</a></p>
<p>测试完成之后我也为官方 staticserver 仓库创建了新的 Pull Request，只是目前还没有得到回应。</p>
<p>有使用 Zed 自带 Web Server 需求的朋友可以检出上面我的 staticserver 代码，并替换到 Zed Chrome 应用的 staticserver 包路径：</p>
<pre class="prettyprint"><code class=" hljs ruby">~<span class="hljs-regexp">/Extensions/pfmjnmeipppmcebplngmhfkleiinphhp</span><span class="hljs-regexp">/1.1.0_0/config</span><span class="hljs-regexp">/packages/gh</span><span class="hljs-regexp">/zedapp/staticserver</span></code></pre>
<p>替换之后重新启动 Zed 应用再运行启动 Web Server 的命令应该就可以解决不能正常访问中文路径的问题了。</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/chromebook-zed-remote/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>适合Chromebook的Zed编辑器上手</title>
		<link>https://zohead.com/archives/chromebook-zed/</link>
		<comments>https://zohead.com/archives/chromebook-zed/#comments</comments>
		<pubDate>Sun, 19 Jun 2016 16:05:21 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[Chrome]]></category>
		<category><![CDATA[工具]]></category>
		<category><![CDATA[Chromebook]]></category>
		<category><![CDATA[Markdown]]></category>
		<category><![CDATA[Sublime Text]]></category>
		<category><![CDATA[Zed]]></category>
		<category><![CDATA[ZPM]]></category>
		<category><![CDATA[命令]]></category>
		<category><![CDATA[快捷键]]></category>
		<category><![CDATA[编辑器]]></category>

		<guid isPermaLink="false">https://zohead.com/?p=1242</guid>
		<description><![CDATA[Zed 编辑器 对于很多 Chromebook 用户来说，缺少比较好用的本地编辑器是一个比较普遍的困扰，特别是我这样的程序员用户对于编辑器的要求就更多一些了。有一些同学是直接通过 crouton 安装 Sublime Text、GitHub Atom 等编辑器或者各种 IDE 软件来解决。 之前我介绍过 Caret 这款 Chrome 应用商店里的文本编辑器 App，如果只是用来编辑纯文本之类的文件那 Caret 是能胜任的，如果你需要额外的一些扩展功能，那只能另寻他法了。我还尝试过第三方开发者移植的 Chrome 版 Adobe Brackets 编辑器（和 Atom 有点类似），不过使用起 [&#8230;]]]></description>
				<content:encoded><![CDATA[<h2 id="zed-编辑器">Zed 编辑器</h2>
<p>对于很多 Chromebook 用户来说，缺少比较好用的本地编辑器是一个比较普遍的困扰，特别是我这样的程序员用户对于编辑器的要求就更多一些了。有一些同学是直接通过 crouton 安装 Sublime Text、GitHub Atom 等编辑器或者各种 IDE 软件来解决。</p>
<p>之前我介绍过 <a href="https://zohead.com/archives/chromebook-caret/">Caret</a> 这款 Chrome 应用商店里的文本编辑器 App，如果只是用来编辑纯文本之类的文件那 Caret 是能胜任的，如果你需要额外的一些扩展功能，那只能另寻他法了。我还尝试过第三方开发者移植的 Chrome 版 <a href="http://brackets.io/">Adobe Brackets</a> 编辑器（和 Atom 有点类似），不过使用起来还是存在各种问题就作罢了。</p>
<p>还好后来我还是在 Chrome 商店里找到了今天要介绍的 Zed 编辑器，Zed 的使用方式和 Sublime Text 比较类似，其主要功能可以参考官网：</p>
<p><a href="http://zedapp.org/">http://zedapp.org/</a></p>
<p>Zed 编辑器其实是有 Chrome App 版本和 Windows、Mac、Linux 等系统下的 Standalone 版本的，Standalone 版本的功能比 Chrome App 版本要更多（例如可以直接运行本地命令等）。</p>
<p>对于 Chromebook 用户来说虽然默认只能用功能相对少的 Chrome App 版本，但相应的也能得到 Chrome 版本的带来的好处：</p>
<ul>
<li>一处安装多处直接运行；</li>
<li>自动通过 Google Drive 同步 Zed Chrome App 配置；</li>
<li>Zed Chrome App 默认自动从 Chrome 商店更新。</li>
</ul>
<p>而且开发者考虑到日益增长的 Chromebook 用户的需求目前也在不断更新 Chrome App 版本，我们可以从 <a href="https://chrome.google.com/webstore/detail/pfmjnmeipppmcebplngmhfkleiinphhp">Chrome 商店</a> 直接安装。</p>
<h2 id="初步使用">初步使用</h2>
<p>Zed 编辑器启动时会提示你使用哪种界面风格，默认是不带目录树甚至隐藏了菜单栏的风格，打开编辑器会显示选择项目界面：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737442978/zed-initial.png" alt="Zed选择项目界面" title="Zed选择项目界面"></p>
<p>点击“Local Folder” 或者“Local File(s)”就可以打开本地的文件夹或文件编辑了，“Zedd Folder”和“Remote Folder”是两种直接编辑远程文件的方式后面单独再做介绍，另外 Zed 还直接支持打开 GitHub 版本库和 Dropbox 这点也比较方便。</p>
<p>打开具体的文件会直接显示文件内容，第一次打开某个项目文件夹的话则默认显示只读的 <code>zed::start</code> 内置使用介绍文件以帮助用户熟悉编辑器的各种快捷键之类的。</p>
<p>Zed 的文件编辑和 Sublime Text 这种类似是直接实时保存用户输入的结果，不需要单独的关闭保存操作。</p>
<p>通常的文件操作可以使用键盘快捷键或者 File 菜单完成：</p>
<ul>
<li><kbd>Ctrl-N</kbd> 键新建文件；</li>
<li><kbd>Ctrl-E</kbd> 键打开文件；</li>
<li><kbd>Alt-T</kbd> 键显示目录树；</li>
<li><kbd>F5</kbd> 键刷新文件夹中的文件列表。</li>
</ul>
<p>新建文件或者打开文件时会显示命令窗口，输入不存在的文件名就可以实现新建文件（当然也就可以直接在命令窗口中输入子目录路径）。</p>
<p>如果你在编辑的过程中需要打开另一个项目文件夹或者文件，那可以按 <kbd>Ctrl-Shift-o</kbd> 键显示最开始的选择项目界面，这样就不用重启 Zed App 了。</p>
<h2 id="zed-配置文件">Zed 配置文件</h2>
<p>这里先说 Zed 的配置文件是因为最常用的调出 Zed 命令窗口的默认快捷键 <kbd>Ctrl-.</kbd> 或 <kbd>Ctrl-Shift-.</kbd> 在 Chromebook 上是不起作用的，当然你也可以鼠标点击 Tools 菜单下的 Run Command 菜单项来实现，不过为了使用方便，我们还是先修改 Zed 配置文件来定制命令快捷键。</p>
<p>打开 Zed 编辑器开始显示的选择项目界面里可以看到 <code>Configuration</code> 项，使用此项就可以打开 Zed 自带的配置项目目录，默认第一次打开还是会显示 <code>zed::start</code> 文件，使用 <kbd>Ctrl-E</kbd> 快捷键或者打开菜单选择 <code>user.json</code> 文件进行编辑，这个就是 Zed 的用户配置文件。</p>
<p>默认的 <code>user.json</code> 用户配置文件可能是这样的（仅供参考）：</p>
<pre class="brush: jscript; title: ; notranslate">
{
    imports: [
        &quot;/default.json&quot;
    ],
    preferences: {},
    modes: {},
    keys: {},
    commands: {},
    handlers: {},
    themes: {},
    packages: [    ]
}
</pre>
<p>我们可以在 <code>keys</code> 中新增一项来修改默认的运行命令快捷键：</p>
<pre class="brush: jscript; title: ; notranslate">
    keys: {
        &quot;Command:Enter Command&quot;: {
            win: &quot;Ctrl-Shift-C&quot;
        }
    },
</pre>
<p>例如改成上面的内容就可以使用 <kbd>Ctrl-Shift-C</kbd> 键调出运行 Zed 命令的窗口了。</p>
<p>当然对于修改主题之类的常用配置，你可以使用 <kbd>Ctrl-,</kbd> 快捷键或者 Configuration - Preferences 菜单项进行图形化的配置，这样也更加方便。</p>
<h2 id="zed-命令">Zed 命令</h2>
<p>Zed 命令的使用方式也是和 Sublime Text 比较相似，经过上面的步骤修改命令快捷键之后就可以体验 Zed 的各项命令了，Zed 的命令窗口支持模糊查找识别的功能。</p>
<p>Zed 相对 Chrome 商店里其它各种编辑器的一大优势就是其支持 Zed Package Manager（简称 ZPM）包管理特性，第三方开发者可以根据需要为 Zed 开发各种扩展功能包，ZPM 的介绍可以参考 Zed <a href="http://zedapp.org/2014/05/zed-package-manager/">官网文章</a>，常用 ZPM 包在这里：</p>
<p><a href="https://github.com/zedapp/zed/wiki/Packages">https://github.com/zedapp/zed/wiki/Packages</a></p>
<p>按快捷键调出运行命令的窗口后，输入 install 就可以看到默认匹配的安装 ZPM 包命令：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737442973/zed-command.png" alt="Zed命令窗口" title="Zed命令窗口"></p>
<p>同样输入 installed 就可以看到默认匹配的列出已安装的 ZPM 包命令，还是比较方便的。</p>
<h2 id="markdown-编辑与预览">Markdown 编辑与预览</h2>
<p>Zed 虽然不像 Sublime Text 那样支持多标签页功能，但也可以在一个 Zed 窗口中显示最多 3 个编辑窗口，通过快捷键可以切换：</p>
<ul>
<li><kbd>Ctrl-2</kbd> 将窗口分割为两个编辑窗口；</li>
<li><kbd>Ctrl-3</kbd> 将窗口分割为三个编辑窗口（最好高分屏才这么干哈）；</li>
<li><kbd>Ctrl-1</kbd> 恢复为单编辑窗口；</li>
<li><kbd>Ctrl-0</kbd> 在多个编辑窗口之间切换焦点。</li>
</ul>
<p>Zed 自带 Markdown 预览功能，如果编辑的是 Markdown 文件则可以通过 <kbd>Ctrl-P</kbd> 快捷键显示预览窗口，开启预览之后还可以多次使用 <kbd>Ctrl-P</kbd> 快捷键切换源 Markdown 文件编辑窗口和预览窗口的大小，当然也可以按 <kbd>Ctrl-1</kbd> 键关闭预览窗口。</p>
<p>我使用的 <a href="http://wiki.zohead.com/">Wiki 系统</a> 中的 Markdown 文件预览效果如下：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737442978/zed-markdown.png" alt="Zed自带Markdown预览效果" title="Zed自带Markdown预览效果"></p>
<p>你可能从上面的截图可以看出 Zed 的 Markdown 预览功能似乎效果一般，这是因为 Zed 自带的 Markdown 预览模块对 GitHub 格式的 Markdown 文件的支持是不太好的。</p>
<p>不过还好已经有人为 Zed 写了一个支持 GitHub Flavored Markdown 的 ZPM 包，其项目地址如下：</p>
<p><a href="https://github.com/akoenig/zed-gfm-preview">https://github.com/akoenig/zed-gfm-preview</a></p>
<p>按照该项目主页的介绍，调出运行命令窗口，选择 <code>Tools:Zpm:Installed Packages</code> 命令准备安装新的 ZPM 包，包地址中输入 <code>gh:akoenig/zed-gfm-preview</code> 就可以完成安装。</p>
<p>安装完成之后编辑 Markdown 文件时可以通过 <code>GitHub:Markdown:Preview</code> 命令使用 zed-gfm-preview 方式来预览 Markdown，当然还是建议修改 Zed 用户配置文件直接将 zed-gfm-preview 配置为 Zed 默认的 Markdown 预览方式：</p>
<pre class="brush: jscript; title: ; notranslate">
modes: {
    markdown: {
        handlers: {
            preview: [
                &quot;!Tools:Preview&quot;,
                &quot;GitHub:Markdown:Preview&quot;
            ]
        }
    }
}
</pre>
<p>这样还是可以按默认的 <kbd>Ctrl-P</kbd> 快捷键直接预览 Markdown 文件：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737442979/zed-markdown-github.png" alt="GitHub Markdown预览效果" title="GitHub Markdown预览效果"></p>
<p>可以看到效果也比 Zed 自带的实现好多了哦，代码块的显示也正确了。</p>
<h2 id="后记">后记</h2>
<p>本文只是对 Zed 编辑器的初步介绍，另外一些 Zed 自带的比较好用的远程编辑文件、自带 Web 服务器等特性后面有空再来写了，大家也可以研究折腾甚至开发自己的 ZPM 包哦。文章中有任何问题还请提出指正，火热的六月仍然祝大家玩的开心呢 ^_^。</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/chromebook-zed/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>发布360云盘播放助手Chrome扩展</title>
		<link>https://zohead.com/archives/cloud-player-helper/</link>
		<comments>https://zohead.com/archives/cloud-player-helper/#comments</comments>
		<pubDate>Fri, 08 Apr 2016 14:50:04 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[Chrome]]></category>
		<category><![CDATA[工具]]></category>
		<category><![CDATA[360]]></category>
		<category><![CDATA[VXG Media Player]]></category>
		<category><![CDATA[云盘]]></category>
		<category><![CDATA[助手]]></category>
		<category><![CDATA[扩展]]></category>
		<category><![CDATA[播放]]></category>
		<category><![CDATA[视频]]></category>

		<guid isPermaLink="false">https://zohead.com/?p=1207</guid>
		<description><![CDATA[最近一段时间以来由于我的个人电脑终端已经基本从 Windows PC 转向 Chromebook，自然之前的一些需求也要看看如何在 Chromebook 上实现。其中一个比较多的需求就是各种云盘中的在线视频播放问题（毕竟我也已经很久没有直接下载视频播放了，基本都是用云盘的离线下载）。 我目前使用的 360 云盘虽然有 Android 和 Windows 下的在线视频播放客户端，但是 Web 端的视频播放功能相对还是弱了一点，云盘里基本上只有标准 H.264 编码的 mp4 格式的视频才能直接用 Chromebook 进行在线播放。 这里还是提一下 360 云盘 Web 版的一个优点就是标准 H [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>最近一段时间以来由于我的个人电脑终端已经基本从 Windows PC 转向 Chromebook，自然之前的一些需求也要看看如何在 Chromebook 上实现。其中一个比较多的需求就是各种云盘中的在线视频播放问题（毕竟我也已经很久没有直接下载视频播放了，基本都是用云盘的离线下载）。</p>
<p>我目前使用的 360 云盘虽然有 Android 和 Windows 下的在线视频播放客户端，但是 Web 端的视频播放功能相对还是弱了一点，云盘里基本上只有标准 H.264 编码的 mp4 格式的视频才能直接用 Chromebook 进行在线播放。</p>
<blockquote>
<p>这里还是提一下 360 云盘 Web 版的一个优点就是标准 H.264 编码的 mp4 格式视频竟然还是以 html5 方式直接播放的。</p>
</blockquote>
<p>其它诸如 avi、wmv、mkv、rmvb 等很常见的视频文件都不能直接在线播放，点击时会直接提示用户下载视频到本地。</p>
<blockquote>
<p><strong>解释</strong></p>
<p>Chrome 浏览器默认只支持播放 H.264 和 WebM 编码的视频,而且 Chrome 45 以上的版本已经不支持不太安全的 NPAPI 形式的插件了（对于 Chromebook 这种终端使用 NPAPI 插件也不现实哦）。</p>
</blockquote>
<p>考虑到 360 云盘的 Android App 目前看起来通过 Chrome ARC 环境也不能正常运行，因此我就稍微花了几天时间写了一个针对 360 云盘的视频播放助手 Chrome 扩展，建议直接从 Chrome 应用商店中安装本扩展：</p>
<p><a href="https://chrome.google.com/webstore/detail/klomjfcgakppceibbbgkbdklmhiiidkl">https://chrome.google.com/webstore/detail/klomjfcgakppceibbbgkbdklmhiiidkl</a></p>
<p>本播放助手扩展主要对 360 云盘的 Web 版做了一些改进：</p>
<ul>
<li>360 云盘的文件列表界面中点击非 mp4(webm) 的视频文件也可以弹出视频播放网页；</li>
<li>视频分类界面中点击视频文件也能达到同样的效果；</li>
<li>视频播放网页上方增加播放助手图标，并显示 <code>[转码视频]</code> 和 <code>[原画视频]</code> 链接，点击可以直接播放，右键也可以复制视频链接地址到其它播放器中播放。</li>
</ul>
<p>特别需要说明的是虽然 Chrome 浏览器本身只支持播放 H.264 和 WebM 编码的视频,不过还好国外的 Video Experts Group 推出了适用于 Chrome 浏览器的 NaCl（PNaCl） 形式的视频播放插件 <code>VXG Media Player Plug-in</code>，此插件可以提升 Chrome 浏览器的视频播放能力，而且相比 NPAPI 插件也更加安全。</p>
<p>有关 <code>VXG Media Player</code> 视频播放器插件的详细介绍可以参考其官网：</p>
<p><a href="http://www.videoexpertsgroup.com/chrome-media-player-plug-in/">http://www.videoexpertsgroup.com/chrome-media-player-plug-in/</a></p>
<p><code>VXG Media Player</code> 插件的基本特性包括：</p>
<ul>
<li>支持 RTSP, RTP, UDP, RTMP, MMS， HLS 等各种常见的媒体协议；</li>
<li>支持 H.264, MPEG-4, MPEG-2 等众多的视频编码；</li>
<li>支持 AAC, PCM, G711, MP3 等音频编码格式；</li>
<li>视频解码支持硬件加速；</li>
<li>由于是 NaCl（PNaCl） 形式的插件，在不同硬件平台上兼容性比较好。</li>
</ul>
<p>安装 <code>VXG Media Player</code> 插件并经过基本测试之后发现该插件虽然也有一些问题，但也算能满足 Chromebook 上网页直接播放视频的需求了。因此经过研究 <code>VXG Media Player</code> 插件的 API 之后决定在我的云盘播放助手扩展中使用此插件以实现更加全面的视频播放支持，最终的使用方式就是：</p>
<ul>
<li>mp4(webm) 视频： <br />
直接使用 360 云盘自带的 html5 视频播放功能，效果最好；</li>
<li>avi、wmv、mkv、rmvb 等视频： <br />
调用 <code>VXG Media Player</code> 插件接口让这些格式的视频也能在云盘视频播放界面中直接播放。</li>
</ul>
<p>安装 <code>VXG Media Player</code> 插件请移步 Chrome 商店：</p>
<p><a href="https://chrome.google.com/webstore/detail/hncknjnnbahamgpjoafdebabmoamcnni">https://chrome.google.com/webstore/detail/hncknjnnbahamgpjoafdebabmoamcnni</a></p>
<p>这里贴上我的云盘播放助手扩展运行效果截图：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737370806/cloud-player-helper.png" alt="云盘播放助手扩展" title="云盘播放助手扩展"></p>
<p>从上面的截图可以看到本扩展在 360 云盘播放界面增加的图标和两个链接，本扩展不会修改云盘播放界面上的默认播放效果（不管是使用 html5 视频播放或者 360 云盘的 Flash 视频播放器），只有点击增加的链接之后才会切换播放方式。</p>
<blockquote>
<p><strong>提示</strong></p>
<p>对于 mp4(webm) 格式的视频文件，由于 360 云盘已经支持比较好的 html5 视频播放效果，本扩展就没有提供使用 <code>VXG Media Player</code> 插件进行播放的功能。</p>
</blockquote>
<p>上面截图展示的就是点击 <code>[转码视频]</code> 链接之后使用 <code>VXG Media Player</code> 插件播放 mkv 视频的效果；当然你也可以在增加的 <code>[转码视频]</code> 和 <code>[原画视频]</code> 链接上点右键复制视频地址在其它播放器中播放（强烈建议 Chromebook 用户安装 Chrome 商店中的 VLC 播放器应用）。</p>
<p>如果你的 Chrome 浏览器没有安装 <code>VXG Media Player</code> 插件，那么在点击 <code>[转码视频]</code> 和 <code>[原画视频]</code> 链接时会自动提示你转到 Chrome 商店安装该媒体播放器插件：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737371494/install-vxg-player.png" alt="提示安装 VXG Media Player 插件" title="提示安装 VXG Media Player 插件"></p>
<p>当然还是要说下本云盘播放助手扩展目前存在的问题：</p>
<ul>
<li><code>VXG Media Player</code> 插件的控制条暂时不支持拖动、快放、慢放、暂停操作，看起来是有些不足，视频插件更新之后应该会有改善；</li>
<li>mkv 等格式的高清视频效果没有外部 VLC 播放器的效果好；</li>
<li>360 云盘自动转码的 m3u8 HLS 视频某些情况下会出现播放速度过快的问题，还是 <code>VXG Media Player</code> 插件的锅，只能等后续更新了；</li>
<li>从上面的截图可以看到播放时会显示 <code>VXG Media Player</code> 插件的 logo 和评估版本的提醒，这个由于是个人使用也不好去掉咯。</li>
</ul>
<p>因此如果你发现 <code>VXG Media Player</code> 插件的播放效果不给力，也大可以使用其它播放器播放，本扩展并没有捆绑依赖 <code>VXG Media Player</code> 插件。</p>
<p>本扩展的源代码已经发布到 GitHub 上：</p>
<p><a href="https://github.com/zohead/cloud-disk-player-helper">https://github.com/zohead/cloud-disk-player-helper</a></p>
<p>如果你在使用云盘播放助手扩展的过程中发现任何问题，欢迎在本扩展的 Chrome 商店页面、GitHub 项目支持页面、本博客文章下提交 issue 或者留言，最后祝玩的开心～～～</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/cloud-player-helper/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Chrome OS自动升级后crouton音频的问题</title>
		<link>https://zohead.com/archives/chromeos-crouton-audio/</link>
		<comments>https://zohead.com/archives/chromeos-crouton-audio/#comments</comments>
		<pubDate>Sat, 26 Mar 2016 19:00:05 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[Chrome]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Chrome OS]]></category>
		<category><![CDATA[Chromebook]]></category>
		<category><![CDATA[CRAS]]></category>
		<category><![CDATA[Crouton]]></category>
		<category><![CDATA[PulseAudio]]></category>
		<category><![CDATA[代理]]></category>
		<category><![CDATA[音频]]></category>

		<guid isPermaLink="false">https://zohead.com/?p=1200</guid>
		<description><![CDATA[日常使用 Chromebook 的朋友们应该都知道 Chrome OS 系统默认是自动推送并更新的，这样可以让你的 Chromebook 等设备始终用上最新的系统，跟上 Google 的步伐，这个特性对于我来说还是相当好的，不过今天我的 Dell Chromebook 11 自动更新到 49.0.2623.95 版本之后却发现 crouton 系统里略显严重的音频问题。 crouton 是一个通用的在 Chrome OS 系统里以 chroot 方式运行普通 Linux 系统的环境，这里我就不做介绍了，由于要测试一下我之前修改的 PPTV Kodi（XBMC） 插件，直接通过 crouton  [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>日常使用 Chromebook 的朋友们应该都知道 Chrome OS 系统默认是自动推送并更新的，这样可以让你的 Chromebook 等设备始终用上最新的系统，跟上 Google 的步伐，这个特性对于我来说还是相当好的，不过今天我的 Dell Chromebook 11 自动更新到 49.0.2623.95 版本之后却发现 crouton 系统里略显严重的音频问题。</p>
<p><a href="https://github.com/dnschneid/crouton">crouton</a> 是一个通用的在 Chrome OS 系统里以 chroot 方式运行普通 Linux 系统的环境，这里我就不做介绍了，由于要测试一下我之前修改的 PPTV Kodi（XBMC） 插件，直接通过 crouton 启动 Ubuntu 14.04 trusty 系统，跟往常一样打开 Kodi 却发现没有任何反应。系统没有直接给出任何报错信息，通过命令可以看到 kodi.bin 进程在运行但一直没有看到 Kodi 媒体系统界面，查看 Kodi 的日志文件 <code>~/.kodi/temp/kodi.log</code> 也看不到有用的错误信息。</p>
<p>接下来发现更加奇怪的是似乎 crouton 系统里所有和音频相关的程序都是启动了没有任何反应，包含 XFCE 自带的 Audio Mixer，例如我之前用的好好的 SuperTux 2 小游戏（一款类似超级马里奥的 Linux 游戏）也运行不了，通过给 SuperTux 2 启动命令加调试输出的参数可以看到：</p>
<pre class="brush: bash; title: ; notranslate">
(trusty)zzm@localhost:~$ supertux2 --verbose
[INFO] /build/supertux-e4GX8V/supertux-0.4.0/src/supertux/main.cpp:236 PhysfsWriteDir: /home/zzm/.supertux2
[INFO] /build/supertux-e4GX8V/supertux-0.4.0/src/supertux/main.cpp:237 PhysfsSearchPath:
[INFO] /build/supertux-e4GX8V/supertux-0.4.0/src/supertux/main.cpp:241   /home/zzm/.supertux2
[INFO] /build/supertux-e4GX8V/supertux-0.4.0/src/supertux/main.cpp:241   /usr/share/games/supertux2
[INFO] /build/supertux-e4GX8V/supertux-0.4.0/src/supertux/main.cpp:305 Component 'config' finished after 0.001 seconds
[INFO] /build/supertux-e4GX8V/supertux-0.4.0/src/supertux/main.cpp:305 Component 'tinygettext' finished after 0.094 seconds
[INFO] /build/supertux-e4GX8V/supertux-0.4.0/src/supertux/main.cpp:305 Component 'controller' finished after 0.001 seconds
[INFO] /build/supertux-e4GX8V/supertux-0.4.0/src/supertux/main.cpp:305 Component 'commandline' finished after 0 seconds
[INFO] /build/supertux-e4GX8V/supertux-0.4.0/src/video/gl/gl_renderer.cpp:61 no support for late swap tearing vsync: No OpenGL context has been made current
[INFO] /build/supertux-e4GX8V/supertux-0.4.0/src/video/gl/gl_renderer.cpp:64 no support for vsync: No OpenGL context has been made current
[INFO] /build/supertux-e4GX8V/supertux-0.4.0/src/video/gl/gl_renderer.cpp:132 Using GLEW 1.10.0
[INFO] /build/supertux-e4GX8V/supertux-0.4.0/src/video/gl/gl_renderer.cpp:133 GLEW_ARB_texture_non_power_of_two: 1
[INFO] /build/supertux-e4GX8V/supertux-0.4.0/src/supertux/main.cpp:291 window  Window: Size(1280, 712) Fullscreen: Size(0, 0)@0 Area: Size(0, 0)
[INFO] /build/supertux-e4GX8V/supertux-0.4.0/src/supertux/main.cpp:305 Component 'video' finished after 0.074 seconds
</pre>
<p>从上面的输出可以看到 SuperTux 已经可以正确加载视频组件了，但似乎到了音频时就直接卡住没反应了，这时我想起看看 crouton 系统的 PulseAudio 音频功能是否工作正常：</p>
<pre class="brush: bash; title: ; notranslate">
(trusty)zzm@localhost:~$ ps ax | grep pulseaudio
 2034 ?        Sl     0:00 /usr/bin/pulseaudio --start --log-target=syslog
11585 ?        Sl     0:00 /usr/bin/pulseaudio --start --log-target=syslog
11944 pts/2    Sl     0:00 /usr/bin/pulseaudio --start --log-target=syslog
11991 pts/2    Sl     0:00 /usr/bin/pulseaudio --start --log-target=syslog
12055 pts/2    Sl     0:00 /usr/bin/pulseaudio --start --log-target=syslog
13094 ?        Sl     0:00 /usr/bin/pulseaudio --start --log-target=syslog
13301 ?        Sl     0:00 /usr/bin/pulseaudio --start --log-target=syslog
13388 pts/2    S+     0:00 grep --color=auto pulseaudio
27624 ?        S      0:00 /usr/bin/pulseaudio --start --log-target=syslog
27630 ?        S      0:00 /bin/sh /usr/bin/start-pulseaudio-x11
27640 ?        Ss     0:00 /usr/bin/pulseaudio --start --log-target=syslog
27641 ?        Sl     0:00 /usr/bin/pulseaudio --start --log-target=syslog
27645 ?        Sl     0:00 /usr/bin/pulseaudio --start --log-target=syslog
</pre>
<p>这下才发现 Ubuntu 的 PulseAudio 音频服务已经不正常了，系统里已经启动了多个 pulseaudio 进程，但都是直接卡住无法退出的状态，我们可以看看系统日志的输出：</p>
<pre class="brush: plain; title: ; notranslate">
2016-03-26T00:44:51.253228+08:00 ERR pulseaudio[13959]: cras_client: Unknown server_state version.
2016-03-26T00:47:17.599107+08:00 ERR pulseaudio[14281]: cras_client: Unknown server_state version.
</pre>
<p>看到 <code>cras_client</code> 就明白了这个是之前大概了解过的 Chrome OS 音频客户端，看看 crouton 官方 Wiki 里关于音频系统的说明：</p>
<p><a href="https://github.com/dnschneid/crouton/wiki/Audio">https://github.com/dnschneid/crouton/wiki/Audio</a></p>
<p>开始就说的是 crouton 系统里音频工作机制：</p>
<pre class="brush: plain; title: ; notranslate">
Audio in crouton should work out of the box, with sound control synchronized between Chrome OS and crouton. By default, audio is forwarded to Chromium OS Audio Server (CRAS), and you will be able to play audio from both Chromium OS and crouton at the same time, without problem.
</pre>
<p>也就是 crouton 系统里的音频是以 ALSA 插件方式直接通过 Chrome OS 自带的 CRAS (Chromium OS audio server) 服务器实现的，这样存在的问题就是 Chrome OS 主系统自动升级之后可能和 crouton 里已经安装的 CRAS 插件不兼容了，这样 PulseAudio 音频服务就会启动失败。</p>
<p>解决方法也就简单了，用最新的 crouton 脚本更新一下已经安装的 Linux 系统一般就能搞定了（请自行把下面的 <code>trusty</code> 换成你安装的 crouton 系统名称）：</p>
<pre class="brush: bash; title: ; notranslate">
chronos@localhost ~/Downloads $ sudo sh ./crouton -n trusty -u
</pre>
<blockquote>
<p><strong>提示</strong></p>
<p>鉴于国内不少 Chromebook 用户没有路由器直接翻墙的条件，而 crouton 系统里又是不能直接使用 Chrome OS 的代理的，这样很多用户会在 crouton 脚本从 <code>chromium.googlesource.com</code> 网站下载音频程序这一步遇到被墙阻挡而更新失败的问题。</p>
<p>这里我安利一下我修改过的 crouton 脚本，和官方脚本的唯一区别就是通过 HTTP（HTTPS） 代理从 <code>chromium.googlesource.com</code> 网站下载音频程序，我已经放到 Gist 上，需要的朋友可以从此 <a href="https://gist.github.com/zohead/1ca9a7371eb0566a5826/raw/836b483b4c67cd846c85f1b48fc942618649c155/crouton">Gist 链接</a> 下载。</p>
</blockquote>
<p>更新成功之后会看到 crouton 其实已经在输出信息的最后对这个问题做了说明,只能怪自己当初安装 crouton 系统的时候就没注意到这点了 -_-#：</p>
<pre class="brush: plain; title: ; notranslate">
Audio from the chroot will now be forwarded to CRAS (Chromium OS audio server),
through an ALSA plugin.

Future Chromium OS upgrades may break compatibility with the installed version
of CRAS. Should this happen, simply update your chroot.
</pre>
<p>另外需要说明的是如果你的 crouton 系统里安装了不止一个图形系统 target （例如我同时安装了 <code>xorg</code> 和 <code>xiwi</code> 这两个 target，默认的 xorg 是为了更好的性能，xiwi 则是为了可以直接在 Chrome OS 系统里以窗口形式运行 Linux 图形程序），那么 crouton 系统自动更新之后默认的图形系统可能会被改回来，这是你只要修改对应 crouton 系统的 xmethod 配置文件 （例如我的是： <code>/usr/local/chroots/trusty/etc/crouton/xmethod</code>） 就可以重新配置默认的图形系统了。</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/chromeos-crouton-audio/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>修改Remix OS kernel支持Chromebook触控板</title>
		<link>https://zohead.com/archives/remixos-cb-trackpad/</link>
		<comments>https://zohead.com/archives/remixos-cb-trackpad/#comments</comments>
		<pubDate>Tue, 01 Mar 2016 18:16:13 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[Chrome]]></category>
		<category><![CDATA[kernel]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[Chromebook]]></category>
		<category><![CDATA[chromeos_laptop]]></category>
		<category><![CDATA[cyapa]]></category>
		<category><![CDATA[cyapatp]]></category>
		<category><![CDATA[I2C]]></category>
		<category><![CDATA[Remix OS]]></category>
		<category><![CDATA[触控板]]></category>

		<guid isPermaLink="false">https://zohead.com/?p=1183</guid>
		<description><![CDATA[继续接着上一篇文章「修改Remix OS适配Chromebook键盘」的修改之后在我的 Dell Chromebook 11 上使用 ext4 U 盘形式的 Remix OS PC 版已经是比较顺利了，那么剩下最大的问题就是触控板问题了，要知道之前我使用 Remix OS 的时候都是必须插着一个 USB 鼠标的。 Chromebook 的触控板由于比较特殊之前很多网友安装的 Ubuntu 系统里经常也用不了，这里我以 Dell Chromebook 11 为例子对 Remix OS PC 版内核模块做一些修改可以实现 Remix OS 下基本的触控功能，对于在 Chromebook 上单独安装 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>继续接着上一篇文章「<a href="https://zohead.com/archives/remixos-cb-keyboard/">修改Remix OS适配Chromebook键盘</a>」的修改之后在我的 Dell Chromebook 11 上使用 ext4 U 盘形式的 Remix OS PC 版已经是比较顺利了，那么剩下最大的问题就是触控板问题了，要知道之前我使用 Remix OS 的时候都是必须插着一个 USB 鼠标的。</p>
<p>Chromebook 的触控板由于比较特殊之前很多网友安装的 Ubuntu 系统里经常也用不了，这里我以 Dell Chromebook 11 为例子对 Remix OS PC 版内核模块做一些修改可以实现 Remix OS 下基本的触控功能，对于在 Chromebook 上单独安装的 Linux 系统下想使用触控板的用户也能做一个参考。</p>
<p>下面的篇幅有很大一部分是对 Remix OS 不能使用 Chromebook 触控板的原因分析，不想了解技术细节的话可以直接拖到最后「<em>修改 Remix OS 系统文件</em>」部分下载并使用我修改编译出来的适合 Remix OS 的内核模块哦。</p>
<blockquote>
<p>编写这篇文章时我使用的是 Remix OS PC 版 2016-02-01 alpha 版本，对应 Android x86 5.1.1 版本，Linux kernel 版本 4.0.9； <br />
  我使用的 Chrome OS 版本是 48.0.2564.116 正式版，Linux kernel 版本 3.8.11。</p>
</blockquote>
<h2 id="触控板问题分析">触控板问题分析</h2>
<p>首先确认能正常工作的 Chrome OS 下的 Chromebook 触控板相关信息，看看 Linux 输入设备中的触控板设备：</p>
<pre class="brush: bash; title: ; notranslate">
I: Bus=0018 Vendor=0000 Product=0000 Version=0001
N: Name=&quot;Cypress APA Trackpad (cyapa)&quot;
P: Phys=i2c-9-0067/input0
S: Sysfs=/devices/pci0000:00/0000:00:15.1/i2c-9/9-0067/input/input7
U: Uniq=
H: Handlers=event7 
B: PROP=5
B: EV=b
B: KEY=e520 10000 0 0 0 0
B: ABS=660800001000003
</pre>
<p>可以看到 Dell Chromebook 11 上的触控板其实用的是 Cypress 家的 APA I2C 输入设备，Chrome OS 上对应 i2c-9 适配器，I2C 地址是 67，对应的 I2C 输入设备驱动为 <code>cyapa</code>。</p>
<blockquote>
<p><strong>提示</strong></p>
<p>其它也有不少三星、HP 之类的 Chromebook 设备用的是 I2C 触控板，但不一定是同一厂商的，有的是使用 ELAN 等 I2C 触控板； <br />
  另外具体机器上 I2C 地址是固定的，i2c-9 适配器则是 Linux kernel 自动生成的并不固定。</p>
</blockquote>
<p>接下来看看 I2C 适配器实际对应的设备位置和名称：</p>
<pre class="brush: bash; title: ; notranslate">
chronos@localhost ~ $ cd /sys/class/i2c-adapter/
chronos@localhost /sys/class/i2c-adapter $ ls -dl *
lrwxrwxrwx 1 root root 0 Mar  1 22:38 i2c-0 -&gt; ../../devices/pci0000:00/0000:00:02.0/i2c-0
lrwxrwxrwx 1 root root 0 Mar  1 22:38 i2c-1 -&gt; ../../devices/pci0000:00/0000:00:02.0/i2c-1
lrwxrwxrwx 1 root root 0 Mar  1 22:38 i2c-10 -&gt; ../../devices/pci0000:00/0000:00:15.2/i2c-10
lrwxrwxrwx 1 root root 0 Mar  1 22:38 i2c-2 -&gt; ../../devices/pci0000:00/0000:00:02.0/i2c-2
lrwxrwxrwx 1 root root 0 Mar  1 22:38 i2c-3 -&gt; ../../devices/pci0000:00/0000:00:02.0/i2c-3
lrwxrwxrwx 1 root root 0 Mar  1 22:38 i2c-4 -&gt; ../../devices/pci0000:00/0000:00:02.0/i2c-4
lrwxrwxrwx 1 root root 0 Mar  1 22:38 i2c-5 -&gt; ../../devices/pci0000:00/0000:00:02.0/i2c-5
lrwxrwxrwx 1 root root 0 Mar  1 22:38 i2c-6 -&gt; ../../devices/pci0000:00/0000:00:02.0/drm/card0/card0-eDP-1/i2c-6
lrwxrwxrwx 1 root root 0 Mar  1 22:38 i2c-7 -&gt; ../../devices/pci0000:00/0000:00:02.0/drm/card0/card0-DP-1/i2c-7
lrwxrwxrwx 1 root root 0 Mar  1 22:38 i2c-8 -&gt; ../../devices/pci0000:00/0000:00:1f.3/i2c-8
lrwxrwxrwx 1 root root 0 Mar  1 22:38 i2c-9 -&gt; ../../devices/pci0000:00/0000:00:15.1/i2c-9
chronos@localhost /sys/class/i2c-adapter $ cat i2c-*/name
i915 gmbus ssc
i2c-designware-pci-1
i915 gmbus vga
i915 gmbus panel
i915 gmbus dpc
i915 gmbus dpb
i915 gmbus dpd
DPDDC-A
DPDDC-B
SMBus I801 adapter at 0400
i2c-designware-pci-0
</pre>
<p>可以看到触控板的 I2C 适配器 i2c-9 在 PCI 设备 0000:00:15.1 上，名称为：<code>i2c-designware-pci-0</code>，另外系统里还有 i2c-10 适配器在 0000:00:15.2 上，名称为：<code>i2c-designware-pci-1</code>，这两个适配器对应的 I2C 总线驱动是：<code>i2c-designware-pci</code>。</p>
<p>下面就可以在 Chromebook 上启动 Remix OS 确认其内核下 I2C 设备信息是否正确：</p>
<pre class="brush: bash; title: ; notranslate">
chronos@localhost ~ $ cd /sys/class/i2c-adapter/
root@remix_cn_x86_64:/sys/class/i2c-adapter # ls -dl *
lrwxrwxrwx root     root              2016-03-01 00:24 i2c-0 -&gt; ../../devices/pci0000:00/0000:00:02.0/i2c-0
lrwxrwxrwx root     root              2016-03-01 00:24 i2c-1 -&gt; ../../devices/pci0000:00/0000:00:02.0/i2c-1
lrwxrwxrwx root     root              2016-03-01 00:24 i2c-10 -&gt; ../../devices/pci0000:00/0000:00:1f.3/i2c-10
lrwxrwxrwx root     root              2016-03-01 00:24 i2c-2 -&gt; ../../devices/pci0000:00/0000:00:02.0/i2c-2
lrwxrwxrwx root     root              2016-03-01 00:24 i2c-3 -&gt; ../../devices/pci0000:00/0000:00:02.0/i2c-3
lrwxrwxrwx root     root              2016-03-01 00:24 i2c-4 -&gt; ../../devices/pci0000:00/0000:00:02.0/i2c-4
lrwxrwxrwx root     root              2016-03-01 00:24 i2c-5 -&gt; ../../devices/pci0000:00/0000:00:02.0/i2c-5
lrwxrwxrwx root     root              2016-03-01 00:24 i2c-6 -&gt; ../../devices/pci0000:00/0000:00:02.0/i2c-6
lrwxrwxrwx root     root              2016-03-01 00:24 i2c-7 -&gt; ../../devices/pci0000:00/0000:00:02.0/i2c-7
lrwxrwxrwx root     root              2016-03-01 00:24 i2c-8 -&gt; ../../devices/pci0000:00/0000:00:15.1/i2c-8
lrwxrwxrwx root     root              2016-03-01 00:24 i2c-9 -&gt; ../../devices/pci0000:00/0000:00:15.2/i2c-9
root@remix_cn_x86_64:/sys/class/i2c-adapter # cat i2c-*/name
i915 gmbus ssc
i915 gmbus vga
SMBus I801 adapter at 0400
i915 gmbus panel
i915 gmbus dpc
i915 gmbus dpb
i915 gmbus dpd
DPDDC-A
DPDDC-B
i2c-designware-pci
i2c-designware-pci
</pre>
<p>这样可以发现 Remix OS 内核下两个 I2C 适配器为 i2c-8 和 i2c-9，虽然 i2c-8 是触控板设备但是使用起来应该是没有影响的，I2C 总线驱动也是正确的，但适配器名称都是一样的 <code>i2c-designware-pci</code>。</p>
<p>同时进一步确认之后发现 Remix OS 内核下虽然没有 Chrome OS 里直接使用的 <code>cyapa</code> 驱动，但其默认集成了新的 Linux kernel 里自带的 <code>cyapatp</code> 驱动。<code>cyapa</code> 是 Google 为 Chromebook 内核专门修改的 Cypress Gen3 系列触控板驱动，而查看源代码之后发现 <code>cyapatp</code> 驱动不但支持 Cypress Gen3 系列触控板，也支持新的 Gen5 系列触控板，这样按说 <code>cyapatp</code> 直接就是支持我的 Chromebook 触控板设备的。</p>
<p>比较郁闷的是我直接在 Remix OS 终端里运行 <code>modprobe cyapatp</code> 命令虽然能成功加载驱动，但系统中并没有注册任何新的输入设备。</p>
<h2 id="chromebook-kernel-研究">Chromebook kernel 研究</h2>
<p>没办法就只能先检出 Chrome OS 当前使用的 3.8.11 版本内核源代码研究下了，检出方法可以参考我之前写的「<a href="https://zohead.com/archives/koding-chromebook/">在Koding云平台上编译Chromebook kernel</a>」这篇文章，Chrome OS kernel 分支可以在这里看到：</p>
<p><a href="https://chromium.googlesource.com/chromiumos/third_party/kernel/">https://chromium.googlesource.com/chromiumos/third_party/kernel/</a></p>
<p>稍微研究后发现原来 Chrome OS kernel 里增加了一个 <code>chromeos_laptop</code> 平台相关的驱动，Chrome OS 系统启动时会加载这个驱动（实际上是直接编译到 Chrome OS kernel 中的），<code>chromeos_laptop</code> 中会自动尝试查找并实例化 Chromebook 上的 I2C/SMBus 设备，看看其中的部分代码：</p>
<pre class="brush: cpp; title: chromeos_laptop.c; notranslate">
#define CYAPA_TP_I2C_ADDR	0x67

const char *i2c_adapter_names[] = {
	&quot;SMBus I801 adapter&quot;,
	&quot;i915 gmbus vga&quot;,
	&quot;i915 gmbus panel&quot;,
	&quot;i2c-designware-pci-0&quot;,
	&quot;i2c-designware-pci-1&quot;,
};

/* Keep this enum consistent with i2c_adapter_names */
enum i2c_adapter_type {
	I2C_ADAPTER_SMBUS = 0,
	I2C_ADAPTER_VGADDC,
	I2C_ADAPTER_PANEL,
	I2C_ADAPTER_I2C0,
	I2C_ADAPTER_I2C1,
};

static struct i2c_board_info cyapa_device = {
	I2C_BOARD_INFO(&quot;cyapa&quot;, CYAPA_TP_I2C_ADDR),
	.flags		= I2C_CLIENT_WAKE,
};

static struct chromeos_laptop wolf = {
	.i2c_peripherals = {
		/* Touchpad. */
		{ .add = setup_cyapa_tp, I2C_ADAPTER_I2C0 },
		/* Elan Touchpad option. */
		{ .add = setup_elantech_tp, I2C_ADAPTER_I2C0 },
	},
};

static struct i2c_client *add_i2c_device(const char *name,
						enum i2c_adapter_type type,
						struct i2c_board_info *info)
{
	const unsigned short addr_list[] = { info-&gt;addr, I2C_CLIENT_END };
	return __add_probed_i2c_device(name,
				       find_i2c_adapter_num(type),
				       info,
				       addr_list);
}

static int setup_cyapa_tp(enum i2c_adapter_type type)
{
	if (tp)
		return 0;

	/* add cyapa touchpad */
	tp = add_i2c_device(&quot;trackpad&quot;, type, &amp;cyapa_device);
	return (!tp) ? -EAGAIN : 0;
}
</pre>
<p>稍微分析下可以看到 <code>chromeos_laptop</code> 驱动是根据名称找到当前系统中的 I2C 适配器的，找到之后最后根据 I2C 地址调用 <code>i2c_new_probed_device</code> 函数实例化 I2C 设备，而这里 <code>cyapa</code> 触控板驱动使用的 I2C 适配器名称固定为 <code>i2c-designware-pci-0</code>。</p>
<p>这样就有 Remix OS 下使用触控板的解决思路了，我们可以修改 <code>i2c-designware-pci</code> 驱动使其报上来的两个 I2C 适配器使用不同的名称，并加入 <code>chromeos_laptop</code> 驱动这样就可以正常使用新的 <code>cyapatp</code> 驱动；或者也可以不修改 <code>i2c-designware-pci</code> 而直接加入并修改 <code>chromeos_laptop</code> 中的触控板 I2C 适配器名称，为了后续 I2C 的区分我决定用第一种方法。</p>
<h2 id="remix-os-kernel-修改">Remix OS kernel 修改</h2>
<p>首先我们就要检出技德不久前开放的 Remix OS kernel 代码了，地址在这里：</p>
<p><a href="https://github.com/jide-opensource/remixos-kernel/">https://github.com/jide-opensource/remixos-kernel/</a></p>
<p>值得一提的是 Remix OS 内核基本就是使用的默认 android-x86_64_defconfig 配置，先开始修改 <code>i2c-designware-pcidrv.c</code> 代码以支持使用不同的 I2C 适配器名称：</p>
<pre class="brush: diff; title: ; notranslate">
--- a/i2c-designware-pcidrv.c	2016-03-02 01:04:19.330843871 +0800
+++ b/i2c-designware-pcidrv.c	2016-03-01 00:18:04.502977140 +0800
@@ -48,7 +48,8 @@ enum dw_pci_ctl_id_t {
 	medfield_5,
 
 	baytrail,
-	haswell,
+	haswell_0,
+	haswell_1,
 };
 
 struct dw_scl_sda_cfg {
@@ -148,7 +149,15 @@ static struct dw_pci_controller dw_pci_c
 		.functionality = I2C_FUNC_10BIT_ADDR,
 		.scl_sda_cfg = &amp;byt_config,
 	},
-	[haswell] = {
+	[haswell_0] = {
+		.bus_num = -1,
+		.bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
+		.tx_fifo_depth = 32,
+		.rx_fifo_depth = 32,
+		.functionality = I2C_FUNC_10BIT_ADDR,
+		.scl_sda_cfg = &amp;hsw_config,
+	},
+	[haswell_1] = {
 		.bus_num = -1,
 		.bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
 		.tx_fifo_depth = 32,
@@ -258,7 +267,8 @@ static int i2c_dw_pci_probe(struct pci_d
 	adap-&gt;dev.parent = &amp;pdev-&gt;dev;
 	adap-&gt;nr = controller-&gt;bus_num;
 
-	snprintf(adap-&gt;name, sizeof(adap-&gt;name), &quot;i2c-designware-pci&quot;);
+	snprintf(adap-&gt;name, sizeof(adap-&gt;name), &quot;i2c-designware-pci-%ld&quot;,
+		(adap-&gt;nr &lt; 0) ? id-&gt;driver_data - haswell_0 : adap-&gt;nr);
 
 	r = devm_request_irq(&amp;pdev-&gt;dev, pdev-&gt;irq, i2c_dw_isr, IRQF_SHARED,
 			adap-&gt;name, dev);
@@ -314,8 +324,8 @@ static const struct pci_device_id i2_des
 	{ PCI_VDEVICE(INTEL, 0x0F46), baytrail },
 	{ PCI_VDEVICE(INTEL, 0x0F47), baytrail },
 	/* Haswell */
-	{ PCI_VDEVICE(INTEL, 0x9c61), haswell },
-	{ PCI_VDEVICE(INTEL, 0x9c62), haswell },
+	{ PCI_VDEVICE(INTEL, 0x9c61), haswell_0 },
+	{ PCI_VDEVICE(INTEL, 0x9c62), haswell_1 },
 	/* Braswell / Cherrytrail */
 	{ PCI_VDEVICE(INTEL, 0x22C1), baytrail },
 	{ PCI_VDEVICE(INTEL, 0x22C2), baytrail },
</pre>
<p>然后将 Chrome OS 3.8.11 版本 kernel 中的 <code>chromeos_laptop</code> 平台相关驱动加到 Remix OS 4.0.9 版本 kernel 中，最后开始编译内核 bzImage 和对应的内核模块文件，实际上编译 bzImage 只是为了生成需要的 Module.symvers 符号文件，真正要使用的是新编译生成的 <code>i2c-designware-pci.ko</code> 和 <code>chromeos_laptop.ko</code> 文件。</p>
<blockquote>
<p><strong>提示</strong></p>
<p>我是在 Chromebook Crouton 64 位 Ubuntu 14.04 环境中检出并修改 Remix OS kernel 进行编译的，实际 kernel 修改、加入新驱动修改 Makefile 和 Kconfig 等还有编译操作步骤什么的这里就不说明了，编译中间可能会有无线驱动报错，稍微修改下内核配置就可以通过了。</p>
</blockquote>
<h2 id="修改-remix-os-系统文件">修改 Remix OS 系统文件</h2>
<p>我编译好的两个内核模块文件下载地址（只适用于 Remix OS PC 版 alpha 4.0.9 内核）：</p>
<p><a href="https://zohead.com/downloads/cbtp-remixos-20160201alpha.zip">https://zohead.com/downloads/cbtp-remixos-20160201alpha.zip</a></p>
<p>首先可以在 Chromebook 上将新的内核模块文件放到 Remix OS U 盘中，如果你使用的是按照我之前的「<a href="https://zohead.com/archives/cb-ext4-remixos/">Chromebook使用ext4 U盘运行Remix OS</a>」文章介绍的方法生成的 ext4 格式 U 盘，那么修改替换 Remix OS 系统文件还是非常简单的。</p>
<pre class="brush: bash; title: ; notranslate">
(trusty)zzm@localhost:~$ sudo cp i2c-designware-pci.ko /media/removable/Android-x86/android-2016-02-02/system/lib/modules/4.0.9-android-x86_64+/kernel/drivers/i2c/busses/
(trusty)zzm@localhost:~$ sudo cp chromeos_laptop.ko /media/removable/Android-x86/android-2016-02-02/system/lib/modules/4.0.9-android-x86_64+/kernel/drivers/platform/x86/
</pre>
<blockquote>
<p><strong>注意</strong></p>
<p>上面的命令例子中假定 Remix OS U 盘已经自动被 Chrome OS 挂载到 <code>/media/removable/Android-x86</code> 目录了，<code>android-2016-02-02</code> 是 Remix OS 系统路径，实际的挂载和系统路径不完全相同请自行检查。</p>
</blockquote>
<p>下面是使用 <code>depmod</code> 命令重新生成新的模块依赖关系等文件，这样 Remix OS 系统在启动的时候就会自动尝试加载 <code>chromeos_laptop</code> 驱动，接着自动加载 <code>cyapatp</code> 驱动成功之后就可以直接 Chromebook 触控板了。</p>
<pre class="brush: bash; title: ; notranslate">
sudo depmod -A -b /media/removable/Android-x86/android-2016-02-02/system 4.0.9-android-x86_64+
</pre>
<p>最后说下我简单测试之后 Remix OS 中 Chromebook 触控板的使用效果：</p>
<ul>
<li>基本的移动、点击等操作可以正常工作；</li>
<li>看起来也是支持简单的多点触控的；</li>
<li>Remix OS 桌面图标的双击功能不起作用；</li>
<li>Chrome OS 下特色的两指上下滚动功能也可以正常使用（不过由于 Android 的自然滚动方式所以方向和 Chrome OS 下是相反的）；</li>
<li>某些 App 下面支持三指同时长按然后放开之后出现右键菜单；</li>
<li>Chrome OS 下特色的两指同时点击呼出右键菜单功能无效。</li>
</ul>
<p>总之虽然触控版的使用不像 Chrome OS 下那样完美但基本还是能满足需求的，本文中有任何错误或疑问欢迎提出指正哦，祝玩的开心～～～。</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/remixos-cb-trackpad/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>修改Remix OS适配Chromebook键盘</title>
		<link>https://zohead.com/archives/remixos-cb-keyboard/</link>
		<comments>https://zohead.com/archives/remixos-cb-keyboard/#comments</comments>
		<pubDate>Tue, 23 Feb 2016 18:01:03 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Chrome]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[Chromebook]]></category>
		<category><![CDATA[keylayout]]></category>
		<category><![CDATA[Remix OS]]></category>
		<category><![CDATA[扫描码]]></category>
		<category><![CDATA[键盘]]></category>

		<guid isPermaLink="false">https://zohead.com/?p=1178</guid>
		<description><![CDATA[按照之前博客里方法在我的 Dell Chromebook 11 上捣鼓使用 ext4 格式 Remix OS U 盘一段时间之后发现对于 Chromebook 上的 Remix OS PC 版一个普遍存在的问题就是 Chromebook 特殊键盘按键功能在 Remix OS 上都不能正常工作了，这对于习惯了 Chrome OS 便利性的我来说还是略不爽的，因此想办法修改了 Remix OS 系统文件以适配 Chromebook 键盘，这里给 Chromebook 用户一个参考。 Chromebook 上的特殊按键包括最上面一排的功能按键和专用搜索键； 功能按键和普通 PC 机上的 F1 - F [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>按照之前博客里方法在我的 Dell Chromebook 11 上捣鼓使用 ext4 格式 Remix OS U 盘一段时间之后发现对于 Chromebook 上的 Remix OS PC 版一个普遍存在的问题就是 Chromebook 特殊键盘按键功能在 Remix OS 上都不能正常工作了，这对于习惯了 Chrome OS 便利性的我来说还是略不爽的，因此想办法修改了 Remix OS 系统文件以适配 Chromebook 键盘，这里给 Chromebook 用户一个参考。</p>
<blockquote>
<p>Chromebook 上的特殊按键包括最上面一排的功能按键和专用搜索键； <br />
  功能按键和普通 PC 机上的 F1 - F12 功能按键有点类似，包括专门为 Chrome OS 设计的前进、后退、全屏、显示亮度控制、音量控制 等按键； <br />
  有关 Chromebook 键盘的相关信息请参考 Google 官方帮助文档 <a href="https://support.google.com/chromebook/answer/1047364">Use your Chromebook keyboard</a> 。</p>
</blockquote>
<p>首先可以用 Crouton Linux 环境中的命令行 <code>showkey</code> 命令或者图形界面下的 <code>xev</code> 命令检查 Chromebook 上特殊按键的 scan code，确认之后发现：</p>
<blockquote>
<p>直接运行 Remix OS 的话也可以安装 <a href="https://play.google.com/store/apps/details?id=aws.apps.keyeventdisplay">KeyEvent Display</a> 这款 App 来确认 Chromebook 上按键的 scan code。</p>
</blockquote>
<ul>
<li>Chromebook 搜索键的 scan code 为：<strong>125</strong>；</li>
<li>Chromebook 上面一排从后退键到提高音量键这些特殊功能键的 scan code 为：<strong>59 - 68</strong>；</li>
<li>特殊功能键的 scan code 和普通 PC 上的 F1 - F10 一致。</li>
</ul>
<blockquote>
<p><strong>注意</strong></p>
<p>不同 Chromebook 上特殊按键的 scan code 也有可能和上面的结果不同，我列出的结果适用于 Dell Chromebook 11 系列。</p>
</blockquote>
<p>知道这些特殊按键的 scan code 之后就可以修改 Android keylayout 以适配 Chromebook 键盘，不过这一步需要修改 Remix OS PC 版 system 目录中的文件。如果你是按照我写的 <a href="https://zohead.com/archives/cb-ext4-remixos/">Chromebook使用ext4 U盘运行Remix OS</a> 文章中的方法安装的，那只要安装过程中启用了 system 目录的可写功能，那可以直接在 Remix OS（Remix OS 中直接修改需要开启 root 权限） 或者 Chrome OS 里修改还是很方便的。</p>
<blockquote>
<p>如果你是用技德官方的工具烧写的 U 盘那会稍微麻烦点，需要在 Chromebook 等 Linux 系统中挂载 system 映像文件修改并重新打包，网上应该也能找到对应的教程，这里就不做详细介绍了。</p>
</blockquote>
<p>修改 Remix OS 中的 <code>/system/usr/keylayout/Generic.kl</code> 文件，首先注释掉这些已有的行（Android 默认的键盘 scan code 到 key code 映射）：</p>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment">#key 59    F1</span>
<span class="hljs-comment">#key 60    F2</span>
<span class="hljs-comment">#key 61    F3</span>
<span class="hljs-comment">#key 62    F4</span>
<span class="hljs-comment">#key 63    F5</span>
<span class="hljs-comment">#key 64    F6</span>
<span class="hljs-comment">#key 65    F7</span>
<span class="hljs-comment">#key 66    F8</span>
<span class="hljs-comment">#key 67    F9</span>
<span class="hljs-comment">#key 68    F10</span>
<span class="hljs-comment">#key 125   META_LEFT</span></code></pre>
<p>然后增加这些行：</p>
<pre class="prettyprint"><code class="language-bash hljs ">key <span class="hljs-number">59</span>    MEDIA_PREVIOUS
key <span class="hljs-number">60</span>    MEDIA_NEXT
key <span class="hljs-number">61</span>    MEDIA_PLAY_PAUSE
key <span class="hljs-number">62</span>    MENU
key <span class="hljs-number">63</span>    APP_SWITCH
key <span class="hljs-number">64</span>    BRIGHTNESS_DOWN
key <span class="hljs-number">65</span>    BRIGHTNESS_UP
key <span class="hljs-number">66</span>    VOLUME_MUTE
key <span class="hljs-number">67</span>    VOLUME_DOWN
key <span class="hljs-number">68</span>    VOLUME_UP
key <span class="hljs-number">125</span>   CAPS_LOCK</code></pre>
<p>这里分别简单解释下：</p>
<ul>
<li>59 - 后退键，改成了「上一个节目」键，改成 <code>BACK</code> 后退键等特殊键似乎会导致 Remix OS 下键盘输入有点问题，索性改成切换节目键可以配合各种音乐 App 方便切换歌曲；</li>
<li>60 - 前进键，改成了「下一个节目」键；</li>
<li>61 - 刷新键，改成了「播放/暂停」键，本来想改成 <code>MEDIA_REWIND</code> 也就是「倒回」键符合原来刷新键的意思，但测试后发现好多 App 不支持就算了；</li>
<li>62 - 全屏键，改成了「菜单」键，Remix OS 下没有直接的全屏按键，这里就用做现在比较少用了的「菜单」键了，目前看起来只有手动退出手机 QQ 时有用 ^_^；</li>
<li>63 - 切换窗口键，改成了「应用切换」键，类似 Android 原生的效果，和 Remix OS 自带的按 <kbd>Alt+Tab</kbd> 键切换应用效果稍微有点不一样；</li>
<li>64 - 降低亮度键；</li>
<li>65 - 提高亮度键；</li>
<li>66 - 静音键；</li>
<li>67 - 降低音量键；</li>
<li>68 - 提高音量键；</li>
<li>125 - 搜索键，改成了「大小写切换」键，因为发现现在 Android 下对原生搜索键支持的 App 太少（测试了只有 Chrome 支持），就改成了更常用的 <kbd>Caps lock</kbd> 键了，如果你想换成 Android 原生搜索键的话可以将值改为 <code>SEARCH</code>。</li>
</ul>
<p>修改之后重新启动 Remix OS 系统就可以看到这些特殊按键的效果了，这样起码能让 Chromebook 用的更顺利咯。如果文章中有任何问题欢迎提出指正哦，祝元宵节后玩的开心～～～</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/remixos-cb-keyboard/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>在PC机上安装CloudReady体验Chrome OS</title>
		<link>https://zohead.com/archives/cloudready/</link>
		<comments>https://zohead.com/archives/cloudready/#comments</comments>
		<pubDate>Fri, 11 Dec 2015 17:55:56 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[Chrome]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[Chrome OS]]></category>
		<category><![CDATA[Chromium]]></category>
		<category><![CDATA[CloudReady]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Neverware]]></category>

		<guid isPermaLink="false">http://zohead.com/?p=1098</guid>
		<description><![CDATA[笔者之前一直都是用的三星 ARM Chromebook 体验 Chrome OS 这个轻量化的浏览器操作系统，最近看到 reddit 上有人用 CloudReady 在配置很普通的 PC 上安装的 Chrome OS 效果也是挺不错的，又想到准备做的 Chrome Nacl 开发还是需要 x86 的环境，因此就准备在我的宏碁 Iconia W700 Win10 平板上用 U 盘安装一个 Chrome OS 系统体验看看。 我的老宏碁 Iconia W700 平板基本配置为： Intel Core i3-2375M 处理器; 4GB 内存; Intel HD Graphics 3000 集成显卡 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>笔者之前一直都是用的三星 ARM Chromebook 体验 Chrome OS 这个轻量化的浏览器操作系统，最近看到 reddit 上有人用 CloudReady 在配置很普通的 PC 上安装的 Chrome OS 效果也是挺不错的，又想到准备做的 Chrome Nacl 开发还是需要 x86 的环境，因此就准备在我的宏碁 Iconia W700 Win10 平板上用 U 盘安装一个 Chrome OS 系统体验看看。</p>
<blockquote>
<p>我的老宏碁 Iconia W700 平板基本配置为：</p>
<ul>
<li>Intel Core i3-2375M 处理器;</li>
<li>4GB 内存;</li>
<li>Intel HD Graphics 3000 集成显卡;</li>
<li>平板默认分辨率 1920x1080;</li>
<li>升级的 256GB SSD.</li>
</ul>
<p>这款机器用来跑 Chrome OS 绝对是绰绰有余的，有些网友都是用配置比较烂的 Intel Atom CPU 上网本安装 CloudReady 系统的。</p>
</blockquote>
<h2 id="cloudready相关介绍">CloudReady相关介绍</h2>
<p>CloudReady 是 Neverware 公司基于 Google 开源 Chromium OS 系统开发出的操作系统，可以提供基本类似 Google 在 Chromebook 等设备上的官方 Chrome OS 系统的功能，目前提供面向个人的免费版和面向教育结构的收费版本，两种版本的比较请参考 <a href="http://www.neverware.com/pricing/">这里</a>，个人版本主要少了技术支持服务之类的，建议直接到 <a href="http://www.neverware.com/free">Neverware官网</a> 下载最新的个人版本。</p>
<blockquote>
<p>我写这篇文章时 CloudReady 最新个人版本是 45.1.20 版本，虽然还跟不上 Google 官方已经推出的 Chrome OS 47.0 版本，但使用起来还是没什么大碍的哦。</p>
</blockquote>
<p>另外目前网上也有一些网友自己编译的 Chromium OS 系统提供下载安装，CloudReady 系统相对来说比较好的地方就是其主要方向在这方面，有一定的技术支持，使用时遇到什么问题也可以到其论坛上提问得到解答。</p>
<h2 id="安装说明">安装说明</h2>
<p>将下载到的 zip 压缩文件解压缩会得到一个 5GB 左右的镜像文件，准备一个容量为 8GB 以上的 U 盘（如果你的电脑有 USB 3.0 接口的话那强烈建议使用 USB 3.0 U 盘，会明显提升 CloudReady 系统速度），使用镜像写入工具直接将解压缩出来的镜像文件写入 U 盘即可（Windows 上可以使用 Win32 Disk Imager 之类的工具，Linux 等系统上可以直接使用 dd 命令写入）。</p>
<p>写入完成之后重启电脑，并将电脑设置为从 USB 启动，这样就可以直接引导并体验 CloudReady 系统了，系统主界面如下：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737370806/cloudready.jpg" alt="CloudReady主界面" title="CloudReady主界面"></p>
<p>可以看到 CloudReady 系统界面和 Chrome OS 基本没有任何区别，启动完成之后可以在右下角菜单中选择 “Install CloudReady…” 将 CloudReady 系统直接安装到硬盘。</p>
<blockquote>
<p><strong>注意</strong></p>
<p>由于 CloudReady 系统暂时还不支持多系统启动功能，通过 Install CloudReady 功能将 CloudReady 系统安装到硬盘会直接擦除掉硬盘的原有数据，如果需要保留硬盘上的原有系统请注意谨慎操作。</p>
</blockquote>
<p>不过我可没有打算把我的平板上的 Win10 系统直接擦除掉用 CloudReady Chrome OS 系统，还是准备直接用 USB 3.0 U 盘体验 Chrome OS，这样也比较方便。</p>
<p>我安装 CloudReady 系统时使用的是 16GB 的 U 盘，但启动起来之类才发现 CloudReady 默认留给 home 用户的空间差不多就 1GB（U 盘多余的空间并没有利用到），对于我这种安装了很多 Chrome 插件和 App 的人来说，开机激活并自动同步所有软件和 Chrome 配置之后就已经开始报空间不足了，所以这里强烈建议在第一次启动之间直接按照下面的步骤先扩容 home 用户空间方便使用。</p>
<blockquote>
<p>Chrome OS 的 home 用户空间是专门存放登录用户的配置文件、历史记录、浏览的缓存数据、安装的扩展和 App 等私人数据的单独分区，Chrome OS 上默认唯一可写的专用下载目录也在此空间中，home 用户空间大小可以在 Chrome OS 自带的 <strong>文件</strong> App 中查看到。</p>
</blockquote>
<h2 id="u-盘用户空间扩容">U 盘用户空间扩容</h2>
<p>这一步由于需要直接扩容 U 盘分区，所以最好在 Linux 系统（也可以使用安装了 crouton 的 Chromebook）下操作，在任何一个普通 Linux 系统下插入 U 盘，使用 <strong>parted</strong> 命令的 p 打印命令可以看到安装了 CloudReady 系统的 U 盘（设备名为：<strong>/dev/sda</strong>）分区布局如下：</p>
<pre><code>(trusty)root@localhost:/home/zzm# parted
GNU Parted 2.3
使用 /dev/sda
欢迎使用 GNU Parted! 输入 'help'可获得命令列表.
(parted) p
Model: Teclast CoolFlash USB3.0 (scsi)
磁盘 /dev/sda: 15.7GB
Sector size (logical/physical): 512B/512B
分区表：gpt

数字  开始：  End     大小    文件系统  Name        标志
11    32.8kB  8421kB  8389kB            RWFW
 6    8421kB  8422kB  512B              KERN-C
 7    8422kB  8422kB  512B              ROOT-C
 9    8422kB  8423kB  512B              reserved
10    8423kB  8423kB  512B              reserved
 2    10.5MB  27.3MB  16.8MB            KERN-A
 4    27.3MB  44.0MB  16.8MB            KERN-B
 8    44.0MB  1118MB  1074MB  ext4      OEM         msftdata
12    1185MB  1202MB  16.8MB  fat16     EFI-SYSTEM  启动
 5    1202MB  1204MB  2097kB            ROOT-B
 3    1204MB  4387MB  3183MB  ext2      ROOT-A
 1    4387MB  5461MB  1074MB  ext4      STATE       msftdata
</code></pre>
<p>从上面的结果我们可以看到用户空间正是 U 盘上序号为 1 的分区（文件系统类型为：<strong>ext4</strong>，实际对应设备为：<strong>/dev/sda1</strong>），只不过刚好在分区表上是最后一个，不过其实这也是非常好的地方，这样我们可以直接对序号为 1 的分区进行扩容而不影响其它分区。</p>
<p>下面使用 parted 的 <strong>resizepart</strong> 命令对序号为 1 的分区进行扩容并验证：</p>
<blockquote>
<p><strong>提示</strong></p>
<p>老版本的 parted 并不支持 resizepart 命令，如果你在 parted 中运行 resizepart 提示不支持的话那就需要升级 parted 软件包了。</p>
</blockquote>
<pre><code>(parted) resizepart 1 -1
(parted) p
Model: Teclast CoolFlash USB3.0 (scsi)
磁盘 /dev/sda: 15.7GB
Sector size (logical/physical): 512B/512B
分区表：gpt

数字  开始：  End     大小    文件系统  Name        标志
11    32.8kB  8421kB  8389kB            RWFW
 6    8421kB  8422kB  512B              KERN-C
 7    8422kB  8422kB  512B              ROOT-C
 9    8422kB  8423kB  512B              reserved
10    8423kB  8423kB  512B              reserved
 2    10.5MB  27.3MB  16.8MB            KERN-A
 4    27.3MB  44.0MB  16.8MB            KERN-B
 8    44.0MB  1118MB  1074MB  ext4      OEM         msftdata
12    1185MB  1202MB  16.8MB  fat16     EFI-SYSTEM  启动
 5    1202MB  1204MB  2097kB            ROOT-B
 3    1204MB  4387MB  3183MB  ext2      ROOT-A
 1    4387MB  15.7GB  11.3GB  ext4      STATE       msftdata
</code></pre>
<p>可以看到序号为 1 的分区已经扩容为 11.3GB 了，但实际底层的 ext4 文件系统还没有扩容，扩容 ext4 文件系统之前需要先用 e2fsck 命令检查文件系统：</p>
<pre><code>(trusty)root@localhost:/home/zzm# e2fsck -f /dev/sda1
e2fsck 1.42.9 (4-Feb-2014)
第一步: 检查inode,块,和大小
第二步: 检查目录结构
第3步: 检查目录连接性
Pass 4: Checking reference counts
第5步: 检查簇概要信息
STATE: 30211/65536 files (0.3% non-contiguous), 228239/262144 blocks
</code></pre>
<p>完成之后再使用 resize2fs 命令扩展 U 盘上序号为 1 的分区的文件系统：</p>
<pre><code>(trusty)root@localhost:/home/zzm# resize2fs /dev/sda1
resize2fs 1.42.9 (4-Feb-2014)
Resizing the filesystem on /dev/sda1 to 2755852 (4k) blocks.
The filesystem on /dev/sda1 is now 2755852 blocks long.
</code></pre>
<p>没什么意外的话 resize2fs 操作将能很快完成，此时 U 盘上 home 用户空间的扩容也就完成了，可以重启用 U 盘引导计算机进入 CloudReady 系统了。</p>
<h2 id="安装-flash-插件">安装 Flash 插件</h2>
<p>CloudReady 系统在第一次激活启动的时候就会提示你安装 Adobe Flash 插件，如果你身在墙外或者全程 VPN 的话点击继续应该可以直接安装成功。</p>
<p>如果启动时提示安装 Adobe Flash 插件时安装失败（被墙阻挡是国内用户安装失败的主要原因，因为 Flash 插件需要从 Google 网站上下载 Chrome Linux 安装包），也可以进入系统之后在 Shell 环境下手工安装。</p>
<p>CloudReady 安装 Flash 插件的脚本在 <strong>/opt/neverware/check_or_install_flash.py</strong> 路径下，查看其中的代码可以发现其从这个网址下载 Chrome Linux 安装包并自动解压缩出 Flash 插件文件安装到当前系统 /opt/google/chrome/pepper 中：</p>
<p><em><a href="https://dl-ssl.google.com/linux/direct/google-chrome-stable_current_i386.deb">https://dl-ssl.google.com/linux/direct/google-chrome-stable_current_i386.deb</a></em></p>
<p>我们可以在浏览器中手工下载该文件，并修改 check_or_install_flash.py 文件中的 deb_path 为实际下载到的文件的路径，例如：</p>
<pre><code>deb_path = "/home/chronos/user/Downloads/google-chrome-stable_current_i386.deb"
</code></pre>
<blockquote>
<p><strong>提示</strong></p>
<p>CloudReady 系统下 home 用户路径为 <em>/home/chronos/user</em>，这一点和 Chrome OS 有点不一样（Chrome OS 路径中会附加随机生成的用户 ID），<em>/home/chronos/user/Downloads</em> 即为用户下载目录路径。</p>
</blockquote>
<p>之后再到 Shell 终端中手工运行 check_or_install_flash.py 应该就可以正确安装了，完成之后最好重启下系统使 Flash 插件生效。</p>
<h2 id="使用体验">使用体验</h2>
<p>经过一段时间的实际使用，我发现 CloudReady 还是基本达到了其宣称的类似 Chromebook 体验的，系统界面看起来和 Google 官方 Chrome OS 基本没什么区别，在一般的 PC 机上使用起来也挺流畅的，使用 Google 账户登录之后原先在 Chromebook 或者 PC 端 Chrome 浏览器上使用的所有书签、历史记录、插件和 App 都可以自动同步过来，我之前发布的 Chrome OS 下的 <a href="https://zohead.com/archives/kuaipan-chromeos/">快盘文件系统</a> App 使用起来也没什么问题。</p>
<p>下面总结一下我个人认为的 CloudReady 系统目前的优劣之处：</p>
<p>优点：</p>
<ul>
<li>无缝支持 Google 账户并同步;</li>
<li>支持 Android Runtime，可以运行一些 Android App;</li>
<li>新版本增加了 Netflix 等相关支持;</li>
<li>免费个人版本直接支持 mp3、mp4（H264）硬件解码;</li>
<li>支持单独安装 Adobe Flash 插件;</li>
<li>相对完善的社区支持.</li>
</ul>
<p>缺点：</p>
<ul>
<li>Evernote（印象笔记）等需要 Chrome OS 的 App 无法运行（提示与设备不兼容）;</li>
<li>底层仍然是 32 位 x86 Linux 系统，最大只能使用 4GB 内存;</li>
<li>CloudReady 不支持直接的在线更新.</li>
</ul>
<p>当然实际使用感受还是见仁见智的，欢迎各位安装 CloudReady 系统进行测试咯，文章中有任何问题欢迎提出指正，祝玩的开心~~~</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/cloudready/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Chrome OS在国内时间同步问题分析</title>
		<link>https://zohead.com/archives/chromeos-timesync/</link>
		<comments>https://zohead.com/archives/chromeos-timesync/#comments</comments>
		<pubDate>Thu, 12 Nov 2015 16:21:24 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[Chrome]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[Chrome OS]]></category>
		<category><![CDATA[Chromebook]]></category>
		<category><![CDATA[NTP]]></category>
		<category><![CDATA[tlsdate]]></category>
		<category><![CDATA[tlsdated]]></category>
		<category><![CDATA[代理]]></category>
		<category><![CDATA[时间同步]]></category>

		<guid isPermaLink="false">http://zohead.com/?p=1080</guid>
		<description><![CDATA[最近在使用我的三星 ARM Chromebook 的时候发现一个问题就是这款 Chromebook 在锁定或者待机后电还是会慢慢的跑，如果待机之前电池电量本来就不多了，那再开机时很可能出现电池电量耗尽导致需要插电源重新开机的现象。接着就发现每次开机之后系统时间却不对，这对于 Chrome OS 这款基本一切皆通过网络同步的操作系统还是很意外的，而且我在 Chrome OS 系统设置中确认过网络时间同步也是开启的。 Chromebook 重新开机之后进入时间设置可以看到这样的报错信息： 之前遇到这种情况我都是傻傻的再设置下系统时间，最近准备专门看下系统时间不能正确同步的原因。 目前用户最常用的时 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>最近在使用我的三星 ARM Chromebook 的时候发现一个问题就是这款 Chromebook 在锁定或者待机后电还是会慢慢的跑，如果待机之前电池电量本来就不多了，那再开机时很可能出现电池电量耗尽导致需要插电源重新开机的现象。接着就发现每次开机之后系统时间却不对，这对于 Chrome OS 这款基本一切皆通过网络同步的操作系统还是很意外的，而且我在 Chrome OS 系统设置中确认过网络时间同步也是开启的。</p>
<p>Chromebook 重新开机之后进入时间设置可以看到这样的报错信息：</p>
<div style="width: 497px" class="wp-caption alignnone"><a href="http://res.cloudinary.com/digwht2y0/image/upload/v1737370805/chromeos-tmsync-err.png" target="_blank"><img alt="Chromebook无法设置系统时间错误" src="http://res.cloudinary.com/digwht2y0/image/upload/v1737370805/chromeos-tmsync-err.png" width="487" height="267" /></a><p class="wp-caption-text">Chromebook无法设置系统时间错误</p></div>
<p>之前遇到这种情况我都是傻傻的再设置下系统时间，最近准备专门看下系统时间不能正确同步的原因。</p>
<p>目前用户最常用的时间同步方法一般是通过广域网上的 NTP 时间服务器进行（Linux 下对应 ntpdate 命令），另一种是直接通过连接 HTTPS（TLS）服务器获取时间戳来同步时间（Linux 下对应 tlsdate 命令），这种方式相比 NTP 协议的主要优势就是更加安全了（NTP 协议可是诞生于上个世纪八九十年代的，协议本身没有任何加密认证之类的处理），另外还有一种是通过 HTTP 协议连接 Web 服务器时间来同步时间（对应 htpdate 命令，这个也算是非常通用了，具体见我之前的一篇博文 [<a href="https://zohead.com/archives/htpdate-raspberry/" target="_blank">树莓派上使用htpdate同步时间</a>]）。</p>
<p>Chrome OS 默认使用的就是 TLS 方式进行时间同步，这个可以通过登录到 Chrome OS Linux Shell 中查看运行进程进行确认：</p>
<pre class="brush: bash; title: ; notranslate">
chronos@localhost / $ ps ax | grep tlsdate | grep -v grep
13799 ?        S      0:00 tlsdated -v -- /usr/bin/tlsdate -v -C /usr/share/chromeos-ca-certificates -l
13800 ?        S      0:00 logger -t tlsdate
13801 ?        S      0:00 tlsdated -v -- /usr/bin/tlsdate -v -C /usr/share/chromeos-ca-certificates -l
</pre>
<p>可以看到 Chrome OS 自带的 tlsdated 服务运行 tlsdate 程序进行时间同步，查看 tlsdate 的日志文件 <strong>/var/log/tlsdate.log</strong> 检查为什么会时间同步出错：</p>
<pre class="brush: bash; title: ; notranslate">
chronos@localhost / $ cat /var/log/tlsdate.log
2015-11-10T01:55:05.881307+08:00 NOTICE tlsdate[3050]: V: tlsdate version 0.0.5
2015-11-10T01:55:05.881395+08:00 NOTICE tlsdate[3050]: V: We were called with the following arguments:
2015-11-10T01:55:05.881445+08:00 NOTICE tlsdate[3050]: V: validate SSL certificates host = clients3.google.com:443
2015-11-10T01:55:05.888424+08:00 NOTICE tlsdate[3050]: V: time is currently 1447091705.888190273
2015-11-10T01:55:05.888485+08:00 NOTICE tlsdate[3050]: V: time is greater than RECENT_COMPILE_DATE
2015-11-10T01:55:05.895243+08:00 NOTICE tlsdate[3050]: V: using TLSv1_client_method()
2015-11-10T01:55:05.896043+08:00 NOTICE tlsdate[3050]: V: opening socket to clients3.google.com:443
2015-11-10T01:55:08.881106+08:00 INFO tlsdated[3049]: [event:action_tlsdate_timeout] tlsdate timed out
2015-11-10T01:55:08.881361+08:00 NOTICE tlsdate[3050]: [event:action_tlsdate_timeout] tlsdate timed out
2015-11-10T01:55:08.883912+08:00 INFO tlsdated[3049]: [event:handle_child_death] tlsdate reaped =&gt; pid:3841 uid:234 status:9 code:2
2015-11-10T01:55:08.884132+08:00 NOTICE tlsdate[3050]: [event:handle_child_death] tlsdate reaped =&gt; pid:3841 uid:234 status:9 code:2
2015-11-10T01:57:13.153015+08:00 NOTICE tlsdate[3050]: SSL connection failed
</pre>
<p>这下直接就明白了，tlsdate 连接 <strong>clients3.google.com</strong> HTTPS 端口进行同步，但由于众所周知的大陆 GFW 系统原罪，我们国内的 Chromebook 用户是无法同步成功的（除非已经通过 VPN 之类的进行全局翻墙了）。</p>
<p>解决起来也就很简单了，下面直接列出几种解决方法：</p>
<h2>1、通过 VPN 进行全局翻墙：</h2>
<p>这是比较方便的解决办法，直接所有流量都走 VPN 就不存在问题了，只是我不太喜欢全局翻墙的方式，会影响国内网站的访问速度；不过如果你有支持隧道分流的 Cisco AnyConnect 之类的 VPN 账户，那也完全可以用这种简单的方式；</p>
<h2>2、修改 tlsdate 连接的服务器地址：</h2>
<p>这种方法需要先开启 Chromebook 的开发者模式，将 tlsdate 连接的 HTTPS 服务器地址改为任何一个国内可访问的信任服务器地址，Chrome OS 下 tlsdated 服务的配置文件路径为：<strong>/etc/tlsdate/tlsdated.conf</strong>，默认内容如下：</p>
<pre class="brush: bash; title: /etc/tlsdate/tlsdated.conf; notranslate">
base-path                          /var/cache/tlsdated
dry-run                            no
jitter                             0
max-tries                          10
min-steady-state-interval          86400
should-load-disk                   yes
should-netlink                     yes
should-save-disk                   yes
should-sync-hwclock                yes
steady-state-interval              86400
subprocess-tries                   10
subprocess-wait-between-tries      3
verbose                            yes
wait-between-tries                 10

# Host configuration.
source
	host clients3.google.com
	port 443
	proxy dynamic
end

# Try it without the proxy.
source
	host clients3.google.com
	port 443
	proxy none
end
</pre>
<p>修改此 tlsdated 服务配置文件需要 root 身份，切换到 root 用户后执行下面的命令可以将 Chrome OS 的根文件系统改为可写的状态（默认只读的配置文件无法修改），执行完成之后必须重启才能生效：</p>
<pre class="brush: bash; title: 将Chrome OS根文件系统改为可写; notranslate">
chronos@localhost ~ $ sudo su -
Password:
localhost ~ # cd /usr/share/vboot/bin/
localhost bin # ./make_dev_ssd.sh --remove_rootfs_verification --partitions 4
Kernel B: Disabled rootfs verification.
Backup of Kernel B is stored in: /mnt/stateful_partition/backups/kernel_B_20151110_020745.bin
Kernel B: Re-signed with developer keys successfully.
Successfully re-signed 1 of 1 kernel(s)  on device /dev/mmcblk0.
</pre>
<p>重启之后我们就可以很 happy 的将 tlsdated.conf 配置文件中默认的 clients3.google.com 改为其它服务器地址了，我是直接改为 www.net.cn 万网的主页地址，修改完成之后直接运行 <strong>restart tlsdated</strong> 命令重启 tlsdated 服务就可以马上看到效果了，Chromebook 系统时间已经正常同步过来了。</p>
<h2>3、为 tlsdate 指定时间同步代理服务器：</h2>
<p>相信你也看到上面的 tlsdated.conf 配置文件中的 proxy 参数了，没错 tlsdate 也直接支持通过代理服务器连接 HTTPS 服务器同步时间，如果你信不过其它的服务器，坚持要用 Google 的服务器进行时间同步，那也可以将配置文件中的 proxy 参数由 none 改为代理服务器地址，代理服务器地址的写法也比较简单，例如如果要用 Shadowsocks 的 SOCKS5 代理，则写法如下（假设 Shadowsocks 使用的本地代理端口是 8050）：</p>
<p><strong>socks5://127.0.0.1:8050</strong></p>
<p>修改完成之后重启 tlsdated 服务不出意外也能看到起作用咯。</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/chromeos-timesync/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>使用Exagear Desktop在ARM Chromebook上运行x86程序</title>
		<link>https://zohead.com/archives/exagear-chromebook/</link>
		<comments>https://zohead.com/archives/exagear-chromebook/#comments</comments>
		<pubDate>Thu, 15 Oct 2015 15:25:51 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[Chrome]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[binfmt_misc]]></category>
		<category><![CDATA[Chromebook]]></category>
		<category><![CDATA[Eltechs]]></category>
		<category><![CDATA[Exagear]]></category>
		<category><![CDATA[QEMU]]></category>

		<guid isPermaLink="false">http://zohead.com/?p=1048</guid>
		<description><![CDATA[关于 Exagear Desktop 有 ARM Chromebook 使用经验的朋友们应该都知道 ARM Chromebook 在可折腾性上要比 x86 的 Chromebook 要差上不少，最主要一个原因就是在 Crouton 下的 ARM Linux 无法运行很多流行的 x86 应用程序。 之前我写过一篇在 Raspberry Pi 上运行 x86 Sopcast 程序的文章，这个主要是使用 QEMU 的用户模式实现在 ARM Linux 上运行 x86 的应用程序，但这种方式的主要问题是 QEMU 的性能比较差。一个比较好的消息是国外的 Eltechs 公司推出的 Exgear Des [&#8230;]]]></description>
				<content:encoded><![CDATA[<h2 id="about-exagear-desktop">关于 Exagear Desktop</h2>
<p>有 ARM Chromebook 使用经验的朋友们应该都知道 ARM Chromebook 在可折腾性上要比 x86 的 Chromebook 要差上不少，最主要一个原因就是在 Crouton 下的 ARM Linux 无法运行很多流行的 x86 应用程序。</p>
<p>之前我写过一篇在 <a href="https://zohead.com/archives/raspberry-pi-sopcast/" target="_blank">Raspberry Pi 上运行 x86 Sopcast</a> 程序的文章，这个主要是使用 QEMU 的用户模式实现在 ARM Linux 上运行 x86 的应用程序，但这种方式的主要问题是 QEMU 的性能比较差。一个比较好的消息是国外的 Eltechs 公司推出的 Exgear Desktop 软件宣称可以在 ARM Linux 上以接近 x86 原生的性能运行 x86 Linux 程序，综合性能是 QEMU 的 5 倍。这样对于我的三星 ARM Chromebook 来说可是相当有用的，因此考虑买一个授权（你没看错，<code>Exagear Desktop</code> 是收费软件，根据设备不同需要 20-30 美元）看看实际效果。</p>
<p>有关 <code>Exagear Desktop</code> 的介绍可以参考 Eltechs 的介绍页面：</p>
<p><a href="http://eltechs.com/product/exagear-desktop/" target="_blank">http://eltechs.com/product/exagear-desktop/</a></p>
<p>花了 30 美元购买 <code>Exagear Desktop</code> 之后 Eltechs 会将软件下载方式及授权文件以邮件方式发过来，通过 Google Drive 下载安装。</p>
<h2 id="install-exagear-desktop">安装 Exagear Desktop</h2>
<p>安装之前可以了解下 <code>Exagear Desktop</code> 的系统概念，运行 ARM Linux 的主机系统被称为 <code>host system</code>，需要运行的 x86 系统被称为 <code>guest system</code>，首先需要先确认所使用的 ARM 设备是否满足要求：</p>
<ul>
<li>ARMv6 或 ARMv7 CPU；</li>
<li>512MB 或更多的内存；</li>
<li>Ubuntu 12.04 14.04 或者 Debian 之类的系统</li>
</ul>
<p>上面的几个要求对于 ARM Chromebook 没有压力了，如果想省事可以直接使用 Crouton 安装 Ubuntu 系统使用。这里我使用 XUbuntu 14.04 armhf 系统测试 <code>Exagear Desktop</code> 的效果。</p>
<p>解压缩 <code>Exagear Desktop</code> 的安装包，可以看到类似这些文件：</p>
<pre class="brush: bash; title: ; notranslate">
chronos@localhost ~ $ ls exagear/
eltechs_exagear_desktop_1.1_guide.pdf  exagear-guest-debian-7-wine2g_3_all.deb  exagear-mem2g_2254-1_armhf.deb
exagear_2254-1_armhf.deb               exagear-guest-ubuntu-1204lts_9_all.deb   install-exagear.sh
exagear-guest-debian-7_3_all.deb       exagear-guest-ubuntu-1404lts_1_all.deb   README
</pre>
<p><code>Exagear Desktop</code> 提供了 Debian 7、Ubuntu 12.04、Ubuntu 14.04 等几种不同的 x86 系统，一般按照 user guide PDF 文件的介绍运行 <code>install-exagear.sh</code> 脚本就可以自动完成安装，中间会提示你安装哪种类型的 x86 guest 系统，选择之后会自动通过网络加载安装 x86 的应用包。</p>
<p>安装完成之后运行 <code>exagear-ls</code> 命令可以查看已经安装的客户机系统，直接运行 <code>exagear</code> 命令就可以进入 x86 客户系统，进行 x86 环境之后可以直接运行或安装 x86 的应用程序。</p>
<h2 id="about-binfmtmisc">关于 binfmt_misc</h2>
<p>Eltechs 建议为了达到无缝运行 x86 程序的效果（特别是能更好的支持运行 需要 SUID 或者 SGID 的 x86 程序），ARM Linux host 系统里最好能支持 <code>binfmt_misc</code>。</p>
<p>不过 Chromebook 上的 Linux kernel 一般没有自带这个，需要自己编译，可以参考我之前写的文章 <a href="https://zohead.com/archives/koding-chromebook/" target="_blank">在Koding云平台上编译Chromebook kernel</a> 自己编译 Chromebook 下的 <code>binfmt_misc</code> 模块。</p>
<p>另外由于 <code>binfmt_misc</code> 没有默认在 Chromebook kernel 中，这样即使加载手工 <code>binfmt_misc</code> 模块之后也是没有 <code>/proc/sys/fs/binfmt_misc</code> 目录的，你需要在 Crouton 等 ARM Linux host 系统中创建 <code>/var/binfmt_misc</code> 目录，这样 <code>Exagear Desktop</code> 服务在启动时才可以自动挂载并启用 <code>binfmt_misc</code> 支持（具体可以参考 <code>/etc/init.d/exagear</code> 服务脚本）。</p>
<p>另外我在 <code>/etc/init.d/exagear</code> 服务脚本里加了一条自动加载 <code>binfmt_misc</code> 模块的处理（Chromebook 的 Crouton 上仍然需要自行编译并安装到系统模块目录中）：</p>
<pre class="brush: bash; title: ; notranslate">
[ -d /sys/module/binfmt_misc ] || modprobe binfmt_misc
</pre>
<h2 id="sum-up">总结</h2>
<p>最后从我最近简单的测试情况来看，<code>Exagear Desktop</code> 对于 x86 程序的兼容性做的还是不错的，平常用的 Sublime Text、Skype 之类的软件可以正常运行，TeamViewer 用起来似乎也无碍，虽然我最想用的 Visual Studio Code 还是运行不了有点遗憾。实际 x86 程序的运行速度也是比较接近 ARM 程序的体验呢。</p>
<p>最后放张 Sublime Text 在我的三星 ARM Chromebook 上的运行效果：</p>
<div style="width: 716px" class="wp-caption alignnone"><a href="http://res.cloudinary.com/digwht2y0/image/upload/v1737371060/exagear-sublime.png" target="_blank"><img alt="Sublime Text on ARM Chromebook" src="http://res.cloudinary.com/digwht2y0/image/upload/v1737371060/exagear-sublime.png" width="706" height="507" /></a><p class="wp-caption-text">Sublime Text on ARM Chromebook</p></div>
<p>祝各位玩的开心～～～</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/exagear-chromebook/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Chromebook上使用KeePass的几种姿势</title>
		<link>https://zohead.com/archives/keepass-chromebook/</link>
		<comments>https://zohead.com/archives/keepass-chromebook/#comments</comments>
		<pubDate>Sat, 01 Aug 2015 17:06:16 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[Chrome]]></category>
		<category><![CDATA[工具]]></category>
		<category><![CDATA[ARC]]></category>
		<category><![CDATA[BrowsePass]]></category>
		<category><![CDATA[Chrome OS]]></category>
		<category><![CDATA[Chromebook]]></category>
		<category><![CDATA[Crouton]]></category>
		<category><![CDATA[KeePass]]></category>
		<category><![CDATA[keepass2]]></category>
		<category><![CDATA[KeePassDroid]]></category>
		<category><![CDATA[LastPass]]></category>
		<category><![CDATA[密码管理]]></category>

		<guid isPermaLink="false">http://zohead.com/?p=1016</guid>
		<description><![CDATA[KeePass 是一个开源的轻量级密码管理器，只需要记住一个 KeePass 主密码就可以用来管理所有其它各种网站或者服务密码，相对于 LastPass 这种在线同步的密码管理器最大的好处就是 KeePass 的密码数据库是完全由用户自己来掌控的，不用担心像 LastPass 被攻击泄漏密码之类的问题（今年就出现过一次哦）。 KeePass 目前相对也有个劣势就是浏览器插件功能不强，基本都需要配合 KeePass 客户端软件使用，好在 KeePass 也支持 Windows、Mac OS X、Linux、Android、iOS 等各种操作系统，可惜目前在 Chromebook 这种不能直接运行 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>KeePass 是一个开源的轻量级密码管理器，只需要记住一个 KeePass 主密码就可以用来管理所有其它各种网站或者服务密码，相对于 LastPass 这种在线同步的密码管理器最大的好处就是 KeePass 的密码数据库是完全由用户自己来掌控的，不用担心像 LastPass 被攻击泄漏密码之类的问题（今年就出现过一次哦）。</p>
<p>KeePass 目前相对也有个劣势就是浏览器插件功能不强，基本都需要配合 KeePass 客户端软件使用，好在 KeePass 也支持 Windows、Mac OS X、Linux、Android、iOS 等各种操作系统，可惜目前在 Chromebook 这种不能直接运行客户端软件的系统上使用时会有一些障碍。LastPass 由于是通过 Chrome 浏览器扩展直接在线同步的没有这个问题，而你如果是 Chromebook 和 KeePass 的重度用户，那还是相当不便的。</p>
<p>有关 KeePass 的详细介绍和原理请参考其官方网站：<a href="http://keepass.info/" target="_blank">http://keepass.info/</a>。</p>
<p>经过初步研究，这里我列出几种在 Chromebook 上使用 KeePass 的方法供读者参考：</p>
<ul>
<li><strong>Crouton + keepass2 + chromeIPass：</strong></li>
</ul>
<p>这个方法可能暂时只适用于使用 x86 处理器的 Chromebook，Chromebook 上可以使用 Crouton 安装基本完整的 Linux 系统，安装完成之后可以直接在 Linux 系统中安装 keepass2 软件包（比较新的 Linux 系统软件源中一般会自带这个的），并从 KeePass 官网下载启用 KeePassHttp 插件，这样就可以在 Chrome OS 系统里安装 chromeIPass 扩展愉快的使用 KeePass 密码数据库了。</p>
<p>这里就不详细介绍 keepass2 软件如何安装，chromeIPass 扩展如何使用之类的了。无奈由于目前 armhf 版本的 Linux 系统自带的 mono （KeePass 图形程序依赖开源的 mono .NET 开发环境）版本的问题，armhf 下的 keepass2 可以安装但无法正常运行。</p>
<p>笔者在目前使用的三星 ARM Chromebook 安装的 Ubuntu 14.04 版本上就无法正常运行，将 Crouton Linux 系统升级到最新的 Ubuntu 15.04 或者 15.10 等系统（自带的 mono 环境已经升级）有可能能正常运行，这里没有继续尝试了。</p>
<ul>
<li><strong>CKP Chrome 扩展程序：</strong></li>
</ul>
<p><a href="https://chrome.google.com/webstore/detail/ckp-keepass-integration-f/lnfepbjehgokldcaljagbmchhnaaogpc" target="_blank">CKP</a> （KeePass integration for Chrome）是 Chrome 应用商店里的一款 KeePass 嵌入式扩展程序，安装之后导入 KeePass 数据库就可以实现访问网站时自动填入用户名和密码，可惜就是 CKP 只能以只读方式使用 KeePass 密码数据库，如果数据库文件变化了只能重新导入（Chromebook 上还没有太好的办法能直接修改密码数据库文件）。</p>
<p>CKP 同时功能上也存在限制：无法完整浏览密码数据库里的全部条目，如果某个服务密码存在密码数据库里但不能直接通过 Chrome 浏览器访问这样就没法取出密码了。</p>
<ul>
<li><strong>BrowsePass Chrome 应用：</strong></li>
</ul>
<p><a href="https://chrome.google.com/webstore/detail/browsepass/pihdapfeofbodahcblfmeckjnfcigakb" target="_blank">BrowsePass</a> 则是另一款独立的 Chrome Packaged App，因此不能实现根据当前浏览的网页自动填写用户名和密码的功能，这个 App 目前对密码数据库文件支持文件好，可以完整浏览全部目录和条目，可以复制密码到相应的网页，但是仍然还有一个主要问题：BrowsePass 目前也只支持只读方式打开密码数据库，作者说后续可能会增加写数据库支持，但不保证什么时候能加入的。</p>
<ul>
<li><strong>Chrome ARC + KeePassDroid：</strong></li>
</ul>
<p>这个是目前我正在使用的方法，主要这种方式完全支持对密码数据库的各种写入操作，不需要另外运行一个 Crouton Linux 系统，而且这也是比较通用的方法哦，不只是能在 Chromebook 下使用，其实也可以直接在 Windows、Linux 等其它安装了普通 Chrome 浏览器的系统下使用。</p>
<p>Chrome 现在支持通过 ARC（App Runtime for Chrome） 直接运行 Android 程序，虽然目前兼容性还不是特别好，但 KeePassDroid 这种没有使用 NDK 代码的简单 Android 应用还是完全支持的。</p>
<p>首先安装 <a href="https://chrome.google.com/webstore/detail/arc-welder/emfinbmielocnlhgmfkkmkngdoccbadn" target="_blank">ARC Welder</a> Chrome 应用，安装完成之后会自动安装其依赖的 App Runtime for Chrome 运行环境，然后从网上下载 KeePassDroid 的安装 apk 文件，打开 ARC Welder 应用加载对应的 apk 文件将其转换为 Chrome 应用，不过需要注意的是转换的时候必须启用剪贴板访问权限，而且记得增加这个参数：</p>
<p><strong>{"enableExternalDirectory": true}</strong></p>
<p>启用外部 SD 卡目录访问权限，这样转换出来的 KeePassDroid Chrome 应用才可以正常打开 KeePass 密码数据库文件，具体如下图所示：</p>
<div style="width: 368px" class="wp-caption alignnone"><a href="http://res.cloudinary.com/digwht2y0/image/upload/v1737369840/arcwelder-keepassdroid.png" target="_blank"><img alt="ARC Welder转换KeePassDroid" src="http://res.cloudinary.com/digwht2y0/image/upload/v1737369840/arcwelder-keepassdroid.png" width="358" height="672" /></a><p class="wp-caption-text">ARC Welder 转换 KeePassDroid</p></div>
<p>然后点击 Download ZIP 按钮保存成 zip 文件，并将 zip 文件解压缩并在扩展程序界面加载为 Chrome 应用。</p>
<p>第一次启动 KeePassDroid 应用时 Chrome OS 系统会提示你选择一个 SD 卡目录，选择之后会让你选择密码数据库文件路径，只要把你的 KeePass 数据库文件放到对应的路径打开即可，例如我使用的路径就是这样：/storage/sdcard/Download/zzm.kdbx。</p>
<p>选择密码数据库文件之后输入你的数据库主密码，KeePassDroid 就会列出数据库里的所有目录和条目，进入一个任何条目，KeePassDroid 会自动弹出通知消息提示你复制用户名和密码，这样就可以正常在各类网站上使用 KeePass 密码咯。</p>
<p><strong>后记：</strong></p>
<p>目前 GitHub 上的 Pascal Mathis 开发了一款基于 Node.js 的 KeePass 库：<a href="https://github.com/NeoXiD/keepass.io" target="_blank">keepass.io</a>，这个 Node.js 库实现了完整的密码数据库读取和写入功能，在和开发者简单沟通之后，有想法在后面有空时基于 keepass.io 将其完整功能改为通过 Chrome Filesystem 等 API 实现从而不依赖 Node.js，这样能以单独 Chrome App 的形式使用 KeePass 密码数据库。只是在发现 KeePassDroid 能正常使用的情况，这个就当作后面有空时的一个念想再说咯～～～ 祝各位玩的开心。 ^_^</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/keepass-chromebook/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
