<?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; Chromebook</title>
	<atom:link href="https://zohead.com/archives/tag/chromebook/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>新玩具 Acer Chromebook 14</title>
		<link>https://zohead.com/archives/acer-chromebook-14/</link>
		<comments>https://zohead.com/archives/acer-chromebook-14/#comments</comments>
		<pubDate>Thu, 29 Mar 2018 15:39:49 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[数码]]></category>
		<category><![CDATA[电脑]]></category>
		<category><![CDATA[Acer]]></category>
		<category><![CDATA[Chrome OS]]></category>
		<category><![CDATA[Chromebook]]></category>

		<guid isPermaLink="false">https://zohead.com/?p=1527</guid>
		<description><![CDATA[Acer Chromebook 14 这两年非工作场合下我的主力电脑已经切换到 Chromebook，一直用的是 Dell Chromebook 11 这款小屏幕的笔记本，习惯了 Linux 之后 Chrome OS 用起来还是比较舒心的。 只是当我发现 Google 新推出的 Android Apps on Chrome OS 不再支持 Dell Chromebook 11 之类的老设备时（基本上所有使用赛扬 2955U 处理器的 Chromebook 都被排除了，具体可以参考 Chrome OS Systems Supporting Android Apps），虽然觉得有点不爽，但还是下定 [&#8230;]]]></description>
				<content:encoded><![CDATA[<h2 id="acer-chromebook-14">Acer Chromebook 14</h2>
<p>这两年非工作场合下我的主力电脑已经切换到 Chromebook，一直用的是 Dell Chromebook 11 这款小屏幕的笔记本，习惯了 Linux 之后 Chrome OS 用起来还是比较舒心的。</p>
<p>只是当我发现 Google 新推出的 Android Apps on Chrome OS 不再支持 Dell Chromebook 11 之类的老设备时（基本上所有使用赛扬 2955U 处理器的 Chromebook 都被排除了，具体可以参考 <a href="https://www.chromium.org/chromium-os/chrome-os-systems-supporting-android-apps" target="_blank">Chrome OS Systems Supporting Android Apps</a>），虽然觉得有点不爽，但还是下定决心准备换新的 Chromebook 设备了。</p>
<p>刚好最近看到一款之前关注过的 Acer Chromebook 14 笔记本，确认在 Play 商店支持的设备列表中就有了兴趣了，配置虽然和老的 Dell Chromebook 11 看起来差不了多少，但主要机身也更轻薄了，屏幕也升级到 1080p 了，立马准备拿下。</p>
<h2 id="specification">基本配置</h2>
<p>简单列一下配置：</p>
<table>
<thead>
<tr>
<th>项目</th>
<th>内容</th>
</tr>
</thead>
<tbody>
<tr>
<td>型号</td>
<td>CB3-431-C0AK</td>
</tr>
<tr>
<td>CPU</td>
<td>Intel® Celeron® N3160 1.6 GHz</td>
</tr>
<tr>
<td>内存</td>
<td>LPDDR3 4GB</td>
</tr>
<tr>
<td>存储</td>
<td>32GB eMMC 闪存</td>
</tr>
<tr>
<td>屏幕</td>
<td>14 寸 IPS 1920x1080</td>
</tr>
<tr>
<td>核显</td>
<td>Intel® HD Graphics 400</td>
</tr>
<tr>
<td>无线</td>
<td>802.11a/b/g/n/ac</td>
</tr>
<tr>
<td>接口</td>
<td>2x USB 3.0、HDMI</td>
</tr>
</tbody>
</table>
<p>其实除了 eMMC 闪存速度一般之外，其它方面我还是比较满意的，由于内存和闪存都是焊在主板上的，也基本没有升级的可能了，当然如果能像 Dell Chromebook 11 一样能自带读卡器就更好了。</p>
<h2 id="appearance">外观</h2>
<p>先看看 Acer Chromebook 14 的正面和背面：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737370636/cb3-431-a.jpg" alt="Acer Chromebook 14 正面"></p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737370637/cb3-431-d.jpg" alt="Acer Chromebook 14 背面"></p>
<p>这款 Chromebook 直接没有风扇，全金属的机身设计的很轻薄，两面都异常简单。</p>
<p>再看看打开后的 B 面和 C 面：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737370637/cb3-431-bc.jpg" alt="Acer Chromebook 14 B 面和 C 面"></p>
<p>支持多点触控的触控板占了 C 面很大的面积，由于 Chromebook 对于多点触控现在支持的也非常好了，我用 Chromebook 时基本都不用鼠标了，键盘相比原来的 Dell Chromebook 11 手感也更好了：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737370647/cb3-431-touchpad.jpg" alt="Acer Chromebook 14 触控板和键盘"></p>
<p>充电孔和耳机插孔都在机身右侧，该 Chromebook 的所有接口都在机身左侧，下面的图也可以看看键盘效果：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737370637/cb3-431-ports.jpg" alt="Acer Chromebook 14 接口"></p>
<h2 id="comments">使用体验</h2>
<p>Acer Chromebook 14 拿上手开机之后还是感觉比原来的 Dell Chromebook 11 屏幕改进挺明显的，老一批 Chromebook 备受诟病的屏幕可视角度问题在这里就基本没有了，只是我发现 1080p 的屏幕默认选择的“最优”分辨率是 1536x864。</p>
<p>我把分辨率改为 1920x1080 的话 Chrome OS 的显示体验就比较差了，网页字体、标题栏、工具栏都显得特别小；这种情况下只能将缩放调至 125% 或者 150%，不过即使这样也只是网页显示正常了，标题栏和工具栏并没有跟进缩放。这样的显示效果甚至还不及 Windows 10 高分屏设备上的 Chrome 浏览器，鉴于 Chrome OS 对高分屏的支持也比较天残，我也只能保持默认“最优”分辨率了。</p>
<p>Chrome OS 必备的爬墙激活这里就不说了，激活成功之后一般就可以领取 90 天的 Play Music 和两年 100 GB 的 Google Drive 空间了。无意外的话连上网络就会有系统更新了，更新到最新的 Chrome OS 64 稳定版本，系统就已经自带新的 Play 商店支持了。</p>
<p>在设置中开启 Play 商店之后，如果你的梯子没什么问题的话应该就可以打开 Play 商店安装常用的 App 了，Chrome OS 自带的 Android 容器为 7.1.1 版本，相比原来的 Chrome ARC 运行时来说 App 的兼容性还是有质的提升的。</p>
<p>我专门测试了网易云音乐、手机 QQ 等几个原来 Chrome ARC 无法运行的 App，在新的 Android 容器中运行都没有什么问题，起码 Chromebook 上使用 QQ 除了 crouton 中运行 Wine QQ 之外终于有直接的解决方案了。</p>
<p>按照我平常基本用 Chromebook 浏览网页，偶尔看点 HTML5 视频的使用场景，这款笔记本还是基本能达到标称的 12 小时续航时间的，这也是 Chrome OS 相对 Windows 等系统的一大优势了。</p>
<p>Acer Chromebook 14 这一段时间的总体使用体验还是比较令人满意的，碰到一个未解决的小问题就是原来通过 crouton 安装的 Ubuntu 14.04 系统无法以 xorg 方式正常启动图形界面了，只能以 <a href="https://github.com/dnschneid/crouton/wiki/crouton-in-a-Chromium-OS-window-(xiwi)" target="_blank">xiwi</a> 窗口形式启动图形界面，更新 crouton 也没有解决，不过还好这个影响不是很大咯。</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/acer-chromebook-14/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<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>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>Linux下USB 3.0移动硬盘读写错误问题分析</title>
		<link>https://zohead.com/archives/linux-usbhdd-err/</link>
		<comments>https://zohead.com/archives/linux-usbhdd-err/#comments</comments>
		<pubDate>Tue, 08 Mar 2016 19:09:23 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[kernel]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[barrier]]></category>
		<category><![CDATA[Chromebook]]></category>
		<category><![CDATA[ext4]]></category>
		<category><![CDATA[FUA]]></category>
		<category><![CDATA[JMicron]]></category>
		<category><![CDATA[journal]]></category>
		<category><![CDATA[SCSI]]></category>
		<category><![CDATA[USB]]></category>
		<category><![CDATA[移动硬盘]]></category>

		<guid isPermaLink="false">https://zohead.com/?p=1188</guid>
		<description><![CDATA[为了解决 Chromebook 上自带 SSD 空间不足的问题，之前我在淘宝上购入了一个绿帆 F200 USB 3.0 移动硬盘盒，该硬盘盒使用的是 JMicron JMS567 这款使用还比较广泛的 SATA 6.0Gbps to USB 3.0 桥接芯片，准备配上 N 年前的神船笔记本淘汰下来的 2.5 寸硬盘给 Chromebook 使用，这样我就可以在 Chromebook 上安装的 Crouton Ubuntu 系统里无碍的使用各种编译开发环境了。 移动硬盘问题说明 首先我在宏碁 W700 Windows 10 平板上接上此移动硬盘建了一个 NTFS 分区并做各种读写拷贝大文件之类的 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>为了解决 Chromebook 上自带 SSD 空间不足的问题，之前我在淘宝上购入了一个绿帆 F200 USB 3.0 移动硬盘盒，该硬盘盒使用的是 JMicron JMS567 这款使用还比较广泛的 SATA 6.0Gbps to USB 3.0 桥接芯片，准备配上 N 年前的神船笔记本淘汰下来的 2.5 寸硬盘给 Chromebook 使用，这样我就可以在 Chromebook 上安装的 Crouton Ubuntu 系统里无碍的使用各种编译开发环境了。</p>
<h2 id="移动硬盘问题说明">移动硬盘问题说明</h2>
<p>首先我在宏碁 W700 Windows 10 平板上接上此移动硬盘建了一个 NTFS 分区并做各种读写拷贝大文件之类的测试没有任何问题；但是我把移动硬盘换到 Chromebook 上之后发现移动硬盘上新建的 ext4 分区读写会报错，无法做任何拷贝文件操作，先看看 Linux kernel 看到的 USB 3.0 移动硬盘的信息：</p>
<pre class="brush: bash; title: ; notranslate">
[ 9934.612465] usb 2-1: new SuperSpeed USB device number 2 using xhci_hcd
[ 9934.624741] usb 2-1: New USB device found, idVendor=152d, idProduct=0567
[ 9934.624768] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 9934.624787] usb 2-1: Product: lvfan USB3.0 storage
[ 9934.624802] usb 2-1: Manufacturer: JMicron
[ 9934.624817] usb 2-1: SerialNumber: 3224043AA81395
[ 9934.626473] scsi2 : usb-storage 2-1:1.0
[ 9935.627536] scsi 2:0:0:0: Direct-Access     lvfan                     0117 PQ: 0 ANSI: 6
[ 9935.629174] sd 2:0:0:0: [sdb] Spinning up disk...
[ 9936.629940] ...ready
[ 9938.634171] sd 2:0:0:0: [sdb] 312581808 512-byte logical blocks: (160 GB/149 GiB)
[ 9938.634552] sd 2:0:0:0: [sdb] Write Protect is off
[ 9938.634580] sd 2:0:0:0: [sdb] Mode Sense: 47 00 10 08
[ 9938.634955] sd 2:0:0:0: [sdb] Write cache: enabled, read cache: enabled, supports DPO and FUA
[ 9938.659685]  sdb: sdb1 sdb2
[ 9938.661548] sd 2:0:0:0: [sdb] Attached SCSI disk
</pre>
<p>这个是拷贝文件出错时候的内核日志：</p>
<pre class="brush: bash; title: ; notranslate">
[ 9910.412002] EXT4-fs (sdb2): mounted filesystem with ordered data mode. Opts: (null)
[ 9918.500515] sd 2:0:0:0: [sdb] Invalid command failure
[ 9918.500530] sd 2:0:0:0: [sdb]  
[ 9918.500537] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
[ 9918.500547] sd 2:0:0:0: [sdb]  
[ 9918.500554] Sense Key : Illegal Request [current] 
[ 9918.500570] sd 2:0:0:0: [sdb]  
[ 9918.500577] Add. Sense: Invalid field in cdb
[ 9918.500589] sd 2:0:0:0: [sdb] CDB: 
[ 9918.500596] Write(10): 2a 08 04 58 18 30 00 00 08 00
[ 9918.500641] end_request: critical target error, dev sdb, sector 72882224
[ 9918.500654] end_request: critical target error, dev sdb, sector 72882224
[ 9918.500695] Aborting journal on device sdb2-8.
[ 9922.109415] EXT4-fs error (device sdb2): ext4_journal_start_sb:349: Detected aborted journal
[ 9922.109439] EXT4-fs (sdb2): Remounting filesystem read-only
</pre>
<p>看起来是报某个扇区写操作出错，那么我先在 Chromebook 上用 dd 命令直接写对应报错的扇区：</p>
<pre class="brush: bash; title: ; notranslate">
chronos@localhost ~ $ sudo dd if=/dev/zero of=/dev/sdb bs=512 count=10 seek=72882224
10+0 records in
10+0 records out
5120 bytes (5.1 kB) copied, 0.0185829 s, 276 kB/s
</pre>
<p>可以看到写之前报错的扇区其实是没有问题的，而且我使用的 SATA 笔记本硬盘之前经过 mhdd 扫描测试没有发现坏道之类的。</p>
<p>无奈我删掉这个 ext4 分区，重新创建了 ext3 分区并格式化拷贝文件但还是存在类似的错误，最后更换为 ext2 或者 FAT32 文件系统才能正常写入文件，这个就非常奇怪了，接着我把移动硬盘换到 Remix OS PC 版 4.0.9 kernel 下挂载 ext4 读写还是有一样的问题，这样我们就必须要具体分析上面的报错信息了。</p>
<h2 id="读写错误问题分析">读写错误问题分析</h2>
<p>从上面的 kernel 日志中可以看到报错的 SCSI CDB 是：<code>2a 08 04 58 18 30 00 00 08 00</code>，而 0x2A 是 SCSI WRITE 10 命令，参考 SCSI 协议可以知道其命令格式为：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737442940/scsi-rw-cmd.jpg" alt="SCSI WRITE 10命令" title="SCSI WRITE 10命令"></p>
<p>我们可以从上图知道 <code>04 58 18 30</code> 是写操作的实际扇区地址（也就是上面报错的 72882224 扇区），<code>08</code> 是写命令的标志位表示这个写命令启用了 <code>FUA</code>。</p>
<p>这里我对 <code>FUA</code>（Force Unit Access）做个简单的介绍：</p>
<ul>
<li>
<p>由于在 Linux 操作系统中从上层到下层多个地方都存在着缓存：page cache（vfs cache）-&gt; HBA/RAID卡自带的 cache -&gt; 磁盘自身的缓存，这样文件系统在写日志等关键的操作时就需要保证写入的数据被真实写到磁盘等物理介质中，而不是存留在各层 cache 里，这样可以防止系统掉电等情况导致数据不一致。</p>
</li>
<li>
<p>Linux kernel 中比较新的文件系统像 ext4、xfs、reiserfs 等则引入了 barrier 特性，遇到带 barrier 标志的写请求（或者 fsync 刷新请求）的时候必须保证之前的所有请求都已经写入到物理介质才能继续。老的 SCSI 或 SAS 磁盘支持通过 <code>SYNCHRONIZE CACHE</code> 命令刷新缓存数据，只不过这样会有额外的影响；新的 kernel 中对于支持 <code>FUA</code> 的设备则是通过发送带 <code>FUA</code> 标志的写请求来实现。</p>
</li>
<li>
<p>SCSI CDB 中的 <code>FUA</code> 标志位如果被置上则表示该请求必须通过访问物理介质实现，如果是带 <code>FUA</code> 的写命令就表示写到物理介质命令才算完成，带 <code>FUA</code> 的读命令则表示直接从物理介质读取绕过缓存。</p>
</li>
</ul>
<p>这样分析下来基本就可以推断出原因了：</p>
<p>由于 ext4、ext3 等文件系统在 kernel 中是默认启用和日志（journal）和 barrier 的，拷贝文件时需要更新文件系统日志，从最上面 kernel 报上来的移动硬盘信息显示是支持 <code>FUA</code> 的，如此日志的写入就是通过发送带 <code>FUA</code> 的写命令实现，然而我的 USB 3.0 移动硬盘响应带 <code>FUA</code> 标志的写命令出现问题导致 ext4、ext3 文件系统变为只读状态无法写入；而 ext2 和 FAT32 文件系统则是完全不带日志的，这样拷贝文件反而就没有问题。</p>
<blockquote>
<p><strong>提示</strong></p>
<p>有关我的移动硬盘使用的 JMicron JMS567 桥接芯片的详细信息请参考 <a href="http://www.jmicron.com/PDF/brief/jms567.pdf">JMicron 技术文档</a>。</p>
</blockquote>
<h2 id="解决方案">解决方案</h2>
<p>如果要顺利使用 ext4 分区，解决方案也有几种，一般的用户建议参考第二种解决方案，下面简单说明下：</p>
<h3 id="禁用-ext4-文件系统日志">禁用 ext4 文件系统日志</h3>
<p>这是比较简单粗暴的解决方案，ext4 文件系统相对 ext3 其中一个改进就是可以手工关闭日志，先卸载已挂载的 ext4 文件系统，然后运行下面的命令：</p>
<pre class="brush: bash; title: ; notranslate">
sudo tune2fs -O ^has_journal /dev/sdb2
</pre>
<p>这样就可以直接关闭 ext4 文件系统默认启用的日志功能，日志被禁用之后基本就类似 ext2 不需要专门发送带 <code>FUA</code> 的写请求了；当然这里我不建议这样做，因为日志功能对于移动硬盘这种热插拔频繁的设备还是相当有用的，可以减少文件出错或丢失的可能。</p>
<h3 id="关闭-ext4-文件系统-barrier">关闭 ext4 文件系统 barrier</h3>
<p>对于不愿意修改或者编译 Linux kernel 的用户这是比较好的解决方案咯，只是关闭 ext4 文件系统 barrier 特性可以保留最有用的日志功能，虽然相比默认启用 barrier 的情况仍然会有一点导致数据不一致的可能，但好处是修改之后就算把移动硬盘接到其它 Linux 机器上基本也能起作用，这样就比较划算了，具体运行下面的命令：</p>
<pre class="brush: bash; title: ; notranslate">
sudo tune2fs -o nobarrier /dev/sdb2
</pre>
<p>然后重新挂载 ext4 分区，一般的 Linux 系统都会在挂载该文件系统时自动禁用 barrier，Chromebook 上自带文件管理器的自动挂载磁盘功能实测有效。</p>
<h3 id="修改-kernel-禁用移动硬盘-fua">修改 kernel 禁用移动硬盘 FUA</h3>
<p>这种解决方案比较适合对编译 kernel 比较熟悉而且相对追求完美（^_^）的用户，不过相对的是需要依赖使用的 Linux 主机 kernel。</p>
<p>由于只禁用 ext4 文件系统的 barrier 还不能完全保证不会有什么别的地方需要用到带 <code>FUA</code> 的读写命令，如果能够修改 kernel 直接让我的这款移动硬盘设备报到系统中时就显示为不支持 <code>FUA</code>，这样就算遇到例如使用 barrier 等场合也可以通过 <code>SYNCHRONIZE CACHE</code> 命令来解决。</p>
<p>Linux kernel USB mass storage 驱动中内置了一个 unusual USB 设备列表，里面包含各种用户已经发现的有问题的 USB 设备及对应处理标志，该列表由 kernel 源代码中的 <code>drivers/usb/storage/unusual_devs.h</code> 文件负责维护。</p>
<p>我们可以先检查下 Chromebook 当前使用的 3.8.11 版本内核和 Remix OS PC 版使用的 4.0.9 版本内核源代码，却都能看到已经有用户报告的我的移动硬盘使用的 JMicron JMS567 芯片的 <code>FUA</code> 问题了：</p>
<pre class="brush: cpp; title: drivers/usb/storage/unusual_devs.h; notranslate">
UNUSUAL_DEV(  0x152d, 0x0567, 0x0114, 0x0114,
		&quot;JMicron&quot;,
		&quot;USB to ATA/ATAPI Bridge&quot;,
		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
		US_FL_BROKEN_FUA ),
</pre>
<p>这个稍微有点奇怪，kernel 碰到带 <code>US_FL_BROKEN_FUA</code> 标志的 USB 设备会自动禁用 <code>FUA</code>，按说报上来的移动硬盘设备应该显示为不支持 <code>FUA</code> 的；不过稍微看下就发现上面的 <code>UNUSUAL_DEV</code> 条目限制了有问题的 USB 设备的 BCD 码固定为 <code>0x0114</code>，我们可以通过 <code>lsusb -v</code> 命令确认下移动硬盘设备的详细 USB 信息：</p>
<pre class="brush: bash; title: ; notranslate">
Bus 002 Device 004: ID 152d:0567 JMicron Technology Corp. / JMicron USA Technology Corp. 
Couldn't open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               3.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0         9
  idVendor           0x152d JMicron Technology Corp. / JMicron USA Technology Corp.
  idProduct          0x0567 
  bcdDevice            1.17
</pre>
<p>可以看到移动硬盘的 USB 设备 BCD 码是 1.17 也就是 <code>0x0117</code>，这样 kernel 就不会认为我这款绿帆移动硬盘是有问题的 USB 设备进而做特殊处理了。</p>
<p>同样我们可以看看最新的 Linux 4.5-rc7 版本 kernel 中异常 USB 设备列表中的 JMS567 条目：</p>
<pre class="brush: cpp; title: drivers/usb/storage/unusual_devs.h; notranslate">
UNUSUAL_DEV(  0x152d, 0x0567, 0x0114, 0x0116,
		&quot;JMicron&quot;,
		&quot;USB to ATA/ATAPI Bridge&quot;,
		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
		US_FL_BROKEN_FUA ),
</pre>
<p>稍微有点无奈最新的 Linux kernel 中的 BCD 码范围是从 0x0114 到 0x0116，还是不包含我这款移动硬盘。</p>
<p>解决步骤也就比较简单了，检出对应的内核源代码，修改 <code>drivers/usb/storage/unusual_devs.h</code> 文件可以把 JMS567 USB 设备的 BCD 码范围改为 0x0114 到 0x0117，也可以彻底点直接改成 0x0000 到 0x9999。</p>
<p>unusual_devs.h 文件修改完成后替换 usb-storage 模块并重新启动，顺利的话就可以看到报上来的 SCSI 磁盘设备显示为：</p>
<pre class="brush: bash; title: ; notranslate">
[ 7205.597952] sd 2:0:0:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
</pre>
<blockquote>
<p><strong>提示</strong></p>
<p>由于 Chromebook 和 Remix OS 中的 usb-storage 驱动都是直接集成在 kernel 中的，无法只编译 usb-storage 模块进行简单替换，因此需要完整编译出 kernel bzImage 直接替换。</p>
</blockquote>
<p><br/>
<p>这样 ext4 文件系统的日志还有 barrier 特性就能愉快的继续使用了，祝各位玩的开心～～～。</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/linux-usbhdd-err/feed/</wfw:commentRss>
		<slash:comments>0</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>Chromebook使用ext4 U盘运行Remix OS</title>
		<link>https://zohead.com/archives/cb-ext4-remixos/</link>
		<comments>https://zohead.com/archives/cb-ext4-remixos/#comments</comments>
		<pubDate>Sun, 14 Feb 2016 18:55:23 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[Chromebook]]></category>
		<category><![CDATA[ext4]]></category>
		<category><![CDATA[EXTLINUX]]></category>
		<category><![CDATA[Grub]]></category>
		<category><![CDATA[Remix OS]]></category>
		<category><![CDATA[U盘]]></category>
		<category><![CDATA[VMware]]></category>
		<category><![CDATA[桌面]]></category>

		<guid isPermaLink="false">https://zohead.com/?p=1167</guid>
		<description><![CDATA[之前在 Dell Chromebook 11 上体验 Remix OS PC 版的时候是直接使用的普通 USB 3.0 U 盘安装官方放出的 Windows 可执行安装版，在 Chromebook 使用 legacy 模式启动（刷了 RW_LEGACY 模式的修改版 BIOS）运行倒是还比较顺利，只是 Remix OS PC 版 U 盘默认 FAT32 分区格式限制了 Android 的用户空间（data 分区）也最多只有 4GB，这样用起来还是挺不爽的。 搜索之后发现 Remix 论坛里已经有直接的硬盘安装方法可以解决 4GB 用户空间限制的问题，但是我的 Chromebook 就只有 16 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>之前在 Dell Chromebook 11 上体验 Remix OS PC 版的时候是直接使用的普通 USB 3.0 U 盘安装官方放出的 Windows 可执行安装版，在 Chromebook 使用 legacy 模式启动（刷了 RW_LEGACY 模式的修改版 BIOS）运行倒是还比较顺利，只是 Remix OS PC 版 U 盘默认 FAT32 分区格式限制了 Android 的用户空间（data 分区）也最多只有 4GB，这样用起来还是挺不爽的。</p>
<p>搜索之后发现 Remix 论坛里已经有直接的硬盘安装方法可以解决 4GB 用户空间限制的问题，但是我的 Chromebook 就只有 16GB 的空间，同时又安装了 crouton 系统，本来就捉襟见肘的空间再给 Remix OS 分一个区就不太现实了，最主要 Chromebook 原生的 Chrome OS 我是必须要保留的，而且 U 盘格式的 Android x86 也比较符合我的需求，因此想到用 Remix OS PC 版里自带的 Android x86 安装器将 Remix OS 安装到 ext4 格式的 U 盘里。</p>
<blockquote>
<p><strong>提示</strong> <br />
  本文中介绍的安装及启动、升级方法不只是适用于 Chromebook 电脑，也同样适用于普通 Windows PC 机； <br />
  另外这篇文章并不是面向初学者的安装教程之类的，需要你对 Linux 有一定的了解。</p>
</blockquote>
<p>下面介绍一下安装方法以及后续升级的步骤：</p>
<h2 id="准备步骤">准备步骤</h2>
<ul>
<li>一个 8GB 以上的 U 盘，最好是 USB 3.0 的；</li>
<li>下载好的 Remix OS PC 版最新<a href="http://www.jide.com/remixos-for-pc">安装映像</a>；</li>
<li>VMware / VirtualBox / QEMU 等支持 USB 模拟的虚拟机软件。</li>
</ul>
<h2 id="vmware-安装-remix-os-步骤">VMware 安装 Remix OS 步骤</h2>
<p>这里以 VMware Workstation 虚拟机软件为例子介绍如何在 Windows 上将 Remix OS PC 版映像以 ext4 文件系统格式安装到普通 U 盘上，其它的虚拟机软件或者操作系统下步骤也是类似的（直接使用 Chromebook 安装 VirtualBox 也是可以完成的哦）。</p>
<ol>
<li>解压缩下载到的 Remix OS PC 版安装映像（一般为 zip 文件），会得到一个比较大的 iso 文件；</li>
<li>创建新虚拟机，记得启用 USB 控制器支持（默认就会启用），然后添加虚拟光驱并使用解压缩出来的 iso 文件，另外不用添加任何虚拟硬盘；</li>
<li>启动虚拟机，正常的话会看到 Android x86 安装画面，这里选择默认的 <code>Resident mode</code> 并按 Tab 键会出现输入参数的界面，在原有的参数后面增加 <code>INSTALL=1</code>，如下图所示：
</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737442937/remixos-install.png" alt="Android x86 启动画面" title="Android x86 启动画面"> </p>
</li>
<li>按回车键启动安装程序，稍等就会出现选择安装分区界面：
</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737442936/remixos-detectdev.png" alt="选择安装分区" title="选择安装分区"> </p>
</li>
<li>对于 VMware 虚拟机这时候需要将焦点切换到虚拟机中并插上 U 盘，一切正常的话稍等片刻就可以在虚拟机状态栏上看到新插上的 USB 设备：
</p>
<blockquote>
<p><strong>说明</strong> <br />
  对于 VirtualBox 这样可以直接在虚拟机设置中添加 USB 设备的虚拟机软件会在虚拟机启动时自动尝试加载 USB 设备就不需要专门做这步了； <br />
  QEMU 也可以直接通过命令行或者配置文件加载 USB 设备； <br />
  VMware 也是可以通过 vmx 配置文件自动加载 USB 设备的，只是配置稍微复杂点这里不做介绍了。</p>
</blockquote>
<p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737442962/vmware-usb-dev.jpg" alt="VMware USB 设备" title="VMware USB 设备"> </p>
</li>
<li>找到 U 盘设备之后选择上面的 <code>Detect devices</code> 菜单项查找设备，顺利的话会看到要安装到的设备：
</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737442937/remixos-usb-dev.png" alt="安装 U 盘" title="安装 U 盘"> </p>
</li>
<li>上图可以看到 U 盘上还没有任何分区，下面可以选择 <code>Create/Modify partitions</code> 菜单在 U 盘上创建并格式化分区，分区文件系统格式最好为 ext4 格式，另外最好也直接将整个 U 盘的空间都用上：
</p>
<blockquote>
<p><strong>提示</strong> <br />
  如果 U 盘上已经存在分区但不是 ext4 格式的也可以在这里删除并重新创建分区。</p>
</blockquote>
<p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737442934/remixos-create-partition.png" alt="创建分区" title="创建分区"> </p>
</li>
<li>分区创建并格式化完成之后退出返回就可以在之前的选择分区界面中看到新创建的分区：
</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737442937/remixos-usb-partition.png" alt="使用新分区" title="使用新分区"> </p>
</li>
<li>选择新创建的分区开始安装，顺利的话稍等几分钟应该就可以安装完成，中间会提示是否需要将 system 分区设为可写的，为了调试以及后续 root 方便建议选择 Yes 将 system 分区设备可写模式。 </li>
<li>这样安装之后的 U 盘就可以一般的电脑上启动成功了，而且用户空间（data 分区）和系统空间（system 分区）都是 ext4 格式的，不存在 4GB 的大小限制，同时后续如果换更大的 U 盘也比较好扩容。</li>
</ol>
<p>安装好之后我们可以看看 Remix OS PC 版 U 盘的分区及文件系统结构：</p>
<pre class="brush: bash; title: ; notranslate">
[root@localhost ~]# parted /dev/sdb p
Model: SanDisk Cruzer Glide 3.0 (scsi)
Disk /dev/sdb: 16.0GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start   End     Size    File system  Name  标志
 1      1049kB  16.0GB  16.0GB  ext4

[root@localhost ~]# mount -t ext4 /dev/sdb1 /mnt/disk
[root@localhost ~]# ls /mnt/disk/
android-2016-01-23  grub  lost+found
[root@localhost ~]# ls /mnt/disk/android-2016-01-23/
data  initrd.img  kernel  ramdisk.img  system
[root@localhost ~]# ls /mnt/disk/android-2016-01-23/system/
addon  app  bin  build.prop  etc  fonts  framework  lib  lib64  lost+found  media  priv-app  priv-setting  tts  usr  vendor  xbin
[root@localhost ~]# ls /mnt/disk/android-2016-01-23/data/
adb  app-asec  app-private  dalvik-cache  dontpanic  local       media     misc      resource-cache  serialno  user
app  app-lib   bugreports   data          drm        lost+found  mediadrm  property  security        system
[root@localhost ~]# df -h /mnt/disk
文件系统              容量  已用  可用 已用%% 挂载点
/dev/sdb1              15G  1.7G   13G  12% /mnt/disk
</pre>
<p>可以看到 U 盘根目录下就是 android-2016-01-23 这样的目录，里面放的就是 Android kernel、initrd 文件以及实际的 data 及 system 目录，安装完成之后 U 盘实际占用了近 2GB 的空间。</p>
<h2 id="chromebook-u-盘启动问题">Chromebook U 盘启动问题</h2>
<p>下面将安装好的 U 盘在 Dell Chromebook 11 上用 legacy 模式启动时会出现无法正常启动的问题。经过初步研究认为是 Android x86 默认使用的 Trusted Grub 安全引导方式对于刷了 RW_LATENCY 模式 BIOS 的 Chromebook 可能存在不兼容的问题。</p>
<blockquote>
<p>刷了 RW_LATENCY 模式 BIOS 的 Chromebook 进入 legacy 模式的方法是在启动时按 <kbd>Ctrl+L</kbd> 键，并选择启动设备。</p>
</blockquote>
<p>为解决这个问题，我在安装好的 U 盘上尝试安装了 Grub、Grub2 等不同的引导程序发现都不能在 Dell Chromebook 11 上正常启动，最后发现如果改为使用 <a href="http://www.syslinux.org/wiki/index.php/EXTLINUX">EXTLINUX</a> 这个 Syslinux 变种不但能支持 ext4 格式分区引导而且支持在 Chromebook 上以 legacy 方式正常启动 Remix OS U 盘。</p>
<p>EXTLINUX 安装也比较简单，这里直接使用 Chromebook 中的 crouton 系统直接安装到 U 盘，下面的操作都需要使用 root 权限才能完成。</p>
<ul>
<li>首先挂载 U 盘分区，并在分区下创建 extlinux 目录，然后运行命令安装 EXTLINUX 相关文件到对应目录：
</p>
<pre class="brush: bash; title: ; notranslate">
[root@localhost ~]# mkdir -p /mnt/disk/extlinux
[root@localhost ~]# extlinux --install /mnt/disk/extlinux
</pre>
</li>
<li>生成 EXTLINUX 配置文件保存到 <code>extlinux/extlinux.conf</code> 中：
</p>
<pre class="brush: bash; title: ; notranslate">
TIMEOUT 5
DEFAULT Remix_OS_2016-01-23

LABEL Remix_OS_2016-01-23
	KERNEL /android-2016-01-23/kernel
	APPEND quiet root=/dev/ram0 androidboot.hardware=remix_cn_x86_64 androidboot.selinux=permissive DATA= SRC=/android-2016-01-23 initrd=/android-2016-01-23/initrd.img

LABEL Remix_OS_2016-01-23_Debug
	KERNEL /android-2016-01-23/kernel
	APPEND root=/dev/ram0 androidboot.hardware=remix_cn_x86_64 androidboot.selinux=permissive DATA= DEBUG=2 SRC=/android-2016-01-23 initrd=/android-2016-01-23/initrd.img
</pre>
<p>其中实际标题及目录名称请根据需要自行替换； </p>
</li>
<li>安装 EXTLINUX 引导程序到 U 盘：
</p>
<pre class="brush: bash; title: ; notranslate">
[root@localhost ~]# umount /mnt/disk
[root@localhost ~]# cat /usr/lib/extlinux/mbr.bin &gt; /dev/sdb
</pre>
<blockquote>
<p><strong>注意</strong> <br />
  进行此步骤还请特别注意不要搞错了 U 盘设备名，否则可能误安装到你的系统盘之类的哦。</p>
</blockquote>
</li>
</ul>
<p>一般这样修改之后的 U 盘就可以正常在 Chromebook 上以 legacy 模式启动了，这种方式最大的优点就是不影响 Chromebook 原生的 Chrome OS 系统。</p>
<h2 id="remix-os-系统升级">Remix OS 系统升级</h2>
<p>由于 Remix OS PC 版并没有提供直接的在线 OTA 升级方式，但按本文提供的方式安装的 U 盘明显又不能使用官方的 Windows 安装工具进行升级，这里就需要专门介绍一下如何升级新系统了。</p>
<p>其实步骤也算是比较简单的，只需要下载新的映像文件解压缩 iso 里的文件，并使用新的 kernel、ramdisk、initrd 替换到对应目录，然后替换整个 system 目录即可（保留 data 目录就可以保留所有用户数据）。</p>
<p>首先挂载 U 盘分区到指定目录，例如 <code>/mnt/disk</code>，上面已经有具体的命令这里不再说明了。</p>
<p>然后挂载 iso 中的 system 文件，这一步由于 Android x86 system 目录使用的是 squashfs 映像所以略微复杂点：</p>
<pre class="brush: bash; title: ; notranslate">
(trusty)zzm@localhost:~/Downloads$ sudo mount -t iso9660 -o ro,loop Remix_OS_for_PC_64_B2016020201_CN_Alpha_Legacy.iso /mnt/test
(trusty)zzm@localhost:~/Downloads$ ls /mnt/test/
efi/         initrd.img   install.img  isolinux/    kernel       ramdisk.img  system.sfs   TRANS.TBL
(trusty)zzm@localhost:~/Downloads$ sudo mount -t squashfs -o ro,loop /mnt/test/system.sfs /mnt/image
(trusty)zzm@localhost:~/Downloads$ ls /mnt/image/
system.img
(trusty)zzm@localhost:~/Downloads$ sudo mount -t ext4 -o ro,loop /mnt/image/system.img /mnt/share
(trusty)zzm@localhost:~/Downloads$ ls /mnt/share/
addon  app  bin  build.prop  etc  fonts  framework  lib  lib64  lost+found  media  priv-app  priv-setting  tts  usr  vendor  xbin
</pre>
<p>接着就是将新的 system 目录到 U 盘中（下面的命令开始多了一条删除 U 盘中原来所有 system 文件的操作）：</p>
<pre class="brush: bash; title: ; notranslate">
(trusty)zzm@localhost:~/Downloads$ sudo rm -rf /mnt/disk/android-2016-01-23/system/*
(trusty)zzm@localhost:~/Downloads$ cp -ra /mnt/share/* /mnt/disk/android-2016-01-23/system/
</pre>
<p>下面是替换 Android kernel、initrd、ramdisk 等文件：</p>
<pre class="brush: bash; title: ; notranslate">
(trusty)zzm@localhost:~/Downloads$ sudo cp /mnt/test/initrd.img /mnt/test/kernel /mnt/test/ramdisk.img /mnt/disk/android-2016-01-23/
</pre>
<p>最后可以将原来的 Android 目录（例如上面的 android-2016-01-23）也重命名为最新的目录（例如：android-2016-02-02），不过重命名之后千万别忘了把 extlinux.conf 配置文件里的标题和目录名称也改掉哦。</p>
<p>依次卸载上面的一些挂载之后用新的 U 盘启动 Chromebook 就可以看到升级后的效果啦。</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/cb-ext4-remixos/feed/</wfw:commentRss>
		<slash:comments>0</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>
	</channel>
</rss>
