December 27th, 2010

HTC's ongoing GPL violations

Over the past months, HTC has caused the Incredible and EVO communities a fair bit of grief by their failure to follow through on their obligations under the GPL; they have been continually releasing new binary versions of kernels for these two phones, but have failed to publish source at their Developer Center web site. Reportedly, when asked by e-mail, HTC has responded indicating that they were unwilling to release source; I'm waiting to hear back from them on this iteration, but last time I asked for an earlier version of the kernel, their support staff was incapable of producing source. I mentioned this in response to a post by mjg59, and he suggested that I write up details of their lack of compliance.

So, in this post, I intend to provide some specific examples of deltas from the latest source that are actively harming the community. The latest source drop available from HTC is available in supersonic-; my version of it has md5sum 8a22a3e6151fd181de93921ce42fde8a. My phone, which is running software version 3.70.651.1, is running kernel version

I'll first take a look at the routine supersonic_panel_unblank, found in arch/arm/mach-msm/board-supersonic-panel.c. In this update (well, a few updates ago, but still later than this kernel), HTC added support to run the LCD panel at a higher clock rate; this allows the EVO to break the previous frame rate cap (around 30FPS) cap, and move closer to 55FPS. These changes occurred in the unblank mechanism, and also in the initialization sequence; before HTC did, toastcfh and netarchy made these changes, proving that it was possible. (Right now, it doesn't look like their code was copied.)

On to the meat of it, then. In the released kernel, the unblank routine looks like this:

static int
supersonic_panel_unblank(struct msm_mddi_bridge_platform_data *bridge_data,
                        struct msm_mddi_client_data *client_data)
        B(KERN_DEBUG "%s\n", __func__);
        if (panel_type == PANEL_AUO) {
                client_data->remote_write(client_data, 0x00, 0x2900);
                client_data->remote_write(client_data, 0x24, 0x5300);
        } else {
                client_data->remote_write(client_data, 0x4000, 0x0600);
                qspi_send_9bit(0x0, 0x29);
                client_data->remote_write(client_data, 0x7000, 0x0324);
                client_data->remote_write(client_data, 0x4000, 0x0600);

        return 0;

However, a (cleaned up) decompilation of the unblank routine in the binary looks like this: (edit: differing parts are bolded)
  if ( vC047A86C == 1 )
    (client_data->remote_write)(client_data, 0x1u, 0xB101u);
    (client_data->remote_write)(client_data, 0x82u, 0xB102u);
    (client_data->remote_write)(client_data, 0x5Au, 45319);
    (client_data->remote_write)(client_data, 0, 17408);
    (client_data->remote_write)(client_data, 0xC8u, 0x4401u);
    (client_data->remote_write)(client_data, 0, 0x2900u);
    _client_data = client_data;
    nextaddr = 0x24u;
    nextdata = 0x5300u;
    (client_data->remote_write)(client_data, 0x3043u, 0x20u);
    (client_data->remote_write)(client_data, 0x10C8u, 0x404u);
    (client_data->remote_write)(client_data, 0x4000u, 0x600u);
    qspi_send_9bit(0, 0x29u);
    (client_data->remote_write)(client_data, 0x7000u, 0x324u);
    _client_data = client_data;
    nextaddr = 0x4000u;
    nextdata = 0x600u;
  (client_data->remote_write)(_client_data, nextaddr, nextdata);

There are substantial changes here (although not the same as those that toast and netarchy originally wrote); the released binary is obviously not the same as the released source.

There are also claims that HTC has made changes to the erase-block size probing algorithm in newer kernels; although I haven't been able to confirm this by disassembly yet, this would explain the beliefs that recovery images based off of old kernel source running on new hardware destroys the private keys stored in the WiMAX partition. So, in that case, it seems that HTC's failure to comply with their licensing obligations has directly caused harm to users. (I'm told that some of the CyanogenMod kernels have support for these new eraseblock sizes; if anyone could point me to a specific patch, I will update this post.)

Newer revisions of the Supersonic (EVO) hardware also have different cameras than the HW0002 version; as a result, the released source is unable to drive the camera on HW0004 Supersonics. This is reflected in the deltas from the source to the binary. On HW0002, the cameras are based on 'ov8810' and 'ov9665' sensors, and in the old kernel, the clocks for these are enabled with the supersonic_ov8810_clk_switch and supersonic_ov9665_clk_switch routines; in the new kernel, these routines simply do not exist. Similarly, the cameras are defined by struct platform_devices named msm_camera_sensor_foo -- on the old kernel, there existed msm_camera_ov8810 and msm_camera_ov9665, but on the new kernel there is a mysterious msm_camera_s5k6aafx. The routines driving this appear to be named things along the lines of s5k6aafx_sensor_probe, et al.; grepping for that string in the released source turns up nothing at all. This makes the old source unusable on HW0004 phones.

HTC, this isn't good enough. This is not a one-off; HTC has knowingly and repeatedly remained in violation of the licenses that the software they distribute comes with. It's time to shape up.

edit: HTC support responded to my e-mail, as follows:
Dear Joshua Wise,

I understand how important it is to have the most up to date kernal for your Sprint EVO 4G. HTC will typically publish on the Kernel open source code for recently released devices as soon as possible. HTC will normally publish this within 90 to 120 days. This time frame is within the requirements of the open source community.


Funny, that. I wonder which community they are talking about for which "sometime later, maybe" is acceptable?

edit, edit: HTC also responded with the following two responses as I responded again -- their web site did not copy me on the messages I sent, so I don't have an easy way to reference them.

Our kernel is not an original kernal, it is a motification of an existing kernel. Because of this, the requirements for releasing the kernel are different under the GPL. HTC is working as quickly as possible in order to provide this kernel. Once it is available, it will be released on

I wonder why the requirements are different? I asked, and they pointed me to section 6, subpart D (and quoted it), concluding:
This basically means that we may make the kernel accessable by offering it through a website for download. It clearly does not indicate a timeframe for this access. It merely states that we must offer it. The 90-120 days is to allow us sufficient time to upload the information to our server and prepare the server for access. Once again, once the kernel is available, you may find it at

I'll leave you to make your own decisions based on that; my reading of 6(d) allows no such window...