tag:blogger.com,1999:blog-32247180342993502232024-03-16T11:53:11.252-07:00kronoshackerprogramming <strike>a synthesizer</strike> random thingsAnonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.comBlogger25125tag:blogger.com,1999:blog-3224718034299350223.post-87713224945540892272018-01-23T10:41:00.003-08:002018-01-23T10:45:05.705-08:00Playing with the Aurora LED PanelsI recently got my hands on a bunch of <a href="https://nanoleaf.me/en/consumer-led-lighting/products/smarter-series/nanoleaf-light-panels-smarter-kit/" target="_blank">Nanoleaf Light Panels</a> for a decent price. To be honest, I have been thinking about buying some for some time now, but IMHO they are quite expensive at about 20 Euros per piece.<br />
<div>
There is a nice <a href="https://www.eevblog.com/forum/projects/nanoleaf-aurora-teardown/" target="_blank">Teardown on EEVblog</a>, but it stops just where things get interesting from a hacker's point of view: the communication protocol you need if you want to control the tiles yourself. I decided to reverse engineer this protocol and to document it in this post.</div>
<h3>
Physical Layer</h3>
<div>
Let's first look at the physical layer. Each tile is connected to it's neighbors via a 4 pin connector. The 4 Pins are:</div>
<div>
<ol>
<li>Power Supply (24V)</li>
<li>Ground</li>
<li>Select (3.3V active high)</li>
<li>Comm (24V active low, open collector)</li>
</ol>
<div>
Pins 1, 2 and 4 are physically connected between the three connectors on the tile's edges. Pin 3 is of each edge is connected to the tile's microcontroller and can be controlled individually for each edge of the tile.</div>
</div>
<h4>
The Comm Pin</h4>
<div>
The Comm Pin is used for data communication between the tiles. It is a open collector bus which can be driven to low by any tile. The protocol must take care of collision avoidance. RS232 at 115200 Baud, 8N1 is used for the communication on this pin. Inactive level is 24V, Active level is 0V. The signal is pulled to 24V by the controller. The tiles drive the signal to GND via a open collector circuit.</div>
<h4>
The Select Pin</h4>
<div>
The Select Pin is used to enumerate the tiles and to discover topology. Usually the Select Pin is a Ground level, but it can be pulled to 3.3V for each edge of a tile separately if requested by the controller. </div>
<h3>
Protocol on Comm Pin</h3>
<div>
The protocol on the comm pin is not too complicated. The first byte in each command is always the command type. The second byte is always the short id of the addressed tile (0xFF addresses all tiles). The rest of the bytes are the optional command payload. Some commands are followed by two bytes checksum (CRC16 CCIT). Some commands trigger a response by the addressed tile which follows immediately after the command. Some responses also are followed by a CRC16.</div>
<h4>
Short and long tile IDs</h4>
<div>
Each tile has a unique 8 Byte long ID that uniquely identifies this specific tile. This long ID is used in the enumeration phase and for topology discovery. In the enumeration phase each tile is assigned a 1 Byte short ID that from then on used to address the tile.</div>
<h3>
Commands known so far</h3>
<h4>
0x01 - Assign short ID by long ID</h4>
<div>
This command is used to assign a tile a short ID if it's long ID is known. If the long ID of the tile matches the long ID in the message, the tile sets i't short ID to the short ID in the message (Byte 11) and responds. The message looks like this:</div>
<table>
<tbody>
<tr><th width="100px">Byte</th><th>Explanation</th></tr>
<tr><td>1</td><td>Command Byte (0x01)</td>
</tr>
<tr><td>2</td><td>Short ID byte (always 0xFF since addressing is done via Long ID)</td>
</tr>
<tr><td>3-10</td><td>Long ID of addressed tile</td></tr>
<tr><td>11</td><td>Short ID to be assigned to this tile</td>
</tr>
<tr><td>12-13</td><td>CRC16 of bytes 1-11</td></tr>
</tbody></table>
The tile with the Long ID matching the Long ID in the message responds with 80 00 00 if present.<br />
<div>
<h4>
0x02 - Set Edge Pin</h4>
<div>
This command is used to set the Edge Pins of the addressed tile. The only payload byte is a bitmask of the levels to be set on the three Edge Pins (0x01 / 0x02 / 0x04). There is no CRC for this command.</div>
<table><tbody>
<tr><th width="100px">Byte</th><th>Explanation</th></tr>
<tr><td>1</td><td>Command Byte (0x02)</td></tr>
<tr><td>2</td><td>Short ID byte </td></tr>
<tr><td>3</td><td>Edge Pin configuration</td></tr>
</tbody></table>
</div>
<div>
The tile with the Short ID matching the Short ID in the message sets it's Edge Pins according to the message and responds with 80 00 00 if present.<br />
<div>
</div>
</div>
<div>
<h4>
0x03 - Read Long ID if selected</h4>
<div>
This command is used to read the long ID from a tile that is selected by pulling one of it's Edge Pins high from a neighbor tile. A tile only responds to this message if one of it's Edge Pins is pulled high from the outside.</div>
<table><tbody>
<tr><th width="100px">Byte</th><th>Explanation</th></tr>
<tr><td>1</td><td>Command Byte (0x03)</td></tr>
<tr><td>2</td><td>Short ID byte (always 0xFF since addressing is done via Edge Pin) </td></tr>
</tbody></table>
</div>
<div>
The tile responds with the following sequence:</div>
<table><tbody>
<tr><th width="100px">Byte</th><th>Explanation</th></tr>
<tr><td>1</td><td>Response Byte (0x83)</td></tr>
<tr><td>2-3</td><td>Unknown</td></tr>
<tr><td>4-11</td><td>Long ID of responding tile</td></tr>
<tr><td>12-13</td><td>CRC16 of bytes 1-11</td></tr>
</tbody></table>
<div>
<div>
<h4>
0x08 - Fade Tile to Color</h4>
<div>
This command is used to set the Color of a specific tile or all tiles. A fade time can be given. There is no CRC and no response for this command.</div>
<table><tbody>
<tr><th width="100px">Byte</th><th>Explanation</th></tr>
<tr><td>1</td><td>Command Byte (0x08)</td></tr>
<tr><td>2</td><td>Short ID byte (or 0xFF for all tiles)</td></tr>
<tr><td>3</td><td>Red color value from 0x00 to 0xFF</td></tr>
<tr><td>4</td><td>Green color value from 0x00 to 0xFF</td></tr>
<tr><td>5</td><td>Blue color value from 0x00 to 0xFF</td></tr>
<tr><td>6</td><td>White color value from 0x00 to 0xFF</td></tr>
<tr><td>7-8</td><td>Fade time MSB first 0x0000 to 0xFFFF</td></tr>
</tbody></table>
</div>
<h4>
0x09 - Call for unconfigured tiles</h4>
<div>
This command is used to check if new tiles have been added to the network. Only tiles which have not been assigned a short ID will respond to this command with 80 00 00. There is no CRC for command or response.</div>
<table><tbody>
<tr><th width="100px">Byte</th><th>Explanation</th></tr>
<tr><td>1</td><td>Command Byte (0x09)</td></tr>
<tr><td>2</td><td>Short ID byte (always 0xFF)</td></tr>
</tbody></table>
</div>
<div>
<h4>
0x0A - Check tile presence</h4>
<div>
This command is used to check if a specific tiles has been removed from the network. The addressed tile will respond to the command with 80 00 00. There is no CRC for command or response.</div>
<table><tbody>
<tr><th width="100px">Byte</th><th>Explanation</th></tr>
<tr><td>1</td><td>Command Byte (0x09)</td></tr>
<tr><td>2</td><td>Short ID byte</td></tr>
</tbody></table>
</div>
<div>
<div>
<h4>
0x0B - Set Brightness</h4>
<div>
This command is used to set the brightness of a specific tile or all tiles.</div>
<table><tbody>
<tr><th width="100px">Byte</th><th>Explanation</th></tr>
<tr><td>1</td><td>Command Byte (0x0B)</td></tr>
<tr><td>2</td><td>Short ID byte</td></tr>
<tr><td>3</td><td>Brightness Value from 0x00 to 0xFF</td></tr>
</tbody></table>
</div>
</div>
<h4>
0x0C - Read tile info</h4>
<div>
This command is used to read some version information from the tile. The version numbers are encoded in ASCII, unused bytes are set to 0x00. The addressed tile responds with its version information and the CRC.</div>
<table><tbody>
<tr><th width="100px">Byte</th><th>Explanation</th></tr>
<tr><td>1</td><td>Command Byte (0x0C)</td></tr>
<tr><td>2</td><td>Short ID byte</td></tr>
</tbody></table>
The tile responds with the following sequence:<br />
<table><tbody>
<tr><th width="100px">Byte</th><th>Explanation</th></tr>
<tr><td>1</td><td>Response Byte (0x8C)</td></tr>
<tr><td>2-20</td><td>Version Information</td></tr>
<tr><td>21-22</td><td>CRC16 of bytes 1-20</td></tr>
</tbody></table>
Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com4tag:blogger.com,1999:blog-3224718034299350223.post-45836603945587020832016-06-05T13:15:00.000-07:002016-06-05T13:15:48.952-07:00Kronos hacking for a broader audience - Step 1: User InterfaceIn the last few days, the interest in this kronos hacking has increased significantly. Unfortunately this blog isn't worth much to someone without deep knowledge about Linux and other stuff. And on top of that, there is no structure since I just wrote down stuff as I researched.<br />
<br />
Marcan (whom I deeply respect for his <a href="https://hackmii.com/">work on the Wii</a>) just filled this gap with a very nice <a href="https://marcan.st/2016/06/hacking-and-upgrading-the-korg-kronos/">blog post</a> that summarizes my research and adds a proper introduction for the beginners as well as some detailed background.<br />
<br />
As he wrote in <a href="http://www.korgforums.com/forum/phpBB2/viewtopic.php?t=104547">this thread</a>, the possibility to provide feedback and to interact with the user is the foundation for a safe and clean way to bring whatever Kronos modifications we might come up with to a broader and less technical audience.<br />
<br />
Fortunately Korg's original drivers provide some basic functionality.<br />
<br />
<b><u>The framebuffer /dev/fb1</u></b><br />
<div>
The kernel module OmapVideoModule.ko provides a framebuffer device that interfaces the Kronos' LCD display. The resolution is 800x600 pixels and it has to be used in 8bpp palette mode. This means that you can choose up to 256 colors that can be shown on the display at the same time.</div>
<div>
<br /></div>
<div>
Since the display is connected to the NKS4 board, the real framebuffer is on the OMAP. This means that all changes in the fake framebuffer on the PC must be sent to the OMAP via USB. There is a special ioctl (OMAPFB_IOCTL_PIXELREGION) to trigger this update for a specific rectangle on the display. Without this ioctl, you will see nothing on the display. Unfortunately, this means that standard applications that work on /dev/fbX will not work.</div>
<div>
<br /></div>
<div>
There is also a ioctl to setup the palette (OMAPFB_IOCTL_PIXELREGION). Up to 256 palette entries can be populated with RGB colors.</div>
<div>
<br /></div>
Then, there are some less important ioctls:<br />
<br />
<ul>
<li>OMAPFB_IOCTL_FILLDATA is an accelerated fill command that fills a rectangle with a specified color</li>
<li>OMAPFB_IOCTL_GETPROGRESS, OMAPFB_IOCTL_SETPROGRESS, OMAPFB_IOCTL_INCPROGRES, OMAPFB_IOCTL_ADDTOPROGRESS are helpers to draw the progress bar that you see when the Kronos is booting. This progress bar is actually handled by the OMAP so that early boot stages can increment it without knowing about graphics.</li>
<li>OMAPFB_IOCTL_INITLCDREGS, OMAPFB_IOCTL_XAXISBYTESIZE can be used to configure the LCD configuration registers in the OMAP. As the OMAP configures those registers independently of the PC when showing the title screen, we do not need to do that.</li>
<li>OMAPFB_IOCTL_GETTITLESCREENVERSION returns some version number that is probably used by the updater to determine where to draw it's messages so that they look nice with different versions of the OMAP software.<br /></li>
</ul>
<b><u>The keypad /proc/OmapNKS4</u></b><br />
<div>
The kernel module OmapNKS4.ko creates a proc file that can be used to read part of the control surface (Keys 0-9, Enter, Exit and the scrollwheel). The interface is ugly - you can only read one keypress each time you open the file, but at least it works...<br /></div>
<div>
<br /></div>
<b><u>A demo application</u></b><br />
<div>
I have hacked together a simple demo that shows working framebuffer and control surface access <a href="https://mega.nz/#!zgtAWABb!4dOl869FcnT4MiaznAKDtKg5r0bswvmk2V2dtoAYgNU">here</a>. If you read through the source, you'll find definitions and wrapper for the ioctls and the keypad interface.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/SBQit_qmeWE/0.jpg" src="https://www.youtube.com/embed/SBQit_qmeWE?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
<div>
<br /></div>
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com13tag:blogger.com,1999:blog-3224718034299350223.post-89476831414797781842016-05-31T15:01:00.004-07:002016-05-31T15:01:42.887-07:00Kronos encrypted file systemsKorg uses <a href="https://en.wikipedia.org/wiki/Cryptoloop">Cryptoloop</a> to hide the important parts of it's Kronos firmware from prying eyes. The mount mechanism is somewhat obfuscated and hidden in <a href="https://kronoshacker.blogspot.de/2016/05/streamlining-kronos-boot-process-what.html">loadmod.ko</a> and <a href="https://kronoshacker.blogspot.de/2015/05/what-does-sbinloadoa-do.html">loadoa</a>. Here is a brief description:<br />
<ol>
<li><span style="font-family: inherit;"><a href="https://kronoshacker.blogspot.de/2015/05/what-does-sbinloadoa-do.html">loadoa </a>loads the kernel module loadmod.ko</span></li>
<li><span style="font-family: inherit;"><a href="https://kronoshacker.blogspot.de/2016/05/streamlining-kronos-boot-process-what.html">loadmod.ko</a> replaces the kernel's mount syscall with it's own implementation (but only if <a href="https://kronoshacker.blogspot.de/2015/06/filesystem-integrity-check-by-loadmodko.html">filesystem check</a>, kernel check and communication with the <a href="https://kronoshacker.blogspot.de/2015/05/notes-from-inside-kronos-part-i.html">security chip</a> are ok).</span></li>
<li><span style="font-family: inherit;"><a href="https://kronoshacker.blogspot.de/2016/05/streamlining-kronos-boot-process-what.html">loadmod.ko</a> reads and decrypts /.pairFact3 to retrieve the Cryptoloop keys. The Cryptoloop keys are the same for all devices, but the keys to decrypt /.pairFact3 are individual for each device. When you "<a href="https://kronoshacker.blogspot.de/2015/05/why-do-you-need-to-authorize-your.html">authorize</a>" your Kronos, you actually get the Cryptoloop keys encrypted </span>with your individual device keys.</li>
<li><a href="https://kronoshacker.blogspot.de/2015/05/what-does-sbinloadoa-do.html">loadoa </a>mounts issues a mount command that looks like this:<br /><span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">/bin/mount -n -t ignoreType ignoreDev /korg/rw/PCM/WaveMotion</span></li>
<li><span style="font-family: inherit;"><a href="https://kronoshacker.blogspot.de/2016/05/streamlining-kronos-boot-process-what.html">loadmod.ko</a> gets the syscall and recognizes the "magic" mount point name (/korg/rw/PCM/WaveMotion). Now it initializes the Cryptoloop device and calls the kernel's normal mount syscall handler to mount the loop device.</span></li>
</ol>
Now, it would be nice to have the Cryptoloop keys for the encrypted file systems inside the Kronos firmware. You can easily e<a href="https://kronoshacker.blogspot.de/2015/06/the-anatomy-of-kronos-firmware-update.html">xtract the encrypted files from the Kronos firmware updates</a> published by Korg. If we just had the keys, we could mount and examine them on any PC around.<br />
<div>
<br /></div>
<div>
The <a href="https://kronoshacker.blogspot.de/2015/05/about-linux-kernel-used-in-korg-kronos.html">possibility to boot our own kernel</a> helps a lot, here. One could just add some printk() to a function that handles the cryptoloop keys (for example loop_set_status).<br />
<br />
<a href="https://mega.nz/#!atFmAYLT!e9fTymnDXW-3MAUSh1BpELGoQU1gL2bdCP7vFdwO7BM">This is the kernel patch</a>. Let's see what happens...</div>
<div>
<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">loop_set_status(0): lo_file_name=/korg/ro/Eva.img lo_encrypt_type=18 lo_crypt_name=aes lo_encrypt_key=342ee59d549c7d329d835537be0540d</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">loop_set_status(1): lo_file_name=/korg/ro/WaveMotion.img lo_encrypt_type=18 lo_crypt_name=aes lo_encrypt_key=3e72c0e59fc017a9eb7d7e1168a4cdb</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">loop_set_status(2): lo_file_name=/korg/ro/Mod.img lo_encrypt_type=18 lo_crypt_name=aes lo_encrypt_key=a336a15cd841ec8926b99e7c3884eaa</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span>
<br />
<h3>
Crazy keys</h3>
</div>
<div>
Looking at <a href="http://lxr.free-electrons.com/source/include/linux/loop.h?v=2.6.31#L100">struct loop_info64</a> it is pretty clear that the simple printk("... lo_encrypt_key=%s ...", status->lo_encrypt_key) should not have worked. lo_encrypt_key should be binary, not a null terminated string!</div>
<div>
<br /></div>
<div>
Someone had no real clue about how to use loop_set_status() and used 31 (plus a \0 byte for string termination) hex digits (containing only 124 bits of information) as AES256 key.<br />
<br />
I am still wondering if this is just a stupid mistake or just one more strange obfuscation. </div>
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com5tag:blogger.com,1999:blog-3224718034299350223.post-33608263141352992402016-05-23T13:24:00.000-07:002016-05-23T13:24:27.691-07:00A short look into the past: OASYSThe Kronos' history actually began more than ten years ago with the <a href="https://en.wikipedia.org/wiki/Korg_OASYS">OASYS</a>. Back then, when the OASYS was released, I really wanted to have one, but I also really could not afford it. So I decided to hack other stuff and kind of forgot about the OASYS.<br />
<br />
Now, ten years later, I got the chance to look into the architecture and the software of the OASYS and the similarities to the Kronos are astonishing. The architecture is almost the same and I would be tempted to say that the Kronos is in fact a "OASYS Lite V2".<br />
<br />
Why "Lite"? Because the Kronos misses many expensive parts (LEDs around knobs/sliders, trigger buttons, large screen, CD drive, ...). It looks like the goal set for the Kronos product engineering was to build a more affordable version of the OASYS (which makes perfect sence, if you look at the price tag of the OASYS).<br />
<br />
Why "V2"? Because the Kronos has some features (more engines, sample streaming) that the OASYS lacks. I am wondering why Korg did not upgrade the OASYS software to include those features. Maybe hardware limitations were the reason. The OASYS has no SSD, so disk access latency might be the reason there is no sample streaming. Also, the OASYS has a single core CPU (Pentium 4) while the Kronos has a dual core (Atom). It would be interesting to benchmark the single core P4 against the dual core Atom... (<b>Update</b>: <a href="http://cpu.userbenchmark.com/Compare/Intel-Pentium-4-280GHz-vs-Intel-Atom-D525/m3163vsm5666">Comparison between OASYS and Kronos CPUs</a>. Looks like the P4 is faster in single core workloads, but the Atom is faster in multi core workloads. A synthesizer is almost a perfect multi core workload, so the Kronos is in fact more powerful than the OASYS).<br />
<br />
However, the software and hardware architecture between OASYS and Kronos are so similar that most articles in this blog are - to a certain degree - also valid for the OASYS.<br />
<br />
Here are - in no particular order - some things I noticed while comparing OASYS and Kronos:<br />
<br />
<br />
<ul>
<li>Both use Linux with RTAI realtime extensions. However, OASYS uses Linux 2.4, Kronos uses Linux 2.6</li>
<li>Security stuff (<a href="https://kronoshacker.blogspot.de/2015/06/filesystem-integrity-check-by-loadmodko.html">filesystem integrity check</a>, <a href="https://kronoshacker.blogspot.de/2015/05/notes-from-inside-kronos-part-i.html">security ic</a>, <a href="https://kronoshacker.blogspot.de/2015/05/why-do-you-need-to-authorize-your.html">authorization file</a>) is almost identical</li>
<li>The OASYS uses the VGA output of the mainboard for it's display while the Kronos uses a display connected to the <a href="https://kronoshacker.blogspot.de/2015/05/notes-from-inside-kronos-part-ii-omap.html">OMAP</a>. This means that the Kronos has to transfer all display data over USB. I am unsure why they did this - the Kronos mainboard also has a VGA connector, but it is unused.</li>
<li>In the OASYS the whole control surface (including the keybed) is connected via USB. On the Kronos, the keybed is connected to the mainboard via RS232 - the rest of the controls are still connected via USB. Maybe latency reduction?</li>
<li>The OASYS uses a custom PCI sound card while the Kronos uses a custom USB sound card for Audio/Midi I/O</li>
</ul>
<div>
Looking at all this, I am wondering why Korg sticks to meaningless upgrades like different colors or different end-plates for it's new/special editions. How about a bigger screen, LEDs for knobs and sliders and some pressure sensitive drum pads? Add a <a href="https://kronoshacker.blogspot.de/2016/02/more-power-for-kronos.html">decent mainboard</a> for <a href="https://kronoshacker.blogspot.de/2016/04/kronos-polyphony-and-performance.html">increased polyphony</a> and call it "platinum edition". KORG, are you listening???</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com0tag:blogger.com,1999:blog-3224718034299350223.post-13151110602648394812016-05-05T14:26:00.001-07:002016-05-05T14:26:22.333-07:00Streamlining the Kronos boot process / what does loadmod.ko do?I have already sched some light on the Kronos boot process in an older article (<a href="https://kronoshacker.blogspot.de/2015/05/what-does-sbinloadoa-do.html">What does /sbin/loadoa do?</a>). There you can see that a kernel module called "loadmod.ko" is loaded just before the encrypted loop files are mounted.<br />
<br />
loadmod.ko plays a vital role in booting the Kronos and is the center of Korg's attempts to protect the Kronos from hacking.<br />
<br />
<h4>
So, what does loadmod.ko do?</h4>
<br />
<ol>
<li>First, loadmod.ko performs a file system integrity check. It opens and reads <a href="https://kronoshacker.blogspot.de/2015/06/filesystem-integrity-check-by-loadmodko.html">a lot of files</a> and hashes them using MD5. The hash is then compared to a constant value encoded in loadmod.ko. If the values do not match, loadmod.ko will bail out with error code 1.<br /></li>
<li>Next, the Linux kernel is checked. loadmod.ko calls the functions register_cdrom() and init_cdrom_command() with some magic values. A normal Linux kernel will just return error codes because the parameters make no sense. The Linux kernel delivered by Korg has modified versions of this functions that return other magic values to signal loadmod.ko that the kernel is "genuine".<br /><br /><i>Korg has not published the source code for those modifications to the Linux kernel even though they are distributing a binary version of Linux with those modifications. This is a clear violation of the </i><a href="https://en.wikipedia.org/wiki/GNU_General_Public_License" style="font-style: italic;">GPL</a><i>.</i><br /><br />You can find a more detailed description of the kernel authentication mechanism in <a href="https://kronoshacker.blogspot.de/2015/05/about-linux-kernel-used-in-korg-kronos.html">About the Linux kernel used in KORG Kronos</a>.<br /><br />I provide a patch that reimplements the modified register_cdrom()/init_cdrom_command() functions <a href="https://mega.nz/#!C8ojnR7T!g6BD0SDUyt-fPNF4HV0jpe4tB1WSW4FXrd51ACRh9j8">here</a>. With this patch you can compile your own kernel that will be accepted by loadmod.ko.<br /><br />If the kernel check fails, loadmod.ko will bail out with error code 3.<br /></li>
<li>After filesystem and kernel have been checked, loadmod.ko tries to read the authorization file called "pairFact". This file contains the encryption keys for the encrypted file systems in the Kronos (<a href="https://kronoshacker.blogspot.de/2015/05/why-do-you-need-to-authorize-your.html">detailed explanation</a>). If loadmod.ko cannot read that authorization data, it will bail <br />out with error code 4.<br /></li>
<li>The contents of "pairFact" are encrypted with a key stored in the <a href="https://kronoshacker.blogspot.de/2015/05/notes-from-inside-kronos-part-i.html">security IC</a>. So, the next step for loadmod.ko is to talk to the security IC (the primitives for the communication are provided by OmapNKS4Module.ko. The Public ID of the Kronos is read and the key needed to decrypt the authorization data is read. If communication with the security IC fails, loadmod.ko will bail out with error code 5.<br /></li>
<li>If all checks were successful, a magic value (0x22FB39CC) is stored at a certain address in kernel memory. This magic value will be checked by the synthesizer module (OA.ko) later. If it is not there, OA.ko will skip some important initializations which will cause the sound output to be bad. So even if you do not need loadmod.ko anymore because you have copied the synthesizer files out of the encrypted file systems, you still need to run loadmod.ko (or at least write this magic value) to have useful sound output.<br /></li>
<li>The error code (or zero if there were no errors) from the checks above is written to "/tmp/stgStatus". This is used by /sbin/loadoa to display a more or less useful error message (or the reauthentication screen) if one of the integrity checks failed.<br /></li>
<li>Now, things are getting crazy: loadmod.ko replaces some of the kernel's syscalls by overwriting <i>sys_call_table. </i>The following syscalls are overwritten: <i style="font-style: italic;">sys_mount, sys_ioctl, </i><i>sys_oldumount, sys_umount, sys_create_module, sys_init_module.</i><br /><br />The syscalls <i>sys_mount </i>and<i> sys_oldumount </i>are replaced with versions that "magically" mount a cryptoloop filesystem if one of the magic paths (/korg/Eva, /korg/Mod, /korg/WaveMotion) is mounted.<br /><br />The other syscall replacements don't do anything but call the original handlers. It looks like Korg wanted to prevent users from loading additional modules (maybe to prevent access to the kernel memory), but that mechanism was not finished.<br /></li>
<li>Finally, a kernel thread is started. This kernel thread will handle system updates by listening on /proc/.update and running /sbin/UpdateOS or /tmp/UpdateOS as a usermode helper if necessary.</li>
</ol>
<h4>
<br /></h4>
<h4>
So, why is that interesting?</h4>
<div>
From a users point of view, loadmod.ko doesn't do many useful things. The filesystem integrity checks take precious boot time and prevent you from changing your file system. The encrypted loop file systems also degrade system performance and you can easily copy their contents onto the unencrypted file system, </div>
<div>
<br /></div>
<div>
However, if you decide to save boot time and trouble by getting rid of loadmod.ko, you still have to write the magic value or else the Kronos' sound will be crippled.</div>
<div>
<br /></div>
<div>
I have updated my <a href="https://mega.nz/#!Gt1BBYob!UriomEfGymM8Ut-ynXkQRaAbVawHvLNuDmaB0wpm_0Y">kernel patches</a> and my <a href="https://mega.nz/#!msk2wRJY!bcFXepmPW8MaNn5ZxS5Jf_FFXMWUTU75NQ2cQqxeJcA">precompiled kernel</a> to do that, Using this kernel, you do not need to load loadmod.ko. You can get rid of the filesystem/kernel integrity check and still OA.ko will work perfectly.</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com5tag:blogger.com,1999:blog-3224718034299350223.post-67810671029177599832016-04-02T16:57:00.001-07:002016-04-02T17:04:27.440-07:00Kronos Polyphony and PerformanceAs <a href="http://www.korgforums.com/forum/phpBB2/viewtopic.php?t=59889&sid=b977c97600fdbfae1a615ed5c40ac1ff">explained</a> <a href="http://www.korgforums.com/forum/phpBB2/viewtopic.php?t=75941&sid=43180e33170ddafb5ccb346e2b7fa86e">in</a> <a href="https://www.youtube.com/watch?v=b0cXManNLns">many</a> <a href="http://www.korgforums.com/forum/phpBB2/viewtopic.php?p=676200&sid=f324f2dbc86d874f1926aaf76bd960b4">discussions</a>, the Kronos has no fixed polyphony. The number of sounding voices differs depending on the engine used for each voice and even depending on which effects are currently active.<br />
<br />
<i>But how does the sound engine know how many voices can be active? </i><br />
<i><br /></i>
The answer is a file called CostProfile in /korg/rw/Startup on your Kronos (this file is not included in the <a href="http://kronoshacker.blogspot.de/2015/06/filesystem-integrity-check-by-loadmodko.html">filesystem integrity check</a>, so you can modify this file via FTP/SCP after <a href="http://kronoshacker.blogspot.com/2015/06/rooting-korg-kronos.html">rooting your Kronos</a>. In this file, the resource cost is stored for each engine and for each effect. The engine uses this file to constantly keep track of the current resource usage. As soon as there are not enough resources for all voices and effects that should be running, some algorithm carefully selects the least audible voices and drops them to make room for new (probably more audible voices).<br />
<br />
So, if you upgrade the CPU power of your synthesizer, you still need to patch CostProfile to get increased polyphony. I have prepared a CostProfile for my <a href="http://kronoshacker.blogspot.de/2016/02/more-power-for-kronos.html">hardware upgrade</a> <a href="https://mega.nz/#!mhwUwTgT!g-3VIrdRw7IpzorUXB6aDPOnnajwgzLbxZqlFMGip0I">here</a>. The proposed setup has enough power to archive 200 note polyphony <i>across all engines</i> and regardless of the active effects,<br />
<br />
Patching CostProfile to reduce the resource cost on the original main board (i.e. without additional CPU power) leads to some interesting behavior when too many voices are triggered: instead of stuttering and/or clicking, single voices drop out at random. This is because of a second mechanism called <i>EmergencyVoiceStealer </i>that seems to just drop one or more voices as a last measure to prevent a complete audio dropout. It looks like Korg spent a lot of effort to make sure there are no hard audio dropouts. Wow!<br />
<br />
Finally, there is a hard limit of 200 voices. This limit is probably a <span style="font-family: "courier new" , "courier" , monospace;">#define</span> in the synthesizer source code and was set arbitrarily by Korg.Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com0tag:blogger.com,1999:blog-3224718034299350223.post-44571743682548203472016-04-01T15:32:00.001-07:002016-05-05T14:42:30.325-07:00Precompiled kernel for the Kronos with XHCI supportIf you want to roll your own <a href="http://kronoshacker.blogspot.de/2016/02/more-power-for-kronos.html">hardware upgrade</a>, and don't want to dive into the details of compiling the Linux kernel, use this <a href="https://mega.nz/#!uxomRYDB!GqM3k20ordLjwi5SvSI1piB8AT2gUUYJtsuMxWHjNBU">precompiled Kronos-compatible kernel with XHCI support</a>.<br />
<br />
The kernel was compiled from the ingredients explained <a href="http://kronoshacker.blogspot.de/2015/09/compiling-linux-kernel-for-korg-kronos.html">here</a>. All patches applied to the <a href="https://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.32.11.tar.gz">Linux kernel 2.6.32.11</a> to compile the binary linked above are available <a href="https://mega.nz/#!S1x2gCAZ!QyIYNI51T7IbRiNMZZyUeEn1q1fUI_tFh9_YtCIvMLQ">here</a>.<br />
<br />
<u>Update (April 3rd 2016):</u><br />
<br />
<ul>
<li>Enabled IPv6 in kernel config (required for Intel NIC drivers)</li>
<li>Fixed problem with selecting OA.ko's heap memory size (<i>orig_mem_size</i>)</li>
<li>Driver modules for both Intel NICs on the Supermicro X11SSV-Q (Compiled from <a href="http://e1000e-3.3.3.tar/">e1000e-3.3.3.tar</a> and <a href="http://igb-5.3.4.4.tar.gz/">igb-5.3.4.4.tar.gz</a>).</li>
</ul>
<div>
<a href="https://mega.nz/#!e0oy3DAI!gCfhHPvDodNsdXka_xg-qSmE5aEonIMd5uuunVaJ7LQ">Linux Kernel</a></div>
<div>
<a href="https://mega.nz/#!C8ojnR7T!g6BD0SDUyt-fPNF4HV0jpe4tB1WSW4FXrd51ACRh9j8">Applied Patches</a></div>
<a href="https://mega.nz/#!GkglADIa!3t0cD1XUfNX3AqV_7MDbAz8tc95-P0Kwmxg_ucX5AD0">Driver Modules for Intel NICs on Supermicro X11SSV-Q</a> (extract to /lib/modules/2.6.32.11-korg)<br />
<br />
<u>Update (May 5th 2016):</u><br />
<div>
<br /></div>
<div>
<ul>
<li>Added magic value to register_cdrom() so that OA.ko still works properly if loadmod.ko was not loaded.</li>
</ul>
<div>
<a href="https://mega.nz/#!msk2wRJY!bcFXepmPW8MaNn5ZxS5Jf_FFXMWUTU75NQ2cQqxeJcA">Linux Kernel</a></div>
</div>
<div>
<a href="https://mega.nz/#!Gt1BBYob!UriomEfGymM8Ut-ynXkQRaAbVawHvLNuDmaB0wpm_0Y">Applied Patches</a></div>
<div>
<br /></div>
<br />
Have fun!Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com4tag:blogger.com,1999:blog-3224718034299350223.post-82627481394169734462016-03-28T13:08:00.000-07:002016-03-29T12:17:19.799-07:00Kronos Keybed CommunicationWhile most knobs, buttons and LEDs on the Kronos are connected to the <a href="http://kronoshacker.blogspot.de/2015/05/notes-from-inside-kronos-part-ii-omap.html">OMAP </a>, the Keybed with the two switches SW1/SW2 and the Pitch Bend Controller "Joystick" are connected to the PC Mainboard.<br />
<br />
The communication between Keybed and PC works via the PC's serial port COM1. This serial port is provided by a 16550A compatible UART inside the mainboard's Super-IO chip (<a href="http://drivers.portwell.com/CA_Manual/GPIO/w83627hf(GPIO)explanation.pdf">Winbond W83627</a>).<br />
<br />
The Keybed sends short (1-4 bytes) commands to the PC when keys are pressed or the analog joystick is moved.<br />
<br />
There are some oddities:<br />
<br />
<ul>
<li>The serial baud rate is 62500 bits/s.</li>
<li>The voltage levels between keybed and PC don't match: The PC is using RS232 levels (-10V/+10V) and the keybed is using TTL levels (0V/+5V). It is a strange thing that the connection even works under those circumstances.</li>
<li>The synthesizer kernel module (OA.ko) completely bypasses the kernel's serial driver. There is a minimal serial driver embedded in OA.ko</li>
<li>The UART baud rate generator is not used with it's default clock of 1.8461 MHz but with an alternative clock of 24 MHz. The baud rate generator clock is switched using the configuration registers of the Super-IO chip. This is also done by OA.ko.</li>
<li>OA.ko also reads the ChipID register of the W83627 and refuses to start if this specific Super-IO chip is not present.</li>
</ul>
<div>
<i>Update:</i> The Kronos 2 mainboard (<a href="http://www.asrock.com/download/e-catalog/IMB-140%20Series.pdf">ASRock IMB-140</a>) has a different Super-IO chip: the <a href="http://datasheet.octopart.com/NCT6627UD-Nuvoton-datasheet-11806968.pdf">NCT6627UD</a>. This is a brother of the <a href="http://download.siliconexpert.com/pdfs/2014/3/30/5/16/42/59/nuvto_/manual/nct6776f_nct6776d_datasheet_v1_2.pdf">NCT6776</a> which is used on my brand new <a href="http://www.supermicro.com/manuals/motherboard/Q170/MNL-1795.pdf">Supermicro X11SSV-Q</a>. The registers required to configure and use the first UART (COM1) are identical on both chips.</div>
<div>
<br /></div>
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com0tag:blogger.com,1999:blog-3224718034299350223.post-64233474484199531022016-02-29T09:24:00.001-08:002016-04-03T11:57:22.228-07:00More power for the KronosLet's assume I'd want to replace the Kronos mainboard with something a little more state-of-the-art. Maybe cost is not my main concern (Kronos was expensive enough, a few more spent bucks don't really matter).<br />
<br />
Here are some thoughts:<br />
<br />
<ul>
<li>Mainboard should be Mini-ITX to fit into the Kronos</li>
<li>CPU must support at least the Intel Atom instruction set (Kronos binaries are optimized for Atom)</li>
<li><strike>There is no point in having more than 4 GB RAM since OA.ko and the other proprietary kernel modules are 32 Bit only.</strike> <i>Update: 8 GB RAM will allow the kernel and userspace applications to live in high memory while OA can use almost all of the low memory. This will squeeze out 200-300 extra MBs of sample memory.</i></li>
<li>There is no point in having more than 2 CPU cores since the signal processing chain is optimized for 2 cores. Each CPU core should be as fast as possible to archive maximum signal processing performance.</li>
<li>Hardware needs at least one USB port to connect the NKS4 module (probably not hard).</li>
<li>Hardware needs a RS232 port to connect the Keybed, should be 16550 compatible (might be problematic, because most modern mainboards have no serial ports anymore)</li>
</ul>
<div>
Here is what I came up with:</div>
<div>
<ul>
<li>Mainboard: <a href="http://www.supermicro.com/products/motherboard/Core/Q170/X11SSV-Q.cfm">Supermicro X11SSV-Q</a> (Mini-ITX, has 2 serial ports - nice!)</li>
<li>CPU: <a href="http://ark.intel.com/products/90733/Intel-Core-i3-6320-Processor-4M-Cache-3_90-GHz">6th Generation Core i3-6320</a> (2 Cores, each with almost 4 GHz - <a href="http://cpu.userbenchmark.com/Compare/Intel-Core-i3-6320-vs-Intel-Atom-D525/3535vsm5666">comparison with the CPU inside the Kronos X</a>) </li>
<li>8 GB DDR3 Memory</li>
<li><a href="http://www.samsung.com/global/business/semiconductor/minisite/SSD/global/html/ssd850pro/overview.html">A fast SSD</a> (adjust size to personal taste)</li>
</ul>
<div>
Obstacles to overcome (updated again):</div>
<div>
<ul>
<li><strike>Skylake chipsets are XHCI only. XHCI-Driver in Kernel 2.6.32 does not support isochronous transfers.</strike> <i>Solved by backporting a newer XHCI-Driver.</i></li>
<li><strike>Memory map is not continuous. There are holes for ACPI NVS. Problematic with KORG's way of allocating the synthesizer's heap in ioremapped memory.</strike> <i>Solved by setting TOLUD (Top Of Low Usable DRAM) in BIOS settings to 3.5 GB. ACPI stuff is then out of the way.</i></li>
<li><strike>SuperIO-Driver embedded in OA.ko for serial port doesn't work (no keybed yet).</strike> <i><a href="http://kronoshacker.blogspot.de/2016/03/kronos-keybed-communication.html">Works with the latest OA.ko versions since SuperIO-Chip in Kronos 2 is similar to the one on the X11SSV-Q.</a> Connection cable inside Kronos needs some soldering since the supermicro board has a SUB-D connector and no pin-header for RS232.</i></li>
<li><strike>Kernel 2.6.32 does not support the ethernet MACs on the SX11SSV-Q. Not a real problem since the mainboard's ethernet connection is unused in the original Kronos design. Backporting a driver from a newer kernel should be possible.</strike> Intel provides drivers for both NICs that compile as modules against 2.6.32-11. Get prebuilt modules <a href="http://kronoshacker.blogspot.de/2016/04/precompiled-kernel-for-kronos-with-xhci.html">here</a>.</li>
</ul>
</div>
<div>
Results (updated):</div>
<div>
<ul>
<li>Kronos boot time < 20s</li>
<li><b>200 voice polyphony </b>accross all engines (even STR-1 and MS-20). </li>
<li>Total cost: ~ $520</li>
</ul>
</div>
<div>
<br /></div>
<div>
<br /></div>
</div>
Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com4tag:blogger.com,1999:blog-3224718034299350223.post-63143397601425822302016-02-28T04:23:00.000-08:002016-02-28T11:08:16.852-08:00Need help from experienced Kronos usersI am working on a way to increase the Kronos' performance (polyphony, simulatneous effects, boot time, etc.) significantly. To test the effectivity and reliability of my modifications, I need some test cases.<br />
<br />
Ideally, you could provide me configuration examples that drive the Kronos into it's limits. The limitations (e.g. voice stealing, missing effects, etc.) should be easy to hear. I cannot rely on the Kronos' performance meters.<br />
<br />
Please leave your examples in the comments or contact me via mail (<a href="mailto:kronoshacking@gmail.com">kronoshacking@gmail.com</a>).<br />
<br />
Sneak preview:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/s_vi/sErXyeK8oOc/default.jpg?sqp=CNyJzbYF&rs=AOn4CLADgZrpU_F5Je8sLChDvTLAEUBRhA" src="https://www.youtube.com/embed/sErXyeK8oOc?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
<br />
<br />
Thanks!Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com3tag:blogger.com,1999:blog-3224718034299350223.post-15441781601546163372015-09-12T13:07:00.000-07:002016-04-01T15:21:47.829-07:00Compiling a Linux kernel for the KORG KronosIt is not a secret that the KORG Kronos is running Linux with RTAI extensions.<br />
<br />
To understand how the Kronos software works and also for development of custom software, it would certainly be useful to be able to compile our own kernel that loads and runs KORG's proprietary modules and the Kronos software.<br />
<br />
The Version Magic String of the kernel distributed with the Kronos is "2.6.32.11-korg SMP preempt mod_unload ATOM". Futhermore, /proc/version tells us that the kernel was compiled using GCC 4.5.0.<br />
<br />
Let us have a look at the kernel log output related to RTAI:<br />
<pre><small>RTAI[hal]: <3.8.1> mounted over IPIPE-NOTHREADS 2.6-03.
RTAI[hal]: compiled with gcc version 4.5.0 (GCC) .
RTAI[hal]: mounted (IPIPE-NOTHREADS, IMMEDIATE (INTERNAL IRQs VECTORED), ISOL_CPUS_MASK: 0).
RTAI[malloc]: global heap size = 2097152 bytes, <BSD>.
RTAI[sched]: IMMEDIATE, MP, USER/KERNEL SPACE: <with RTAI OWN KTASKs>, <uses LINUX SYSCALLs>, kstacks pool size = 524288 bytes.
RTAI[sched]: hard timer type/freq = APIC/10416873(Hz); default timing: periodic; linear timed lists.
RTAI[sched]: Linux timer freq = 1000 (Hz), TimeBase freq = 1666440000 hz.
RTAI[sched]: timer setup = 999 ns, resched latency = 2944 ns.
</small></pre>
<br />
Since the <a href="https://www.kernel.org/">kernel</a> and <a href="https://www.rtai.org/">RTAI</a> are distributed under the GPL, KORG should deliver all sources necessary to build the kernel together with the compiled binary file (or include a written offer to send the sources on request).<br />
<br />
In <a href="https://shop.korg.com/uploads/Support/KRONOS_Update_and_Restore_E2.pdf">some documentation</a>, it says that the sources for GPLed code would ship on "Accessory Disk 2".
<br />
<br />
Since KORG is distributing the compiled Linux kernel online in the <a href="http://www.korg.de/uploads/tx_softwarecenter/KRONOS_X__Betriebssystem_v302.zip">Kronos Firmware Update</a> downloads, the Kernel sources should also be available online. I have not been able to find them, so this is probably a GPL violation.<br />
<br />
Since I have bought a Kronos, I also own the Accessory Disks and - indeed - on Accessory Disk 2, there are the sources for the Linux kernel version 2.6.32.11 and RTAI 3.8.1 together with two patches (scroll to the bottom of this post to see the patches in detail).<br />
<br />
If you do not have the Accessory Disks, the sources are of course also available for download:<br />
<br />
<ul>
<li><a href="https://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.32.11.tar.gz">Linux 2.6.32-11</a></li>
<li><a href="https://www.rtai.org/userfiles/downloads/RTAI/rtai-3.8.1.tar.bz2">RTAI 3.8.1</a></li>
</ul>
<br />
So, we should have everything to build our own kernel for the Kronos, right?<br />
<br />
Unfortunately, we are still missing one crucial part of information: the kernel configuration. Usually, this configuration is compiled into the kernel and available under /proc/config.gz, but KORG has disabled that feature. So, we need to find the kernel configuration by trial and error. It is important to get this right if you want to load the proprietary modules from KORG. The rely on sizes of data structures that may differ if the kernel configuration differs. In that case, the system will behave strange and/or just crash.<br />
<br />
Download the kernel configuration I have found by trial and error <a href="https://mega.nz/#!zhMGAaJa!F_NTPzonczFhOD5sXkW0yymDEnnG0GTc_mtBhXltlPw">here</a>. It is not perfect, but matches close enough.<br />
<br />
Now, we can boot our own kernel on the synthesizer. But something is strange - the proprietary modules will not load. loadmod.ko which is supposed to mount the encrypted loop filesystems with the synthesizer software just errors out. <a href="http://kronoshacker.blogspot.de/2015/05/about-linux-kernel-used-in-korg-kronos.html">I have already explained the reason for that behavior</a>.<br />
<br />
What KORG did here is a clear violation of the Linux kernel's software license - the <a href="https://www.gnu.org/licenses/old-licenses/gpl-2.0-faq.en.html">GPL</a>. All sources necessary to build the software must be made available with the distributed binary.<br />
<br />
To remedy this problem (I <b>really</b> want my own kernel on my Kronos), I have developed a set of patches that imitate the behaviour of the kernel distributed by KORG close enough, so that loadmod.ko works:<br />
<br />
<b><u>hal-linux-2.6.32.11-x86-2.6-03.patch</u></b><br />
This patch is taken directly and unmodified out of the RTAI archive (<a href="https://www.rtai.org/userfiles/downloads/RTAI/rtai-3.8.1.tar.bz2">RTAI 3.8.1</a>). It implements lots of changes and hooks that the RTAI modules need to integrate themselves into the kernel.<br />
<br />
<b><u>kronos-provide-meminfo.patch</u></b><br />
This patch exports two symbols (<i>orig_mem_size </i>and <i>orig_mem_start</i>). <i>orig_mem_size </i>is used by OA.ko (the actual synthesizer running in kernel mode) to determine how much memory is available on the system. This is important because OA.ko bypasses the kernel's dynamic memory management by ioremapping physical memory that is not used by the kernel.<br />
<br />
<b><u>kronos-cryptostuff.patch</u></b><br />
This patch implements some cryptographic helpers that KORG hid inside the generic cdrom driver. Those functions are used by loadmod.ko to calculate the keys required to the security IC. If they are not implemented properly in the kernel, loadmod.ko cannot read the secret per-device key that is used to decrypt the authorization file (<a href="http://kronoshacker.blogspot.com/2015/05/why-do-you-need-to-authorize-your.html">detailed explanation</a>).<br />
<br />
<u><b>kronos-export-do_generic_file_read.patch</b></u><br />
This patch exports do_generic_file_read() which is required by KORG's proprietary modules.<br />
<br />
<b><u>kronos-fix-kconfigs.patch</u></b><br />
This patch enables FB_DEFERED_IO which is required by KORG's framebuffer driver (the Kronos' screen is actually a framebuffer which is sent to the <a href="http://kronoshacker.blogspot.com/2015/05/notes-from-inside-kronos-part-ii-omap.html">OMAP</a> via USB). Also it enables support for the legacy firewire driver which is used by KORG, but masked by BROKEN in the kernel.<br />
<br />
<b><u>kronos-backport-xhci-driver.patch</u></b><br />
This patch backports the XHCI driver from a later kernel version as the experimental driver in 2.6.32.11 does not support isochronous transfers (which are required by the NKS4 board).<br />
The patch is required only if you want to <a href="http://kronoshacker.blogspot.de/2016/02/more-power-for-kronos.html">upgrade your synthesizer with a XHCI-only mainboard</a>.<br />
<br />
<b><u>kronos-increase-mlock-limit.patch</u></b><br />
Eva (the userspace part of the Kronos firmware responsible for the UI) communicates with OA.ko (the kernel part of the Kronos firmware) via mmapped memory ranges. This patch removes the kernel's default limit on mmapped memory to accommodate Eva's requirements.<br />
<br />
<b><u>kronos-kernel-config.patch</u></b><br />
This patch replaces the stock .config (kernel configuration file) with the kernel config I researched for the Kronos. There are some small additions (USB debugging, XHCI support) that do not forfeit binary compatibility between Korg's proprietary kernel modules and the compiled kernel.<br />
<br />
<b><u>KorgHwmonPermsPatch</u></b><br />
<i>This patch is actually published by Korg on their rescue CD.</i> Changes permissions for hardware sensor access.<br />
<br />
<b><u>load_module_patch</u></b><br />
<i>This patch is actually published by Korg on their rescue CD.</i> Patches module loading to trade memory usage for system startup time.<br />
<br />
<b>The latest set of patches (2016-04-02) is available <a href="https://mega.nz/#!S1x2gCAZ!QyIYNI51T7IbRiNMZZyUeEn1q1fUI_tFh9_YtCIvMLQ">here</a>.</b><br />
<br />
<b>Using those patches, you can now compile your own bzImage for the Kronos and use it as a starting point for your own development. Have fun!</b>Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com6tag:blogger.com,1999:blog-3224718034299350223.post-75905724315963306612015-09-03T14:13:00.002-07:002015-09-03T14:14:40.382-07:00Installing EXs using '/sbin/InstallEXs' form the command lineInstalling EXs files is not done by Eva (the userspace GUI) or OA (the kernel engine). Instead, Eva calls a helper binary: /sbin/InstallEXs
If you have installed the <a href="http://kronoshacker.blogspot.com/2015/06/rooting-korg-kronos.html">extensions for ssh access to your Kronos</a>, you can also run the helper directly. Use the following syntax:
<pre>
/sbin/InstallEXs -m VFAT -t <i>disk</i> -f <i>exins-file</i> -p <i>exs-directory</i>
</pre>
where
<i>disk</i> is 0 for install on first SSD or 1 for install on second SSD
<i>exins-file</i> is the name of the install info file (without path name)
<i>exs-directory</i> is the directory where the EXs files are located
<br>
An example:
<pre>
# /sbin/InstallEXs -m VFAT -t 0 -f EXs13.exsins -p /mnt/usbdisk0/EXs13/
</pre>
InstallEXs will now count to 100 (this is the percentage shown in the GUI). After the installation is finished, there is debug info in /tmp/installer_debug.
Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com5tag:blogger.com,1999:blog-3224718034299350223.post-28144861694454629492015-06-13T17:00:00.000-07:002015-06-13T17:03:10.535-07:00Rooting the KORG Kronos<div>
<b>Disclaimer:</b></div>
<div>
<br /></div>
<div>
<b>The following file is provided without any warranties. Backup all your settings before using it - maybe you'll need to reinstall your Kronos. You might even break it beyond repair (unlikely). Whatever happens - you are responsible - I am not liable in any way. Everything you do, you do on your own risk!</b></div>
<div>
<b><br /></b></div>
<div>
After the update, you can login into your Kronos as "root" and look around. The update also installs a busybox for your convinience. <a href="http://kronoshacker.blogspot.com/2015/06/filesystem-integrity-check-by-loadmodko.html">Be careful and do not change anything or you will likely end up with a non-bootable system.</a></div>
<div>
<br /></div>
<div>
Download: <a href="https://mega.nz/#!elcGybSR!uyDLcPcb87YMgcP3mwig-J5EVSGnxK5dJTml1-FtE30">https://mega.nz/#!elcGybSR!uyDLcPcb87YMgcP3mwig-J5EVSGnxK5dJTml1-FtE30</a></div>
<div>
<br /></div>
<div>
How to install:</div>
<div>
<ol>
<li>Make sure that your Kronos is updated to software version 3.0.2</li>
<li>Copy the files in the archive on a USB drive - just like a real update</li>
<li>Insert the USB drive into the Kronos and start the update process</li>
<li>Wait until the update is reported as successful</li>
<li>Power cycle the Kronos</li>
</ol>
<div>
How to access your Kronos:</div>
</div>
<div>
<ol>
<li>Connect a compatible USB network adapter (or use the mainboard's ethernet connector).</li>
<li>Set a FTP password in the settings</li>
<li>Make sure the network settings are correct and look up the IP address of your Kronos</li>
<li>Use ssh/scp/putty/winscp/... to connect as user "root" with the passwort set in the network settings as FTP password</li>
</ol>
<div>
Have fun!</div>
</div>
<div>
<br /></div>
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com12tag:blogger.com,1999:blog-3224718034299350223.post-62953961746355648372015-06-13T16:59:00.000-07:002015-06-13T16:59:28.850-07:00Filesystem Integrity Check by loadmod.koWhen the Kronos is booting, the contents of the following files is hashed (MD5). The MD5 sum is compared to a static value compiled into loadmod.ko. If the values do not match, loadmod.ko will bail out. Do not change the files in this list on your Kronos or it will not boot anymore!<br />
<br />
<pre>/
/bin
/bin/sync
/bin/awk
/bin/touch
/bin/grep
/bin/test
/bin/ls
/bin/mount
/bin/cut
/bin/setterm
/bin/gzip
/bin/echo
/bin/false
/bin/dc
/bin/stat
/bin/chown
/bin/mv
/bin/bash
/bin/bar
/bin/dd
/bin/cp
/bin/RunGrub.sh
/bin/env
/bin/tar
/bin/fanctrld
/bin/usleep
/bin/sed
/bin/vmstat
/bin/kill
/bin/gawk
/bin/ipcalc
/bin/sleep
/bin/umount
/bin/hostname
/bin/df
/bin/ShowReauthScreen
/bin/expr
/bin/date
/bin/vi
/bin/rm
/bin/mkdir
/bin/chmod
/bin/true
/bin/cat
/bin/sh
/bin/uname
/sbin
/sbin/ifconfig
/sbin/OmapNKS4Module.ko
/sbin/init
/sbin/insmod.static
/sbin/loadoa
/sbin/e2fsck
/sbin/hwclock
/sbin/dhclient-script
/sbin/insmod
/sbin/killall5
/sbin/MIDID
/sbin/GetPubIdMod.ko
/sbin/dosfsck
/sbin/hdparm
/sbin/modprobe
/sbin/shutdown
/sbin/grub
/sbin/UpdateOS
/sbin/mkswap
/sbin/iptables
/sbin/sysctl
/sbin/ip
/sbin/ifup.lite
/sbin/loadmod.ko
/sbin/tune2fs
/sbin/arping
/sbin/rmmod
/sbin/poweroff
/sbin/losetup
/sbin/runlevel
/sbin/reboot
/sbin/swapoff
/sbin/mke2fs
/sbin/ifdown.lite
/sbin/swapon
/sbin/halt
/sbin/pidof
/sbin/OmapVideoModule.ko
/sbin/STGEnabler.ko
/etc
/etc/sysconfig
/etc/sysconfig/network
/etc/sysconfig/network-scripts
/etc/sysconfig/network-scripts/ifcfg-eth0
/etc/sysconfig/network-scripts/ifcfg-lo
/etc/modprobe.conf
/etc/sysctl.conf
/etc/OA.rc
/etc/ld.so.conf
/etc/mtab
/etc/OA.si
/etc/inittab
/etc/fstab
/sys
/korg
/korg/ro
/korg/Eva
/korg/rw
/korg/Mod
/tmp
/mnt
/var
/usr
/usr/realtime
/usr/realtime/modules
/usr/realtime/modules/rtai_hal.ko
/usr/realtime/modules/rtai_fifos.ko
/usr/realtime/modules/rtai_sched.ko
/usr/realtime/modules/rtai_sem.ko
/usr/realtime/modules/rtai_ndbg.ko
/usr/realtime/modules/rtai_smp.ko
/usr/share
/usr/share/fonts
/usr/share/fonts/truetype
/usr/share/fonts/truetype/Arialbd.ttf
/usr/share/fonts/truetype/Geneva.ttf
/usr/share/fonts/truetype/Arial.ttf
/usr/share/fonts/truetype/Geneva_Bold.ttf
/usr/share/terminfo
/usr/share/terminfo/a
/usr/share/terminfo/a/ansi
/usr/share/terminfo/l
/usr/share/terminfo/l/linux
/boot
/dev
/lib
/lib/libcrypto.so.6
/lib/libresolv.so.2
/lib/modules
/lib/modules/2.6.32.11-korg
/lib/modules/2.6.32.11-korg/modules.pcimap
/lib/modules/2.6.32.11-korg/modules.dep
/lib/modules/2.6.32.11-korg/modules.inputmap
/lib/modules/2.6.32.11-korg/modules.ofmap
/lib/modules/2.6.32.11-korg/modules.ieee1394map
/lib/modules/2.6.32.11-korg/modules.usbmap
/lib/modules/2.6.32.11-korg/kernel
/lib/modules/2.6.32.11-korg/kernel/drivers
/lib/modules/2.6.32.11-korg/kernel/drivers/net
/lib/modules/2.6.32.11-korg/kernel/drivers/net/mii.ko
/lib/modules/2.6.32.11-korg/kernel/drivers/net/r8169.ko
/lib/modules/2.6.32.11-korg/kernel/drivers/scsi
/lib/modules/2.6.32.11-korg/kernel/drivers/scsi/scsi_wait_scan.ko
/lib/modules/2.6.32.11-korg/modules.isapnpmap
/lib/modules/2.6.32.11-korg/modules.ccwmap
/lib/modules/2.6.32.11-korg/source
/lib/modules/2.6.32.11-korg/modules.order
/lib/modules/2.6.32.11-korg/modules.seriomap
/lib/modules/2.6.32.11-korg/build
/lib/modules/2.6.32.11-korg/modules.symbols
/lib/modules/2.6.32.11-korg/modules.alias
/lib/libcom_err.so.2
/lib/ld-linux.so.2
/lib/libfreetype.so.6
/lib/libtinfo.so.5
/lib/libsepol.so.1
/lib/libext2fs.so.2
/lib/libattr.so.1
/lib/libdl.so.2
/lib/libpcre.so.0
/lib/libgssapi_krb5.so.2
/lib/libaudit.so.0
/lib/libpthread.so.0
/lib/libe2p.so.2
/lib/libstdc++.so.6
/lib/libgmp.so.10
/lib/libkrb5support.so.0
/lib/libselinux.so.1
/lib/librt.so.1
/lib/libz.so.1
/lib/libsysfs.so.2
/lib/libkrb5.so.3
/lib/libc.so.6
/lib/libblkid.so.1
/lib/libm.so.6
/lib/libncurses.so.5
/lib/libpopt.so.0
/lib/libssl.so.6
/lib/libkeyutils.so.1
/lib/libproc-3.2.7.so
/lib/libk5crypto.so.3
/lib/libuuid.so.1
/lib/libacl.so.1
/lib/libgcc_s.so.1
/lib/libdevmapper.so.1.02
/proc
</pre>
Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com0tag:blogger.com,1999:blog-3224718034299350223.post-24680056444112423902015-06-13T14:55:00.002-07:002015-06-13T16:30:46.877-07:00The anatomy of a Kronos firmware update The ZIP file contains some files that should be copied to a USB stick which is to be inserted into the Kronos. Let's have a look at the files:<br />
<br />
<b>bc</b><br />
X86 32 Bit Linux Binary - a calculator<br />
<br />
<b>md5sum</b><br />
X86 32 Bit Linux Binary - calculates MD5 checksums of files<br />
<br />
<b>DisplayUpdaterMessage</b><br />
X86 32 Bit Linux Binary - opens a linux frame buffer device (/dev/fb1) that represents the Kronos' display (managed by the OMAP).<br />
<br />
<b>install.info</b><br />
Holds information about the update itself. This is the first file that the Kronos reads when updating. Contains references to 3 other files (KRONOS_Update_3_0_2.tar.gz, pretar.sh, posttar.sh) and a signature.<br />
<br />
The signature is the SHA1 of the following data (concatenated in the mentioned order):<br />
<br />
<ul>
<li>the contents of the pretar script (if given in the install.info)</li>
<li>the contents of the posttar script (if given in the install.info)</li>
<li>the following 16 "magic bytes": 13h, D0h, AFh, EFh, E0h, 3Ch, 9Bh, 92h, 16h, 2Fh, AEh, FFh, 77h, 53h, 55h, E1h</li>
</ul>
<br />
The updater (UpdateOS) will only accept the update if the signature in install.info is correct.<br />
<br />
<b>pretar.sh</b><br />
A shell script (bash) that is called in the upgrade progress before the actual firmware is extracted. This script does the following things:<br />
<br />
<br />
<ul>
<li>Call DisplayUpdaterMessage to show "Verifying install media..."</li>
<li>Call md5sum to calculate the MD5-Checksum of "KRONOS_Update_3_0_2.tar.gz" and compare it to a known value</li>
<li>Call md5sum to calculate the MD5-Checksum of "DisplayUpdaterMessage" and compare it to a known value (pointless since DisplayUpdaterMessage has already been called before)</li>
<li>Call md5sum to calculate the MD5-Checksum of "bc" and compare it to a known value</li>
<li>Make sure (via kill and kill -9) that the following processes are not running: vsftpd, avahi-daemon, messagebus, ifplugd</li>
<li>Make sure that the date is at least 1.12.2014</li>
</ul>
<br />
<b>posttar.sh</b><br />
A shell script (bash) that is called in the upgrade progress after the actual firmware is extracted. This script checks all extracted files' checkusms against the checksums stored in "KRONOS_Update_3_0_2.csum". It displays a progress bar by using "bc" to calulate the percentage of finished files and writing it to "writing to /proc/OmapNKS4ProgressBar"<br />
<br />
<b>KRONOS_Update_3_0_2.tar.gz</b><br />
Contains the Kronos' root file system. This is the acutal firmware update. I will look into it and explain it's contents later in this post.<br />
<br />
<b>KRONOS_Update_3_0_2.csum</b><br />
Contains checksums for all files in "KRONOS_Update_3_0_2.tar.gz". Used by posttar.sh to make sure that the firmware update was properly installed<br />
<br />Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com0tag:blogger.com,1999:blog-3224718034299350223.post-16698947909124815332015-06-03T16:05:00.000-07:002015-06-03T16:05:08.003-07:00And one more GPL violation: vsftpdThe FTP service on the KORG Kronos is actually a vsftpd. Parts of the configuration have been patched into the binary. Here is part of the output of "strings vsftpd":<br />
<pre>/SSD1
/korg/rw/HD%s/%s
/SSD2
/korg/rw2/HD%s/%s
/korg/ftp/%s
/korg/rw/HD
</pre>
According to vsftpd's <a href="https://security.appspot.com/vsftpd.html">website</a>, vsftp is licensed under the GPL. However, the changed sources for vsftpd are not provided on the recovery DVD. There is also no written offer to deliver the sources on request. This makes vsftpd the third GPL violation inside the Kronos...<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com0tag:blogger.com,1999:blog-3224718034299350223.post-32306535586226769952015-05-29T17:06:00.001-07:002016-01-05T15:58:49.567-08:00Another GPL violation: loadmod.ko / STGGmp.koThe KORG Kronos software contains yet another GPL violation in the proprietary kernel module <b>loadmod.ko </b>that is delivered with the recovery images on the <a href="http://www.korg.com/us/products/synthesizers/kronos/">support page</a>.<br />
<br />
The module is statically linked with the <a href="https://gmplib.org/">gmplib</a> that is distributed under GPL/LGPL dual licensing. KORG does not provide the source code for loadmod.ko as required by the GPL.<br />
<br />
In newer firmware versions, gmplib is no longer included in loadmod.ko, but in a different module called <b>STGGmp.ko</b>. So it looks like KORG is aware of the licensing problem but does not fix their old binaries.<br />
<br />
<i>Update: </i>The statically linking version of loadmod.ko was not present in firmware version 3.0.2. It was then again distributed with firmware version 3.0.3. On 2015-12-25 firmware version 3.0.3 was replaced with a firmware that is internally branded as 3.0.3B - the only change between 3.0.3 and 3.0.3B was to replace the statically linking loadmod.ko with the dynamically linking version.<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com0tag:blogger.com,1999:blog-3224718034299350223.post-50427272045679716632015-05-29T13:18:00.002-07:002015-05-29T13:18:45.856-07:00What does /sbin/loadoa do?<pre>
=== increment progress ===
fopen("/proc/progress")
fscanf("%d")
add 1
fprintf("%d")
fflush()
fclose()
=== load modules (1st batch) ===
/sbin/insmod /usr/realtime/modules/rtai_hal.ko
/sbin/insmod /usr/realtime/modules/rtai_smp.ko
/sbin/insmod /usr/realtime/modules/rtai_sem.ko
/sbin/insmod /usr/realtime/modules/rtai_ndbg.ko
/sbin/insmod /usr/realtime/modules/rtai_fifos.ko
/sbin/insmod /sbin/STGEnabler.ko
/sbin/insmod /sbin/STGGmp.ko
=== set smp affinity ===
search "ehci_hcd" in /proc/interrupts
write '4' to "/proc/irq/%d/smp_affinity"
=== load modules (2nd batch) ===
/sbin/insmod /sbin/OmapNKS4Module.ko
/sbin/insmod /sbin/OmapVideoModule.ko
/sbin/insmod /sbin/GetPubIdMod.ko
/sbin/insmod /sbin/loadmod.ko
=== check if STG modules are alive ===
open /tmp/stgStatus
check if value is '1'
=== mount crypto FS (1st batch) ===
/bin/mount -n -t ignoreType ignoreDev /korg/rw/PCM/WaveMotion > /dev/null
/bin/mount -n -t ignoreType ignoreDev /korg/Mod > /dev/null
=== load modules (3rd batch, from cryptoFS) ===
/sbin/insmod /korg/Mod/KorgUsbAudioDriver.ko
/sbin/insmod /sbin/USBMidiAccessory.ko
=== fork ===
fork()
=> child stays and will update /proc/progress
parent writes progress child PID to "/tmp/progress.pid":
fopen("/tmp/progress.pid")
fprintf("%d")
fflush()
fclose()
=== mount 2nd disk if present ===
call "Has2ndInternalDisk":
ls /sys/block | grep sdb
udevinfo -a -p /sys/block/sdb | grep DRIVERS | grep usb
mount -t ext3 -o commit=1,noatime /dev/sdb1 /korg/rw2
mv -f /korg/rw2/Options/* /korg/rw/Options
mount --bind /korg/rw/HD /korg/ftp/SSD1
=== load modules (4th bath, from cryptoFS) ===
/sbin/insmod /korg/Mod/OA.ko Has2ndInternalDisk=?
=== mount more stuff ===
/bin/umount -n /korg/Mod
/bin/mount -n -t ignoreType ignoreDev /korg/Eva > /dev/null
/bin/mount -n -t ignoreType ignoreDev /korg/rw/PCM/WaveMotion > /dev/null
=== run fanctrld ===
/bin/fanctrld > /dev/null
=== run Eva ===
/korg/Eva/Eva > /dev/null
</pre>
Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com0tag:blogger.com,1999:blog-3224718034299350223.post-38651267258481877492015-05-29T07:32:00.003-07:002015-05-29T07:32:49.621-07:00Why do you need to "authorize" your Synthesizer?When you "authorize" your Kronos (for example after recovery), the authorization file actually contains the crypto keys necessary to access proprietary kernel modules, the actual synthesizer software and some "WaveMotion" data.<br />
<br />
The keys are not there in plain, but encrypted with another key that is stored in the Kronos' security chip. The encryption key is probably different for each device so that one authorization file is only valid for one synth.<br />
<br />
To access the security chip, you need a different key (see authorization and encryption in the AT88's datasheet) which is calculated from the Public ID and some magic numbers in the driver module.<br />
<br />
So, when you "authorize" your Kronos, you get the crypto keys to access to the synthesizer software on it.Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com0tag:blogger.com,1999:blog-3224718034299350223.post-42856510972154555872015-05-28T09:28:00.004-07:002015-07-09T15:21:46.333-07:00Notes from inside the Kronos - Part II: The OMAP (NKS4)<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5feLbQALVPdmIRJzQeVW7a7MsDiUXi9HRQE-fmvqtP3QZHneTb8KU7sZXeQDUOB8vEjG44DMawG-j9-2cEquCS_WDd36rKCqqwTj94RAQQ1uFZ43FIQCS2gliR3OCbbpqPSJt3Yeeyw4/s1600/KronosOMAP.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="316" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5feLbQALVPdmIRJzQeVW7a7MsDiUXi9HRQE-fmvqtP3QZHneTb8KU7sZXeQDUOB8vEjG44DMawG-j9-2cEquCS_WDd36rKCqqwTj94RAQQ1uFZ43FIQCS2gliR3OCbbpqPSJt3Yeeyw4/s320/KronosOMAP.jpg" width="320" /></a></div>
<br />
<br />
The <a href="http://www.ti.com/lit/ds/symlink/am1806.pdf">AM1806B</a> is connected to the Kronos' PC as a USB 2.0 Device. It is used as an I/O helper for the PC with (at least) the following tasks:<br />
<ul>
<li>LCD Display Interface - the OMAP exports it's display interface via USB to the PC where one of KORG's proprietary drivers installs it as a framebuffer device. So the contents you see on the display are (except for the startup screen) rendered by the PC and sent to the OMAP via USB.</li>
<li>Touch Screen Interface</li>
<li>Audio Interface(s) <strike>and audio mixing / routing</strike></li>
<li>MIDI Interfaces(s)</li>
<li>Interface to the PSOC which handles the mechanical user interface </li>
<li>Interface to the <a href="http://kronoshacker.blogspot.com/2015/05/notes-from-inside-kronos-part-i.html">Security IC</a> </li>
<li>USB Device Interface (The Kronos' USB Host Ports are provided by the Intel Mainboard)</li>
<li><strike>Effects processing. Probably the OMAP handles the IFX and MFX (to be confirmed...)</strike> there is no effect processing on the OMAP. All effect processing is done on the PC.</li>
</ul>
So, one could say, that the OMAP is a very fancy sound card for the Kronos' Intel mainboard - nothing more - nothing less. There is a <a href="http://www.gearzonemusic.com/Kronos/KRONOS_Sub-System_win_604.zip">software update</a> available from KORG which probably contains the OMAPs firmware.<br />
<br />
The OMAP is often referred as "NKS4".<br />
<br />
<br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com0tag:blogger.com,1999:blog-3224718034299350223.post-43291592034800752632015-05-27T14:34:00.000-07:002015-05-28T01:46:28.054-07:00Warranty void<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5MlcBJmU7F58geeCTdMTrXP81rmu0VwHnil-ZHQHjjL1oUb_bvJMRr3AU6-OkTvXoKODrzycHBKXTtwVSOIsFZEdNd4E1NOELqWJ9v6BdKqagTwin1c-TTfPGIb34wQ2Z_wT7kyVbINk/s1600/KronosUSB1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="114" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5MlcBJmU7F58geeCTdMTrXP81rmu0VwHnil-ZHQHjjL1oUb_bvJMRr3AU6-OkTvXoKODrzycHBKXTtwVSOIsFZEdNd4E1NOELqWJ9v6BdKqagTwin1c-TTfPGIb34wQ2Z_wT7kyVbINk/s320/KronosUSB1.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKldQJw72m5XhbntY08boRecVKZwJfP_9BHC85S8HyXDfXj-jXDX3bRFEUKo0INn4WjOakzbnLwwuvQ8CELq18HOUEhvobmKtriAa1MNURYShoC1VeUev4OhUIzMZbRh4z7GrfqtdkzUI/s1600/KronosUSB2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="114" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKldQJw72m5XhbntY08boRecVKZwJfP_9BHC85S8HyXDfXj-jXDX3bRFEUKo0INn4WjOakzbnLwwuvQ8CELq18HOUEhvobmKtriAa1MNURYShoC1VeUev4OhUIzMZbRh4z7GrfqtdkzUI/s320/KronosUSB2.jpg" width="320" /></a></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjbz5qvbS-G8a2U-MvPlg0EaSNai4zv8aImr2dExsxfXiKz9LNgMmvalsGFHb0BGsiAX6VRJRL_ROptEjqyPpbBT-JKM1GS2Jd73V3WrLJtK4Su6FZhqYekFGj3SxwQ1hvXFT7EqBVFps/s1600/KronosUSB3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="114" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjbz5qvbS-G8a2U-MvPlg0EaSNai4zv8aImr2dExsxfXiKz9LNgMmvalsGFHb0BGsiAX6VRJRL_ROptEjqyPpbBT-JKM1GS2Jd73V3WrLJtK4Su6FZhqYekFGj3SxwQ1hvXFT7EqBVFps/s320/KronosUSB3.jpg" width="320" /></a></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8zZu8QzTm8q5YrivGVrFeDgomKKxM0RDfRTZQg818kxLXgk02blIVeuatHNBf_wt_ayN_Ho-9E_zgg2A6zjbfB1i_K3RK4-P8Ar_saklwNurx8SeKmkCrk_KqsKJKB_7UTO5pj251dn0/s1600/KronosEth1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="114" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8zZu8QzTm8q5YrivGVrFeDgomKKxM0RDfRTZQg818kxLXgk02blIVeuatHNBf_wt_ayN_Ho-9E_zgg2A6zjbfB1i_K3RK4-P8Ar_saklwNurx8SeKmkCrk_KqsKJKB_7UTO5pj251dn0/s320/KronosEth1.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiF-jhyphenhyphenbGv7Ce74NtxkytBX5ucMJALwyH8r5PBbD9AFMr_m6yRyKfAXUKCT3Npdr3hr2rf8Q4wyHov7k0RylTGCNVJ2WTPJlxIfPprL5t_OaEneIIQYcTdMnoXiW09HIceMdGghRMhUxaU/s1600/KronosUSBEth.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="114" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiF-jhyphenhyphenbGv7Ce74NtxkytBX5ucMJALwyH8r5PBbD9AFMr_m6yRyKfAXUKCT3Npdr3hr2rf8Q4wyHov7k0RylTGCNVJ2WTPJlxIfPprL5t_OaEneIIQYcTdMnoXiW09HIceMdGghRMhUxaU/s320/KronosUSBEth.jpg" width="320" /></a></div>
<div>
<br />
The Ethernet port on the Kronos' mainboard is actually functional. So it's possible to add a extra Ethernet port to the Kronos without using a USB<->Ethernet adapter.<br />
</div>
Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com0tag:blogger.com,1999:blog-3224718034299350223.post-87033693506144038352015-05-27T11:56:00.000-07:002015-05-27T11:56:07.935-07:00Notes from inside the Kronos - Part I: The security IC<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgu95WQxkm84e6F6uejoy9jnTGpoFPAMGl3pDxT8U4JUpBnr8DZOAMYfWBkpQgoewpBhEgAkAIy2vY9PamZ0BdWKSNugJQolzpzl0xQwIGFQ6C4JgljfiR6t3YCHjTD66l5AZaMp0SSbj8/s1600/KronosSecurity.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="254" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgu95WQxkm84e6F6uejoy9jnTGpoFPAMGl3pDxT8U4JUpBnr8DZOAMYfWBkpQgoewpBhEgAkAIy2vY9PamZ0BdWKSNugJQolzpzl0xQwIGFQ6C4JgljfiR6t3YCHjTD66l5AZaMp0SSbj8/s320/KronosSecurity.jpg" width="320" /></a></div>
<br />
<br />
<br />
<br />
<br />
The <a href="http://www.atmel.com/Images/Atmel-5202S-CryptoMem-AT88SC0204CA-Datasheet-Summary.pdf">AT88SC0204CA</a> is used for at least the following purposes:<br />
<br />
<ol>
<li>It defines the Kronos' Public ID</li>
<li>It holds (part of) the AES keys that are used to encrypt the synthesizer software</li>
<li>It is used to authenticate EXs</li>
</ol>
The chip is connected to the OMAP via I2C and can be accessed by the Linux kernel via the USB connection between OMAP and PC. OmapNKS4Module.ko implements functions to access the security IC.<br />
<br />Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com1tag:blogger.com,1999:blog-3224718034299350223.post-3763596659536262902015-05-26T15:59:00.000-07:002015-07-09T15:22:41.374-07:00About the Linux kernel used in KORG KronosIt is well known that KORG's Kronos Synthesizer uses a (more or less) standard Intel Mainboard/CPU for a large part of its functionality. The Intel CPU is running the Application Software with the User Interface, handles Storage and USB Host / Network connections, generates the synthesizer voices and does all the effects. Inside the Kronos, there is also a OMAP CPU that connects most of the audio related I/O Ports (Analog Audio, MIDI, USB Device). This OMAP CPU is connected to the PC as an USB device.<br />
<br />
If we look at the software running on the Intel CPU, it becomes pretty clear that there is a Linux Kernel with RTAI realtime extensions. KORG provides the source code for the kernel and the RTAI extensions on the recovery discs as required by the GPL. However, if you try to replace the Linux Kernel with a kernel you compiled yourself, this will not work. To prevent people from modifying their Kronos, KORG did some subtle changes to the Linux kernel that make it impossible to load the driver modules for the OMAP CPU into a kernel that was not compiled by KORG. <br />
<br />
The first problem we have do deal with when replacing the kernel is that KORG does not provide the kernel configuration file. It is also not included in the original kernel. This might be regarded as a violation of the GPL since the kernel configuration is clearly a source file required to build the kernel. Futhermore, KORG has modified specific functions (register_cdrom() and init_cdrom_command()) to provide some kind of Challenge/Response authentication mechanism. The driver modules call those modified functions and expect a certain behaviour that only the kernel compiled by KORG exposes.<br />
<br />
<b>This is a clear GPL violation since the modifications done to the kernel are not provided with the binary.</b><br />
<b><br /></b>
The register_cdrom()/init_cdrom_command() mechanism works like this:<br />
<br />
<ol>
<li>Proprietary module calls <a href="http://lxr.linux.no/linux+v2.6.32.11/drivers/cdrom/cdrom.c#L387">register_cdrom()</a> with a magic number in <a href="http://lxr.linux.no/linux+v2.6.32.11/include/linux/cdrom.h#L937">cdrom_device_info</a>.for_data to identify itself to the kernel</li>
<li>register_cdrom() writes a pointer to a statically allocated <a href="http://lxr.linux.no/linux+v2.6.32.11/include/linux/cdrom.h#L281">struct cdrom_generic_command</a> into <a href="http://lxr.linux.no/linux+v2.6.32.11/include/linux/cdrom.h#L937">cdrom_device_info</a>.handle (acutally, the pointer is obfuscated by some bitshifting and offset adding) and returns the (otherwise unused) errorcode -42</li>
<li>Proprietary module inserts another magic number into the *(<a href="http://lxr.linux.no/linux+v2.6.32.11/include/linux/cdrom.h#L281">struct cdrom_generic_command</a>) retrieved in step 2 and calls <a href="http://lxr.linux.no/linux+v2.6.32.11/drivers/cdrom/cdrom.c#L1506">init_cdrom_command()</a> with that pointer as argument</li>
<li><a href="http://lxr.linux.no/linux+v2.6.32.11/drivers/cdrom/cdrom.c#L1506">init_cdrom_command()</a> does a lot of obfuscation, looks up some magic values in static arrays and returns some values by writing them into the static <a href="http://lxr.linux.no/linux+v2.6.32.11/include/linux/cdrom.h#L281">struct cdrom_generic_command</a></li>
</ol>
<div>
This mechanism is used mainly by loadmod.ko - a proprietary module that is responsible for software update and software encryption. The module refuses to load if register_cdrom()/init_cdrom_command() are not implemented as described above.It also uses the scrambling done in init_cdrom_command() to deobfuscte the keys required to loop-mount Eva.img, Mod.img and WaveMotion.img after reading those keys from the security IC.</div>
<div>
<br /></div>
<br />
<b><br /></b>
<b><br /></b>Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com4tag:blogger.com,1999:blog-3224718034299350223.post-34830601973319985412015-05-21T14:21:00.001-07:002015-05-25T04:34:04.147-07:00NKS4 Statup Communication<table>
<tr><th>Request</th><th>Response</th><th>Comment</th><td>Module</th></tr>
<tr><td>0x0000ee00</td><td>0x00006600</td><td>Communication Check</td><td>OmapNKS4Module.ko</td></tr>
<tr><td>0x0000f000</td><td>0x02647000</td><td>Get OMAP/PSOC Versions</td><td>OmapNKS4Module.ko</td></tr>
<tr><td>0x0000f101</td><td>0x00007101</td><td>Read Port Configuration</td><td>OmapNKS4Module.ko</td></tr>
<tr><td>0x003f9001</td><td></td><td>Set Number of Analog Inputs</td><td>OmapNKS4Module.ko</td></tr>
<tr><td>0x2800b001</td><td></td><td>Set All Analog Input Filter</td><td>OmapNKS4Module.ko</td></tr>
<tr><td>0x00037000</td><td></td><td>Set Number of LEDs</td><td>OmapNKS4Module.ko</td></tr>
<tr><td>0x00c08101</td><td></td><td>Configure Rotary Encoders</td><td>OmapNKS4Module.ko</td></tr>
<tr><td>0x00008301</td><td></td><td>Configure Rotary Encoders</td><td>OmapNKS4Module.ko</td></tr>
<tr><td>0x00018201</td><td></td><td>Configure Rotary Encoders</td><td>OmapNKS4Module.ko</td></tr>
<tr><td>0x00648000</td><td></td><td>Set Rotary Encoder Sample Speed</td><td>OmapNKS4Module.ko</td></tr>
<tr><td>0x004e0000</td><td></td><td></td></tr>
<tr><td>0x2800b001</td><td></td><td></td></tr>
</table>Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com0tag:blogger.com,1999:blog-3224718034299350223.post-64444241488383024912015-05-21T14:12:00.001-07:002015-05-21T14:12:22.241-07:00NKS4 USB Descriptor<pre>
ID 0944:1005 KORG, Inc.
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 239 Miscellaneous Device
bDeviceSubClass 2 ?
bDeviceProtocol 1 Interface Association
bMaxPacketSize0 64
idVendor 0x0944 KORG, Inc.
idProduct 0x1005
bcdDevice 1.00
iManufacturer 1 KORG INC.
iProduct 2 KRONOS
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 351
bNumInterfaces 6
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x40
(Missing must-be-set bit!)
Self Powered
MaxPower 0mA
Interface Association:
bLength 8
bDescriptorType 11
bFirstInterface 0
bInterfaceCount 3
bFunctionClass 1 Audio
bFunctionSubClass 0
bFunctionProtocol 0
iFunction 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 1 Control Device
bInterfaceProtocol 0
iInterface 0
AudioControl Interface Descriptor:
bLength 10
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdADC 1.00
wTotalLength 52
bInCollection 2
baInterfaceNr( 0) 1
baInterfaceNr( 1) 2
AudioControl Interface Descriptor:
bLength 12
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 1
wTerminalType 0x0101 USB Streaming
bAssocTerminal 0
bNrChannels 6
wChannelConfig 0x0003
Left Front (L)
Right Front (R)
iChannelNames 0
iTerminal 0
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 2
wTerminalType 0x0302 Headphones
bAssocTerminal 0
bSourceID 1
iTerminal 0
AudioControl Interface Descriptor:
bLength 12
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 3
wTerminalType 0x0713 Synthesizer
bAssocTerminal 0
bNrChannels 6
wChannelConfig 0x0003
Left Front (L)
Right Front (R)
iChannelNames 0
iTerminal 0
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 4
wTerminalType 0x0101 USB Streaming
bAssocTerminal 0
bSourceID 3
iTerminal 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 3 AUDIO OUT
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 1
bNumEndpoints 2
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 3 AUDIO OUT
AudioStreaming Interface Descriptor:
bLength 7
bDescriptorType 36
bDescriptorSubtype 1 (AS_GENERAL)
bTerminalLink 1
bDelay 0 frames
wFormatTag 1 PCM
AudioStreaming Interface Descriptor:
bLength 11
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bNrChannels 6
bSubframeSize 3
bBitResolution 24
bSamFreqType 1 Discrete
tSamFreq[ 0] 48000
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0090 1x 144 bytes
bInterval 1
bRefresh 0
bSynchAddress 129
AudioControl Endpoint Descriptor:
bLength 7
bDescriptorType 37
bDescriptorSubtype 1 (EP_GENERAL)
bmAttributes 0x00
bLockDelayUnits 0 Undefined
wLockDelay 0 Undefined
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 1
Transfer Type Isochronous
Synch Type None
Usage Type Data
wMaxPacketSize 0x0003 1x 3 bytes
bInterval 1
bRefresh 6
bSynchAddress 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 4 AUDIO IN
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 1
bNumEndpoints 1
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 4 AUDIO IN
AudioStreaming Interface Descriptor:
bLength 7
bDescriptorType 36
bDescriptorSubtype 1 (AS_GENERAL)
bTerminalLink 4
bDelay 0 frames
wFormatTag 1 PCM
AudioStreaming Interface Descriptor:
bLength 11
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bNrChannels 6
bSubframeSize 3
bBitResolution 24
bSamFreqType 1 Discrete
tSamFreq[ 0] 48000
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0090 1x 144 bytes
bInterval 1
bRefresh 0
bSynchAddress 0
AudioControl Endpoint Descriptor:
bLength 7
bDescriptorType 37
bDescriptorSubtype 1 (EP_GENERAL)
bmAttributes 0x00
bLockDelayUnits 0 Undefined
wLockDelay 0 Undefined
Interface Association:
bLength 8
bDescriptorType 11
bFirstInterface 3
bInterfaceCount 1
bFunctionClass 255 Vendor Specific Class
bFunctionSubClass 0
bFunctionProtocol 0
iFunction 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 0
iInterface 5 NKS
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0080 1x 128 bytes
bInterval 4
Interface Association:
bLength 8
bDescriptorType 11
bFirstInterface 4
bInterfaceCount 2
bFunctionClass 1 Audio
bFunctionSubClass 0
bFunctionProtocol 0
iFunction 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 4
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 1 Control Device
bInterfaceProtocol 0
iInterface 0
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdADC 1.00
wTotalLength 9
bInCollection 1
baInterfaceNr( 0) 5
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 5
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 1 Audio
bInterfaceSubClass 3 MIDI Streaming
bInterfaceProtocol 0
iInterface 6 LEGACY MIDI
MIDIStreaming Interface Descriptor:
bLength 7
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdADC 1.00
wTotalLength 52
MIDIStreaming Interface Descriptor:
bLength 6
bDescriptorType 36
bDescriptorSubtype 2 (MIDI_IN_JACK)
bJackType 1 Embedded
bJackID 16
iJack 5 NKS
MIDIStreaming Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (MIDI_OUT_JACK)
bJackType 2 External
bJackID 64
bNrInputPins 1
baSourceID( 0) 16
BaSourcePin( 0) 1
iJack 0
MIDIStreaming Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (MIDI_OUT_JACK)
bJackType 1 Embedded
bJackID 48
bNrInputPins 1
baSourceID( 0) 32
BaSourcePin( 0) 1
iJack 6 LEGACY MIDI
MIDIStreaming Interface Descriptor:
bLength 6
bDescriptorType 36
bDescriptorSubtype 2 (MIDI_IN_JACK)
bJackType 2 External
bJackID 32
iJack 0
MIDIStreaming Interface Descriptor:
bLength 6
bDescriptorType 36
bDescriptorSubtype 2 (MIDI_IN_JACK)
bJackType 1 Embedded
bJackID 17
iJack 7 USB MIDI
MIDIStreaming Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (MIDI_OUT_JACK)
bJackType 2 External
bJackID 65
bNrInputPins 1
baSourceID( 0) 17
BaSourcePin( 0) 1
iJack 0
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x04 EP 4 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
bRefresh 0
bSynchAddress 0
MIDIStreaming Endpoint Descriptor:
bLength 5
bDescriptorType 37
bDescriptorSubtype 1 (GENERAL)
bNumEmbMIDIJack 1
baAssocJackID( 0) 16
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x84 EP 4 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
bRefresh 0
bSynchAddress 0
MIDIStreaming Endpoint Descriptor:
bLength 5
bDescriptorType 37
bDescriptorSubtype 1 (GENERAL)
bNumEmbMIDIJack 1
baAssocJackID( 0) 48
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x03 EP 3 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
bRefresh 0
bSynchAddress 0
MIDIStreaming Endpoint Descriptor:
bLength 5
bDescriptorType 37
bDescriptorSubtype 1 (GENERAL)
bNumEmbMIDIJack 1
baAssocJackID( 0) 17
Device Qualifier (for other device speed):
bLength 10
bDescriptorType 6
bcdUSB 2.00
bDeviceClass 239 Miscellaneous Device
bDeviceSubClass 2 ?
bDeviceProtocol 1 Interface Association
bMaxPacketSize0 64
bNumConfigurations 1
Device Status: 0x0001
Self Powered
</pre>Anonymoushttp://www.blogger.com/profile/04331570220720338171noreply@blogger.com1