tag:blogger.com,1999:blog-13048820584684036252023-11-15T06:43:20.447-08:00Personal items of noteBrian Rzyckihttp://www.blogger.com/profile/05567239597443298839noreply@blogger.comBlogger2125tag:blogger.com,1999:blog-1304882058468403625.post-59760960610130357792015-04-14T14:38:00.000-07:002015-04-14T15:38:33.554-07:00Using a Chromebox as a low-cost VSTi playerThe Google Chromebox devices are great little computers: they're small, quiet, inexpensive, and run Linux as the basis of Chrome OS. I wondered if it were possible to use it as a portable Virtual Instrument player.
<br />
<br />
Turns out with a little know-how and patience the device works surprisingly well. Here are the high-level steps to to make one of your very own!<br />
<br />
<ol>
<li>Purchase an Intel-based Chromebox. I'm using the popular <a href="http://www.asus.com/us/ASUS_Chromebox/">Asus model</a>.</li>
<li>Install <a href="http://rogerstringer.com/2014/09/21/upgrade-asus-chromebox-ram-bigger-ssd-ubuntu">Ubuntu on Chrome OS (Chrubuntu)</a>.</li>
<li>Boot Ubuntu by default and bypass the developer mode 'CTRL-D' screen.</li>
<li>Configure Ubuntu: wireless networking, ssh, and the power button.</li>
<li>Setup priorities for audio and confgure the audio interface. I used the built-in 3.5mm headphone port.</li>
<li>Setup <a href="https://www.winehq.org/">Wine</a>.</li>
<li>Setup <a href="http://jackaudio.org/">jackd</a> and <a href="http://sourceforge.net/projects/fsthost/">fsthost</a>.</li>
<li>Setup a suitable VSTi. I used <a href="http://www.u-he.com/cms/zebra">u-he's Zebra2 synthesizer</a>.</li>
<li>Configure your VSTi to start on boot.</li>
</ol>
<div>
Let's go through each of these steps in a bit more detail.</div>
<div>
<br /></div>
<h4>
Selecting your Chromebox</h4>
<div>
We're going to be running Wine and Windows-based VSTi plugins. Both of these have to run on an x86 CPU so make sure you don't purchase an ARM-based device.</div>
<div>
<br /></div>
<div>
I decided on the Asus CHROMEBOX-M004U mostly because it is the most popular one and most of the information on the web seems to be about this device. There's also a more expensive model that uses a Core i3 processor which may be more useful if the plugin you want to run requires more CPU resources.</div>
<div>
<br /></div>
<div>
I'd also like to say that you don't necessarily need a Chromebox. If you already have an x86 based PC running Ubuntu then this software and configuration should work equally as well. Just skip the steps that are tied to Chrome OS, its firmware, or booting.</div>
<div>
<br /></div>
<h4>
Install Ubuntu</h4>
<div>
I followed <a href="http://rogerstringer.com/2014/09/21/upgrade-asus-chromebox-ram-bigger-ssd-ubuntu">Roger Stringer's guide</a> and he did a great job of getting me to an Ubuntu login prompt. I didn't upgrade my hardware though. Here are the choices I made when configuring the software:</div>
<div>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; direction: ltr; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><span style="color: #f8f8f2; font-family: Consolas, Monaco, Andale Mono, monospace;"><span style="font-size: 12px; line-height: 14px;">chrome $ sudo chromeos-firmwareupdate --mode=todev</span></span></pre>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; direction: ltr; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><span style="color: #f8f8f2; font-family: Consolas, Monaco, Andale Mono, monospace;"><span style="font-size: 12px; line-height: 14px;">chrome $ curl -L -O http://goo.gl/s9ryd > /tmp/s9ryd</span></span></pre>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; direction: ltr; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><span style="color: #f8f8f2; font-family: Consolas, Monaco, Andale Mono, monospace;"><span style="font-size: 12px; line-height: 14px;">chrome $ sudo bash /tmp/s9ryd ubuntu-standard</span></span></pre>
</div>
<div>
I selected the dual-boot option and gave Ubuntu 6GB of space.</div>
<div>
<br /></div>
<h4>
Boot Ubuntu by Default</h4>
<div>
Next I ran the command in ChromeOS to always boot Ubuntu:</div>
<div>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; color: #f8f8f2; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', monospace; font-size: 12px; line-height: 14px; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><code class=" language-javascript" style="background: rgb(34, 34, 34); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', monospace; padding: 2px; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal; word-spacing: normal;">chrome $ sudo cgpt add <span class="token operator">-</span>i <span class="token number" style="color: #ae81ff;">6</span> <span class="token operator">-</span>P <span class="token number" style="color: #ae81ff;">5</span> <span class="token operator">-</span>S <span class="token number" style="color: #ae81ff;">1</span> <span class="token operator">/</span>dev<span class="token operator">/</span>sda && sudo reboot</code></pre>
</div>
<div>
When you reboot now you should see a warning about using the device in developmental mode and are required to hit "CTRL-D" to continue. <b>DO NOT HIT THE SPACE BAR, IT WILL WIPE OUT UBUNTU!</b></div>
<div>
<br /></div>
<div>
This was a problem for the way I intended to use the device: without a computer keyboard or monitor. I needed a way to bypass the "CTRL-D" screen.</div>
<div>
<br /></div>
<div>
Once you have verified Ubuntu is working you need to boot back into Chrome OS to modify the firmware so that you don't need to hit "CTRL-D" every time you boot. At a Linux prompt enter the following:</div>
<div>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', monospace; font-size: 12px; line-height: 14px; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><code class=" language-javascript" style="background-attachment: initial; background-clip: initial; background-color: #222222; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', monospace; padding: 2px; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal; word-spacing: normal;"><span style="color: #f8f8f2;">ubuntu $ sudo cgpt add -i </span><span style="color: #ae81ff;">6</span></code><span style="background-color: #222222; color: #f8f8f2; word-spacing: normal;"> -P </span><span style="background-color: #222222; color: #ae81ff; word-spacing: normal;">0</span><span style="background-color: #222222; color: #f8f8f2; word-spacing: normal;"> -S </span><span style="background-color: #222222; color: #ae81ff; word-spacing: normal;">0</span><span style="background-color: #222222; color: #f8f8f2; word-spacing: normal;"> /dev/sda && sudo reboot</span></pre>
</div>
<div>
You have to <i>physically open</i> the device and remove the firmware write-protect screw. Every model is different. I used <a href="http://www.deconetworks.com/chromebox-full-linux-desktop/">Don Slesnick's guide</a> for my Asus. You'll have to use Google to find out how to do it on your Chromebox if it's a different vendor. <b>THIS WILL VOID YOUR WARRANTY! ONLY DO SO AT YOUR OWN RISK.</b></div>
<div>
<br /></div>
<div>
Next, an article by <a href="https://johnlewis.ie/neutering-the-developer-mode-screen-on-your-chromebook/">John Lewis</a> helped me get the Chrome OS commands to modify the firmware settings. John's guide is a bit dated and intended for ARM devices though so the commands I used are slightly different.</div>
<div>
Backup the firmware:</div>
<div>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; direction: ltr; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><code class=" language-javascript" style="background-attachment: initial; background-clip: initial; background-color: #222222; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', monospace; font-size: 12px; line-height: 14px; padding: 2px; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal; word-spacing: normal;"><span style="color: #f8f8f2;">chrome $</span></code><span style="background-color: transparent; font-size: 12px; line-height: 14px;"><span style="color: #f8f8f2; font-family: Consolas, Monaco, Andale Mono, monospace;"> sudo mkdir /usr/local/fw && sudo flashrom -r /usr/local/fw/bios.bin</span></span></pre>
</div>
<div>
Change the firmware to a developer-friendly mode (fast boot with no CTRL-D delay and support booting from USB devices):</div>
<div>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; direction: ltr; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><code class=" language-javascript" style="background-attachment: initial; background-clip: initial; background-color: #222222; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', monospace; font-size: 12px; line-height: 14px; padding: 2px; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal; word-spacing: normal;"><span style="color: #f8f8f2;">chrome $</span></code><span style="background-color: transparent; font-size: 12px; line-height: 14px;"><span style="color: #f8f8f2; font-family: Consolas, Monaco, Andale Mono, monospace;"> sudo </span></span><span style="background-color: transparent; font-size: 12px; line-height: 14px;"><span style="color: #f8f8f2; font-family: Consolas, Monaco, Andale Mono, monospace;">/usr/bin/set_gbb_flags.sh 0x11 && sudo reboot</span></span></pre>
</div>
<div>
The device should reboot into Chrome OS without needing "CTRL-D". All that's left now is to switch back to Ubuntu as your boot partition:</div>
<div>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; color: #f8f8f2; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', monospace; font-size: 12px; line-height: 14px; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><code class=" language-javascript" style="background: rgb(34, 34, 34); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', monospace; padding: 2px; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal; word-spacing: normal;">chrome $ sudo cgpt add <span class="token operator">-</span>i <span class="token number" style="color: #ae81ff;">6</span> <span class="token operator">-</span>P <span class="token number" style="color: #ae81ff;">5</span> <span class="token operator">-</span>S <span class="token number" style="color: #ae81ff;">1</span> <span class="token operator">/</span>dev<span class="token operator">/</span>sda && sudo reboot</code></pre>
</div>
<div>
If all goes well the Chromebox should boot into Ubuntu in just under 7 seconds.</div>
<div>
<br /></div>
<h4>
Configure Ubuntu</h4>
<div>
The "ubuntu-standard" setup is really pretty minimal. You'll need to install a few packages to make your life easier and to prepare for setting up Wine and fsthost. By default the only editor installed is nano. If you want something different add it at this time. I chose emacs, but it's not required for the build. The apt-file package also isn't strictly required but it made my life easier when searching for dependencies and packages that own particular files.</div>
<div>
<br /></div>
<div>
Don't forget the default username is "user" and the password is also "user". The account has sudo access to run all your requests.</div>
<div>
<br /></div>
<div>
Here are the packages I installed first:</div>
<div>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; color: #f8f8f2; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', monospace; font-size: 12px; line-height: 14px; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><code class=" language-javascript" style="background: rgb(34, 34, 34); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', monospace; padding: 2px; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal; word-spacing: normal;">ubuntu $ sudo apt-get update && sudo apt-get install gcc make apt-file unzip emacs23-nox openssh-server wpasupplicant wireless-tools acpid</code></pre>
</div>
<div>
<br /></div>
<h2>
Setup wireless networking</h2>
<div>
To keep the device mostly portable I opted for wireless networking in my home. I did not use the Ubuntu standard networking because I did not want the device to wait for an IP address on boot. I'd rather it connect after the plugin is loaded. Because I run WPA2 at home there's <a href="https://www.linux.com/learn/tutorials/374514-control-wireless-on-the-linux-desktop-with-these-tools">a bit more work to setup a WiFi connection</a>.</div>
<div>
<br /></div>
<div>
I created /etc/wpa_supplicant.conf with the following contents. You need to generate your own file with wpa_supplicant:</div>
<div>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; direction: ltr; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><span style="color: #f8f8f2; font-family: Consolas, Monaco, Andale Mono, monospace;"><span style="font-size: 12px; line-height: 14px;">network={
ssid="my_home_ssid"
#psk="password"
psk=a133925147b607bdda00872e400000000039d489a9d7ca8a0e7e1e8c64500000
}</span></span></pre>
</div>
<div>
Change the WiFi module parameters to enhance performance over power savings. Create the file /etc/modprobe.d/ath9k.conf with the following:</div>
<div>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; direction: ltr; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><span style="color: #f8f8f2; font-family: Consolas, Monaco, Andale Mono, monospace;"><span style="font-size: 12px; line-height: 14px;">options ath9k nohwcrypt=1 blink=1 btcoex_enable=1 enable_diversity=1</span></span></pre>
</div>
<div>
And now we make sure networking starts at boot by adding the following lines to /etc/rc.local:</div>
<div>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; direction: ltr; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><span style="color: #f8f8f2; font-family: Consolas, Monaco, Andale Mono, monospace;"><span style="font-size: 12px; line-height: 14px;"># starts wifi in the background
/sbin/wpa_supplicant -B -i wlan0 -Dwext -c /etc/wpa_supplicant.conf
/sbin/iwconfig wlan0 power off
/sbin/dhclient -nw wlan0</span></span></pre>
</div>
<div>
Change the last line to assign a static IP address if you want to be able to reliably ssh into your device. Since you've already installed openssh-server you are all set to accept incoming connections.</div>
<div>
<br /></div>
<h2>
Power button</h2>
<div>
I wanted the power button to immediately and safely power down the device when pressed. This minimizes the potential for the Linux filesystem to become corrupted and require manual maintenance. The acpid package is already installed and all it takes is a minor edit to the acpi daemon settings. Edit the file /etc/acpi/events/powerbtn and make the following modification:</div>
<div>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; direction: ltr; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><span style="color: #f8f8f2; font-family: Consolas, Monaco, Andale Mono, monospace;"><span style="font-size: 12px; line-height: 14px;"># action=/etc/acpi/powerbtn.sh
action=/sbin/poweroff
</span></span></pre>
</div>
<div>
<span style="color: #f8f8f2; font-family: Consolas, Monaco, Andale Mono, monospace;"><span style="font-size: 12px; line-height: 14px;"><br /></span></span></div>
<div>
Now a quick tap of the power button will immediately power off your Chromebox. </div>
<div>
<br /></div>
<h4>
Audio Priorities</h4>
<div>
Ted Felix has a great <a href="http://tedfelix.com/linux/linux-midi.html">introduction to Audio and MIDI on Linux</a>. From this guide I decided to use Jack version 2.x. First we need to install it:</div>
<div>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; color: #f8f8f2; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', monospace; font-size: 12px; line-height: 14px; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><code class=" language-javascript" style="background: rgb(34, 34, 34); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', monospace; padding: 2px; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal; word-spacing: normal;">ubuntu $ sudo apt-get update && sudo apt-get install jackd2 alsa-utils alsa-base</code></pre>
</div>
<div>
When it installs be sure to answer <b><YES></b> to real-time audio priority. It will setup the audio group and configure process limits in /etc/security/limits.d/audio.conf.</div>
<div>
<br /></div>
<div>
Now we just need to add the default user 'user' to the audio group. (If you decide to use a different username for audio you'll need to adjust the command accordingly).</div>
<div>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; color: #f8f8f2; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', monospace; font-size: 12px; line-height: 14px; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><code class=" language-javascript" style="background: rgb(34, 34, 34); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', monospace; padding: 2px; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal; word-spacing: normal;">ubuntu $ sudo gpasswd -a user audio</code></pre>
</div>
<div>
<br /></div>
<div>
Next we need to check for the audio interface. You should see the following output when running this command:</div>
<div>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; color: #f8f8f2; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', monospace; font-size: 12px; line-height: 14px; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><code class=" language-javascript" style="background: rgb(34, 34, 34); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', monospace; padding: 2px; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal; word-spacing: normal;">$ cat /proc/asound/cards
0 [MID ]: HDA-Intel - HDA Intel MID
HDA Intel MID at 0xe0710000 irq 62
1 [PCH ]: HDA-Intel - HDA Intel PCH
HDA Intel PCH at 0xe0714000 irq 64</code></pre>
</div>
<div>
The important line in my case is number 1 that contains "PCH". The number 0 interface is the HDMI digital audio path. A quick test of the audio will tell us it's working:</div>
<div>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; color: #f8f8f2; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', monospace; font-size: 12px; line-height: 14px; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><code class=" language-javascript" style="background: rgb(34, 34, 34); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', monospace; padding: 2px; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal; word-spacing: normal;">ubuntu $ amixer -c 1 set Master 100 unmute # unmutes and maxes volume for card #1 above
ubuntu $ wget http://www.kozco.com/tech/piano2.wav # fetch piano testfile
ubuntu $ aplay -D hw:1 piano2.wav # play piano testfile on card #1 above</code></pre>
</div>
<div>
If you hear audio, great! If not you'll probably have to spend some time debugging why and is certainly beyond the scope of this tutorial. Google is your friend in this case.</div>
<div>
<br /></div>
<div>
<h4>
Wine Setup</h4>
</div>
<div>
The installer for chrubuntu is a bit non-standard and doesn't do everything a normal Unbuntu installer does. You need to do a bit more to get Wine installed.</div>
<div>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; color: #f8f8f2; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', monospace; font-size: 12px; line-height: 14px; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><code class=" language-javascript" style="background: rgb(34, 34, 34); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', monospace; padding: 2px; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal; word-spacing: normal;">ubuntu $ sudo add-apt-repository ppa:ubuntu-wine/ppa
ubuntu $ sudo dpkg --add-architecture i386
ubuntu $ sudo apt-get update
ubuntu $ sudo apt-get install wine1.7</code></pre>
</div>
<div>
I'm using the PPA version to get the latest optimizations to Wine. We have to add the i386 arch because Wine depends on several i386 libraries.</div>
<div>
<br /></div>
<div>
<h4>
Compiling fsthost</h4>
</div>
<div>
We're almost done. Next we need to compile the latest trunk version of fsthost. Use the "Download Snapshot" button <a href="http://sourceforge.net/p/fsthost/code/HEAD/tree/trunk/">on the top right of this page</a>. This is necessary to prevent a segfault while executing.</div>
<div>
<br /></div>
<div>
You'll need to install a few more packages to meet the requirements to build:</div>
<div>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; direction: ltr; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><code class=" language-javascript" style="background-attachment: initial; background-clip: initial; background-color: #222222; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; color: #f8f8f2; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', monospace; font-size: 12px; line-height: 14px; padding: 2px; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal; word-spacing: normal;">ubuntu </code><span style="background-color: transparent; font-size: 12px; line-height: 14px;"><span style="color: #f8f8f2; font-family: Consolas, Monaco, Andale Mono, monospace;">$ sudo apt-get install </span></span><span style="background-color: transparent; font-size: 12px; line-height: 14px;"><span style="color: #f8f8f2; font-family: Consolas, Monaco, Andale Mono, monospace;">libglib2.0-dev libxml2-dev libxml-perl wine1.7 libjack-jackd2-dev libc6-dev-i386 wine1.7-dev libx11-dev dbus-x11</span></span></pre>
</div>
<div>
Edit the Makefile and disable building 32-bit, LASH, and GTK. I had trouble with all three of these options and found this to be the simplest way to a compiled fsthost64 binary. Here's the diff generated to the Makefile:</div>
<div>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; direction: ltr; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><code class=" language-javascript" style="background-attachment: initial; background-clip: initial; background-color: #222222; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; color: #f8f8f2; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', monospace; font-size: 12px; line-height: 14px; padding: 2px; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal; word-spacing: normal;">ubuntu </code><span style="background-color: transparent; font-size: 12px; line-height: 14px;"><span style="color: #f8f8f2; font-family: Consolas, Monaco, Andale Mono, monospace;">$ diff -u fsthost/Makefile.orig fsthost/Makefile
--- fsthost/Makefile.orig 2015-04-14 14:01:19.623081021 +0000
+++ fsthost/Makefile 2015-04-14 13:56:24.983086298 +0000
@@ -1,11 +1,11 @@
### Generated by Winemaker ... and improved by Xj ;-)
SRCDIR := .
SUBDIRS :=
-PLAT := 32
-GTK := 3
+PLAT := 64
+GTK := 0
VUMETER := 0
LBITS := $(shell getconf LONG_BIT)
-LASH_EXISTS := $(shell if pkg-config --exists lash-1.0; then echo yes; else echo no; fi)
+LASH_EXISTS := no # $(shell if pkg-config --exists lash-1.0; then echo yes; else echo no; fi)
#LAST_EXISTS := 'no'
# Modules
@@ -97,9 +97,9 @@
endif
# On 64 bit platform build also fsthost64
-ifeq ($(LBITS), 64)
-PLAT += 64
-endif
+#ifeq ($(LBITS), 64)
+#PLAT += 64
+#endif
EXES := $(PLAT:%=fsthost%)</span></span></pre>
</div>
<div>
<span style="background-color: transparent;">Now all you should need to do to compile is run make wherever you unziped the source:</span></div>
<div>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; direction: ltr; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><code class=" language-javascript" style="background-attachment: initial; background-clip: initial; background-color: #222222; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; color: #f8f8f2; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', monospace; font-size: 12px; line-height: 14px; padding: 2px; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal; word-spacing: normal;">ubuntu </code><span style="background-color: transparent; font-size: 12px; line-height: 14px;"><span style="color: #f8f8f2; font-family: Consolas, Monaco, Andale Mono, monospace;">$ make</span></span></pre>
</div>
<div>
<span style="background-color: transparent;"><br /></span></div>
<div>
<h4>
Setup your VSTi</h4>
</div>
<div>
I chose Zebra2 because I love it and because u-he have very unobtrusive plugins that only use a simple serial file to register and do not add keys to the Windows Registry.</div>
<div>
<br /></div>
<div>
All I had to do was Zip up the installed Windows VST directory and unzip it to ~/Zebra2 on my Linux machine. It's already registered to me and remembers my MIDI mappings for XY controllers and master volume. It looks like this:</div>
<div>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; direction: ltr; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><span style="color: #f8f8f2; font-family: Consolas, Monaco, Andale Mono, monospace;"><span style="font-size: 12px; line-height: 14px;">ubuntu $ ls -F $HOME/Zebra2
Zebra2.data/ Zebra2(x64).dll</span></span></pre>
</div>
<div>
<br /></div>
<div>
<h4>
Running it all</h4>
</div>
<div>
It only takes a few commands to get everything working:</div>
<div>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; direction: ltr; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><span style="color: #f8f8f2; font-family: Consolas, Monaco, Andale Mono, monospace;"><span style="font-size: 12px; line-height: 14px;">ubuntu $ eval $(dbus-launch --auto-syntax)
ubuntu $ amixer -c 1 set Master 100 unmute
ubuntu $ jack_control exit
ubuntu $ jackd -R -d alsa --device hw:1 --rate 48000 --period 256 --midi raw &
ubuntu $ $HOME/fsthost/fsthost64 -V "$HOME/Zebra2/Zebra2(x64).dll" &</span></span>
</pre>
</div>
<div>
At this point you should be able to plug in your favorite USB MIDI Keyboard and play notes!</div>
<div>
<br /></div>
<div>
The settings above give about a 5.5ms latency to the MIDI channel. If you want even faster response change --period to 128. Be warned though, this increases CPU usage.</div>
<div>
<br /></div>
<div>
<h4>
Starting it at boot</h4>
</div>
<div>
I made a slightly more refined script to get the whole thing started at boot:</div>
<div>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; direction: ltr; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><span style="color: #f8f8f2; font-family: Consolas, Monaco, Andale Mono, monospace;"><span style="font-size: 12px; line-height: 14px;">ubuntu $ </span></span><span style="background-color: transparent; font-size: 12px; line-height: 14px;"><span style="color: #f8f8f2; font-family: Consolas, Monaco, Andale Mono, monospace;">$ cat ~/run-vst.sh
#!/bin/bash
if [ -n "$1" -o -n "$(pgrep jackd)" ]; then
kill $(pgrep fsthost64.so)
kill $(pgrep jackd)
[ -n "$1" ] && exit 0
fi
export DISPLAY=:0
eval $(dbus-launch --auto-syntax)
card_num=$(grep ' - HDA Intel PCH$' /proc/asound/cards |
awk '{print $1}')
amixer -c $card_num set Master 100 unmute
jack_control exit
jackd -R -d alsa --device hw:$card_num --rate 48000 \
--period 256 --midi raw &>/dev/null &
while [ -z "$(pgrep jackd)" ] ; do
sleep 0.2
done
$HOME/fsthost/fsthost64 -V "$HOME/Zebra2/Zebra2(x64).dll" \
&>/dev/null &</span></span></pre>
</div>
<div>
<br /></div>
<div>
And I launch it on boot with the following addition to /etc/rc.local:</div>
<div>
<pre class=" language-javascript" style="background: rgb(39, 40, 34); border-radius: 0.3em; direction: ltr; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: rgba(0, 0, 0, 0.298039) 0px 1px; word-break: normal;"><span style="color: #f8f8f2; font-family: Consolas, Monaco, Andale Mono, monospace;"><span style="font-size: 12px; line-height: 14px;"># Start the plugin
runuser -u user /home/user/run-vst.sh</span></span></pre>
</div>
<div>
When all is said and done I can boot to Zebra in just under 10 seconds. Not bad at all. :)</div>
<div>
<br /></div>
<div>
I change patches with MIDI program change message and morph the patch with the pre-mapped XYs from my Windows setup.<br />
<br /></div>
<div>
<h4>
Overall Performance</h4>
</div>
<div>
Zebra2 is a very CPU-efficient synththesizer. The default sawtooth sound plays without any issues on the Chromebox easily playing multiple notes and chords. However, more complex patches, heavy use of FX, arpeggiator, or CPU-intensive filter modes like the XMF can quickly cause the little Intel Celeron to hit max CPU.</div>
<div>
<br /></div>
<div>
Some patches will need tweaking to bring their CPU down. As long as presets are created with a mindset of reducing CPU usage I see this as a very functional setup.</div>
<div>
<br /></div>
<div>
If you are concerned about CPU there is an Intel i3 Chromebox made by Dell and the Intel NUC has a Core i5 option: something I may consider in a future build.</div>
<div>
<br /></div>
<div>
<h4>
Items for further exploration</h4>
</div>
<div>
Ubuntu has a realtime-kernel option. I didn't use it because the Chromebox is doing tricky things to boot and is most certainly not doing the usual grub2 PC setup.</div>
<div>
<br /></div>
<div>
Completely replace the firmware with <a href="http://forum.kodi.tv/showthread.php?tid=194362">SeaBIOS</a>. I chose not to do this for fear of bricking the device and I am uncertain to its level of support.</div>
<div>
<br /></div>
<div>
fsthost -S telnet option. The -S option allows you to telnet to a specified port and view/alter VST settings. I haven't tried this at all but it looks like an interesting way to interact with the plugin. Definitely worth examination.<br />
<br />
Multicore usage. I haven't explored this at all and have no idea if plugins that attempt to execute in a multi-threaded manor will actually consume other cores. I might try using u-he's Diva to see what happens. I'm not sure how I will enable multicore though since I don't have a gui and I don't think that button can be MIDI learned.</div>
<div>
<br /></div>
<div>
Using the device with other plugins. I am considering an install for Camel Audio's Alchemy. Now that the company was acquired by Apple and Alchemy is discontinued it would provide for a stable way to use the plugin for years to come.</div>
Brian Rzyckihttp://www.blogger.com/profile/05567239597443298839noreply@blogger.com0tag:blogger.com,1999:blog-1304882058468403625.post-58288385238145394412014-08-25T15:00:00.002-07:002014-08-26T07:15:01.745-07:00Using QEMU to run Ubuntu ARM 64-bit (aarch64)There are several low-cost 32-bit ARM devices on the market today. Unfortunately the same is not true for 64-bit ARM devices. Thankfully the good people working on <a href="http://wiki.qemu.org/Main_Page">QEMU</a> have recently added aarch64 support. An excellent blog post by <a href="http://www.bennee.com/~alex/blog/2014/05/09/running-linux-in-qemus-aarch64-system-emulation-mode/">Alex Bennée</a> outlines the steps needed to get QEMU installed on your Linux system ready to run 64-bit ARM code. The goal of this post is to take the installation one step further and get a full-fledged <a href="http://www.ubuntu.com/">Ubuntu</a> Linux distribution running in QEMU.<br><br>
The reason I chose Ubuntu is for one important reason: they <a href="https://cloud-images.ubuntu.com/">publish nightly builds</a> of their OS for cloud machine deployment. These images contain a full base OS install and only require a bit of tweaking. Once deployed in QEMU they work just like any other Ubuntu installed device.<br><br>
When researching this I used a git checkout of QEMU HEAD as 35858955e6c6f9ef41c199d15457c13426ac6434. I also used Ubuntu 14.04 LTS on an x86_64 system to run QEMU and to prepare the Ubuntu guest OS image.<br><br>
First up we need to fetch an appropriate image. I like using LTS as Ubuntu is a little more careful about package updates/changes to their long-term releases. Grabbing the latest nightly image means fewer package updates once we're done customizing the image. With that in mind I selected <a href="https://cloud-images.ubuntu.com/trusty/current/trusty-server-cloudimg-arm64-disk1.img">this 300MB image</a>. It's important to note the "-disk1.img" files are qcow2 images which are QEMU's native disk format.<br><br>
Once the image is downloaded we need to resize the filesystem. By default Ubuntu only leaves about 400MB of space free for use and becomes pretty cramped for any real work. We have to perform three steps to resize the image. Resize the qcow2 disk size to whatever you want. I used 8GB:
<pre>$ $HOME/git/qemu/qemu-img resize trusty-server-cloudimg-arm64-disk1.img 8G
Image resized.
$ $HOME/git/qemu/qemu-img info trusty-server-cloudimg-arm64-disk1.img | grep size:
virtual size: 8.0G (8589934592 bytes)
disk size: 301M
cluster_size: 65536</pre>
Next, resize the disk partition layout. We use qemu-nbd to allow us to mount the filesystem as a block device. Ubuntu's kernel has support for nbd compiled in and we just need to load the module.
<pre>$ sudo modprobe nbd max_part=8
$ sudo $HOME/git/qemu/qemu-nbd --connect=/dev/nbd0 trusty-server-cloudimg-arm64-disk1.img
$ sudo fdisk /dev/nbd0
Command (m for help): p
Disk /dev/nbd0: 8589 MB, 8589934592 bytes
4 heads, 32 sectors/track, 131072 cylinders, total 16777216 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0008bae4
Device Boot Start End Blocks Id System
/dev/nbd0p1 * 2048 2889727 1443840 83 Linux
</pre>
In the above output we need to save off the starting block of the partition /dev/nbd0p1. It's the number <b>2048</b> in the last line above. I've only ever seen 2048 but it can possibly change in the future so be sure to check what it is with fdisk. Now we delete (and re-create) the partition entry:
<pre>command (m for help): d
Selected partition 1
Command (m for help): n
Partition type:
p primary (0 primary, 0 extended, 4 free)
e extended
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-16777215, default 2048): 2048
Last sector, +sectors or +size{K,M,G} (2048-16777215, default 16777215):
Using default value 16777215
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.</pre>
Note the use of <b>2048</b> as the First Sector as mentioned previously. The last step is to resize the actual filesystem contained within the first partition:
<pre>$ sudo e2fsck -f /dev/nbd0p1
...
$ sudo resize2fs /dev/nbd0p1</pre>
While we have the filesystem available through nbd we need to obtain the Linux kernel and initrd.img files:
<pre>$ sudo mkdir -p /mnt/virt && sudo mount /dev/nbd0p1 /mnt/virt
$ cd /some/path
$ sudo cp /mnt/virt/boot/*-generic .
$ sudo chown $USER:$USER *-generic
$ ln -s *disk1.img disk1.img
$ ln -s vmlinuz-* vmlinuz
$ ln -s initrd.img-* initrd.img</pre>
As far as I can tell QEMU doesn't like having to search the virtual hard drive for the bootable images which necessitates that step. The symlinks just make invocations to QEMU a bit easier and shorter. And now we can remove the nbd mounted filesystem:
<pre>$ sudo umount /mnt/virt && rmdir /mnt/virt
$ sudo $HOME/git/qemu/qemu-nbd -d /dev/nbd0</pre>
We're now ready for our first boot of QEMU. Here's the command line I used:
<pre>$ $HOME/git/qemu/aarch64-softmmu/qemu-system-aarch64 \
-machine type=virt -cpu cortex-a57 -smp 1 -m 2048 -nographic \
-rtc driftfix=slew -kernel vmlinuz \
-append "console=ttyAMA0 root=LABEL=cloudimg-rootfs rw init=/bin/sh" \
-initrd initrd.img -device virtio-scsi-device,id=scsi \
-device scsi-hd,drive=hd -drive if=none,id=hd,file=disk1.img</pre>
The boot -append line is important here: the LABEL= is necessary for Unbuntu to mount the root filesystem and we short-circuit the boot process into an emergency shell. If we didn't boot into a shell the image would try to come up as a cloud slave node and try to phone home. Not very useful for our needs. If all goes well you should see a prompt like the following:
<pre>Begin: Running /scripts/init-bottom ... done.
#</pre>
At this point there are some customization steps that need to be done before we can boot this image normally. In order to set things up we have to mount the <i>soon-to-be</i> root filesystem and then chroot into it:
<pre># mount /dev/sda1 /mnt
# chroot /mnt /bin/bash
bash: cannot set terminal process group (-1): Inappropriate ioctl for device
bash: no job control in this shell
root@(none):/# </pre>
Set root's password. Ubuntu images don't have one:
<pre>root@(none):/# passwd root
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully</pre>
Remove the cloud packages from the Ubuntu image. This speeds up boot time and also gives you a console login prompt:
<pre>root@(none):/# dpkg -P cloud-guest-utils cloud-init pollinate landscape-client landscape-common apparmor apport apport-symptoms ufw
...
root@(none):/# rm -f /etc/init/pollinate.conf /etc/default/pollinate
root@(none):/# rm -rf /etc/cloud</pre>
Disable the VESA framebuffer. It doesn't work with QEMU and just produces boot-up errors.
<pre>root@(none):/# perl -p -i -e 's/modprobe -q -b vesafb/true/g;' /etc/init/udev-fallback-graphics.conf</pre>
Allow all users to SSH into the OS with passwords and keys:
<pre>root@(none):/# perl -p -i -e 's/^PermitRootLogin.+$/PermitRootLogin yes/g;' /etc/ssh/sshd_config
root@(none):/# perl -p -i -e 's/^PasswordAuthentication.+$/PasswordAuthentication yes/g;' /etc/ssh/sshd_config
</pre>
Generate new, unique SSH server keys for each guest OS:
<pre>root@(none):/# rm -f /etc/ssh/ssh_host_*_key*
root@(none):/# dpkg-reconfigure openssh-server</pre>
Change your timezone with the ncurses menu:
<pre>root@(none):/# dpkg-reconfigure tzdata</pre>
I also recommend setting up NTP on the Guest OS, especially if you're sharing files between the guest and host OS. The change below will tell Ubuntu to synchronize time with ntp.ubuntu.com, the default setting in the "NTPSERVERS=" variable in the same file:
<pre>root@(none):/# perl -p -i -e 's/^NTPDATE_USE_NTP_CONF=.+$/NTPDATE_USE_NTP_CONF=no/g;' /etc/default/ntpdate</pre>
(optional) I like the next two commands to make root logins much more responsive. Ubuntu will try to gather OS information on every login and display it to you if you don't disable it. These commands remove that feature. Don't run these if you like seeing Ubuntu's login information:
<pre>root@(none):/# >/root/.hushlogin
root@(none):/# rm -f /etc/update-motd.d/*</pre>
(optional) Setup a shared storage location to copy files to/from the Guest and Host OS. QEMU has a nice feature called virtio to accomplish this:
<pre>root@(none):/# mkdir /shared
root@(none):/# vi /etc/rc.local
/bin/mount -t 9p -o trans=virtio lvdisk0 /shared # add this somewhere before the 'exit 0' line
</pre>
Don't add this entry to /etc/fstab. There seem to be module loading conflicts during boot time which prevent it from succeeding.<br><br>
(optional) Create a non-root admin user:
<pre>root@(none):/# adduser ubuntu
...
Is the information correct? [Y/n] y
root@(none):/# usermod -aG adm ubuntu
root@(none):/# usermod -aG sudo ubuntu
</pre>
(optional) Statically set the hostname. You also can choose to pass in a hostname at boot (see below):
<pre>root@(none):/# echo "newhost" >/etc/hostname</pre>
When you're done you need to exit the chroot and halt the system to perform the final normal boot:
<pre>root@(none):/# exit
# sync; sync; sync; halt
</pre>
I've had the halt command fail on me which is why I have the old-fashioned three syncs before executing it.<br><br>
You can exit the QEMU console with "ctrl-a c" to get the QEMU console, and then typing "quit".
Finally you can try to boot the image normally. Here's an example command line I use:
<pre>$ BASE=$PWD; HOST=ubuntu; mac=52:54:00:00:00:00; sshport=22000
$ $HOME/git/qemu/aarch64-softmmu/qemu-system-aarch64 \
-machine type=virt -cpu cortex-a57 -smp 1 -m 2048 -nographic \
-rtc driftfix=slew -kernel "$BASE"/vmlinuz \
-append "console=ttyAMA0 root=LABEL=cloudimg-rootfs rw" \
-initrd "$BASE"/initrd.img \
-device virtio-scsi-device,id=scsi -device scsi-hd,drive=hd \
-drive if=none,id=hd,file="$BASE"/disk1.img \
-fsdev local,id=vdisk0,path="$BASE"/shared,security_model=none \
-device virtio-9p-device,fsdev=vdisk0,mount_tag=lvdisk0 \
-netdev user,hostfwd=tcp::${sshport}-:22,hostname=$HOST,id=net0 \
-device virtio-net-device,mac=$mac,netdev=net0 \
-monitor telnet:0.0.0.0:24000,server,nowait \
-serial telnet:0.0.0.0:23000,server,nowait</pre>
There are a few differences from the previous QEMU invocation worthy of note. I have setup a virtio shared directory at $BASE/shared using the line starting with "-fsdev". The netdev line sets a MAC address for the device and also port-forwards traffic on the host OS port $sshport to the guest OS port 22. This port-forwarding allows both remote and local SSH connections to the running guest OS over SSH. The HOST= parameter sets the guest OS hostname.<br><br>
The "-monitor" and "-serial" lines give you telnet-like interfaces to the QEMU console and Linux console respectively. It's a great way to expose those interfaces as long as your network is secure, like a lab environment. I wouldn't expose those interfaces if you don't trust others on your network as those ports will act like telnet sessions without any authentication.<br><br>
At this point you should be able to SSH into $sshport on the QEMU host and login as either root or your admin user. You can then apt-get and natively compile to your heart's content.<br><br>
If you want to run multiple instances of QEMU on the same host just change $sshport and $BASE to unique values and copy the kernel, initrd.img, and disk1.img files separately for each running instance. I've run 5 instances on the same host OS with no problems using this technique and I'm sure I could have run more as needed.<br><br>
Feedback and comments are appreciated. I know it's a bit of a brain dump but I figured it'd be useful for others to have this information. Due to the scarce available of aarch64 hardware this is a great stop-gap until those cheap SoCs start hitting the market.<br><br>
Have fun!
Brian Rzyckihttp://www.blogger.com/profile/05567239597443298839noreply@blogger.com0