Razer Blade R2

Funtoo Linux Notes

Pre-emptive warning

This page is still being written; it's currently an incomplete relation of my experiences setting Funtoo (Gentoo) Linux up on a Razer Blade R2, and I'm honestly not yet done setting it up. Some things might even require drivers to be written. (That said, this page was written on that machine)

As such, standard disclaimer: this page is written as a guideline to setting things up yourself, but I cannot and do not take responsibility for any action (or consequences of that action) taken because of the reading of this page. Please do not blame/sue me if for some reason your bootloader has gone missing or the string "lulz" has written itself over and over your storage media.

Hardware

The Razer Blade is a beast of a machine, sporting a Core i7 3632QM CPU (quad-core + HT), nVidia Optimus switching between the onboard graphics of the Core i7 and an nVidia GeForce GTX 660M with 2 GB GDDR5 VRAM, plus all the other things you can expect of a laptop: wireless, keyboard, bluetooth, all that good stuff.

GNU/Linux, however, is known to not always support the newest hardware. With that in mind, I'll start by listing what works:

Installation

First off, you must disable Secure Boot, because otherwise you can't boot off any media at all.

Now, since the machine lacks an optical media drive (what?), you will require a VFAT-formatted USB drive. Preferably a real USB drive of good quality; while I have managed to use a USB stick that adapts a microSD card, it was a really difficult endeavor that was frought with confusion ("why isn't it booting anymore?").

On the USB drive, you want to create a folder labelled "EFI", and one under that called "Boot". This is where you will store your EFI bootloader. You can use any that you want, but I would strongly recommend rEFInd by Rod Smith -- it's nice and graphical by default, and its autodetect can really bail you out of any jam you can get in. I also strongly recommend using it if you plan on dual-booting with the pre-installed Windows 8 OS, since you will have to replace Windows's bootloader with it -- but don't worry about that yet...

Now, it's worth noting that I was working from Gentoo's livecd, so some of this might be vastly different for your choice of distribution. However, by default, the kernel on that livecd isn't an EFI-stub kernel, so you're going to need an EFI bootloader like ELILO to actually boot the kernel. (Note: if the first two characters of the kernel file on your livecd actually do happen to be "MZ", you can skip grabbing ELILO entirely; you have an EFI stub-loading kernel)

Finally, you want to grab the liveCD you want to boot into (maybe gentoo's install livecd, or Ubuntu's media). You need a few files out of this: the kernel, the initrd, and the (usually squashfs) filesystem image file on-disk. In Gentoo, the kernel is /gentoo.efimg.mountPoint/gentoo, the initrd is /gentoo.efimg.mountPoint/gentoo.igz, and the filesystem image is /image.squashfs -- all relative to the root of the media. In Gentoo's case, there is one more file to grab -- /livecd, which is an empty file that indicates to the init scripts on the live media that it has found the media it's actually on.

Take your kernel, initrd, FS image and any indicator files needed (if needed) and put them somewhere on your flash drive where you'll remember. Then, take the kernel arguments found in /isolinux/isolinux.cfg (or wherever it may be) and put them into your EFI bootloader configuration of choice. What's important is that the kernel be booted with the same arguments ISOLINUX would boot it with, so that it acts as if it is on a livecd, even though it's booting from a VFAT stick. This means, for instance, if your isolinux.cfg reads:

label gentoo
  kernel gentoo
  append root=/dev/ram0 init=/linuxrc  dokeymap looptype=squashfs loop=/image.squashfs  cdroot initrd=gentoo.igz vga=791

Then your elilo.cfg (for instance) should read:

image=/gentoo
   label="Gentoo"
   description="Gentoo Install Media"
   initrd=/gentoo.igz
   append="root=/dev/ram0 init=/linuxrc dokeymap looptype=squashfs loop=/image.squashfs cdroot initrd=gentoo.igz vga=791"

And this should let you boot into the installation media normally. You should, from there, be able to install your Linux distribution as you normally might -- but beware of it trying to blindly overwrite bootloaders and such!

Dual-booting

Once you've installed everything, make sure you have an EFI bootloader that will work -- again, I strongly recommend rEFInd due to its autodetection fallback -- and put it onto your EFI SYSTEM partition. You can do that on Windows via mountvol /S X: and simply placing the files onto the volume, or you can do that while you're booted onto your media (on my system, it's on /dev/sda2). (Note that the new volume may not show up in Windows Explorer!)

When the files have been placed in a safe (and preferably separate) location on the SYSTEM partition, you will need to run this command:

bcdedit /set {bootmgr} path \EFI\ubuntu\grubx64.efi

When you next reboot, your chosen EFI boot manager should come up rather than the Windows bootloader.

Odds and ends

There are some things I haven't yet worked out. I've put as much information as I have here. You can contact me at FxChiP@Gmail.com or on Twitter @FxChiP if you might be able to help. (Thanks in advance for this!)

Keyboard

The keyboard has a weird tendency to sometimes ignore or repeat characters. It's really strange and I'm not sure why this might happen. This forum post contains instructions on changing some code within the usbhid driver to shorten the polling interval and allow all keystrokes to come through.

Touchpad

It looks like the touchpad's default mode of operation is to emulate a normal, bog-standard mouse, as most touchpads tend to do. However, what's strange is that the Synaptics driver doesn't have any idea how to handle it; as far as it's concerned, it's not a synaptics pad. What's even weirder is that the pinch-to-zoom gesture seems to be implemented in hardware; any time you perform the gesture, the touchpad sends "button 4 pressed" and "button 5 pressed" events. I gathered this from using xinput -test on the touchpad. Button 5 on pinch and button 4 on stretch. I can't get it to do two-finger scrolling, though.

The driver attached to it is evdev, but it doesn't seem to send/do multitouch events (at least according to mtdev-test). Then again, that might just be for tablets.

Update 5/5/2013: the touchpad *is* a multi-touch device, the "weird device" below turns out to be an "alternate setting" for that interface; once the interface is set to use that alternate setting, it starts reporting multi-touch data. (Unfortunately, it also hoses the keyboard. I suspect there might be USB issues involved...)

This makes me wonder if I'm not barking up the wrong tree. Maybe it's an mtrack device instead. This seems really odd though.

12/01/2013: It really is a Synaptics device, just a new one that follows the same synusb protocol but extends it by (1) appending a byte whose upper bits indicate the count of fingers on the pad and lower bits indicate the index of the finger itself and (2) appending four more such packets, allocating one for each finger. There is a patch at the end of this page that will enable this touchpad as a multitouch device, but there's a problem: the touchpad is sensitive enough that it will constantly report incredibly small variations in coordinates while the finger is ostensibly stationary. I don't know the math to filter this out effectively, and fuzzing turns out to be an extremely poor solution (partly because it doesn't entirely work anyway, and partly because it doesn't appear to be the strategy Windows uses at all either).

Macro keys

The bottom row of 5 seem to come in under the keyboard, yielding "n" or "]" characters alternately. The top row of 5 seem to come in under their own device, /dev/input/event5, with the top left, top middle, and top right buttons sending events (the same exact one, it looks like) and the other two doing absolutely nothing. However, doing more research, it turns out that those extra two actually send "left shift" and "right shift" keycode events on the keyboard's device, /dev/input/event6.

The Fn key comes in under /dev/input/event5, too.

Update 5/18/2013: as it turns out, setting the alternate interface on the touchpad will also change the input semantics for every other input device in the laptop. Keyboard reports begin coming in on the interface thought to be used for the macro keys (interface 1) and the macro keys begin differentiating. Specifically, there start to be two "report IDs": 0x01, for the keyboard (which seems to support about 15 simultaneous key-presses) and 0x04, for the macro/extended keys "keyboard". The screened keys come in as 0x50-0x59 (1-10, left to right, top to bottom), Fn comes in as 0x01, and the Razer button comes in as 0x02. They're laid out like the standard keyboard; one byte set per button pressed, 0x00 indicates "nothing pressed."

Update 5/26/2013: See below -- essentially, setting the trackpad's interface to the alternate will cause the keyboard to use the other HID interface, which also enables support for the media keys, the macro keys, power management (I think) and what may or may not be exception handling.

The extra device

There are five interface descriptors underneath the root "Razer Razer Blade" (surprisingly not a typo) device when running lsusb -v. Funnily enough, the configuration descriptor only declares 4 interfaces, even though I see five -- but I digress. The first is the mouse, the second is something (gives scarce little information), the third is the keyboard, the fourth is another keyboard (presumably the macro keys), and the fifth is a Vendor-Specific interface that takes bulk transfers (a lot like an iPhone, actually!). Here's the information on it:

    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        3
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass    240 
      bInterfaceProtocol      0 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 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     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0

In fact, while I'm at it, here it is for that weird second device too:

    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       1
      bNumEndpoints           1
      bInterfaceClass         0 (Defined at Interface level)
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               8

I think I'm going to try reading that second one raw and see what happens. What to do about that vendor-specific one? It's probably what controls all the images and stuff, and might also convey some input data from them -- but that doesn't make much sense to me...

Update 05/26/2013: The vendor-specific one is write-only. If there's a way to read it, it's probably via the control interface... but I doubt it.

That "weird second device" turns out to be an alternate setting to the first interface, the mouse. When that interface is set to that alternate, it begins reporting multitouch data, which looks like absolute coordinates per-finger. Interesting. But the problem is setting it to that seems to wipe the keyboard out.

Update 05/26/2013: Actually, it turns out that synaptics-test, which I had been using for previous tests, was wiping out the keyboard when detaching the driver from the device. My working copy of razer-test has a feature to re-attach the "macro keys" after switching the alternate setting, and this causes the keyboard (and the media keys, which weren't read before) to be read. I have no ETA on its release.

razer-test

I have written a sample program to just read the raw input from all of the input devices, called razer-test. It will read the input, tell you where it came from and output the bytes it got in hexadecimal digits.

Future planned features include interpretation of received input, setting of the alt interface (as described above) and continuing to read from devices, and maybe more stable code. :)

Download: razer-test.tar.bz2

CHANGES 05/21/2013: razer-test now sets the input hardware to the alternate interface, allowing *FAR* more accurate input to be read. It also does extremely basic interpretation of the data received. The harness can rebind input hardware to input drivers if razer-test fails to do so, and it will also reset all the hardware back to defaults once finished, almost guaranteeing that input resumes as normal once the testing is over.

CHANGES 06/27/2013: Time marches on, and so do efforts. I have a patch for the synaptics-usb driver that enables and supports multitouch for the touchpad (and in the process, enables the multimedia controls on the keyboard). It's still extremely preliminary, however, so it may still not work right all the time (plus, I'm not sure what causes all the inputs to crash randomly).

Newer devices

Razer Blade 14

It looks like the Razer Blade 14 uses a rather different layout of interfaces/input devices. For one, the interface-switching technique usable on the R2 and Blade Pro won't work at all, since there are no alternate interfaces on the Blade 14's USB input device(s). Instead, it looks like a packet would need to be sent over the first interface (interface 0 or 1, depending on Linux or Windows) that indicates whether the device switch needs to be performed. Once that's done, I imagine, the input would start flowing through the alternate interface(s).

Razer Blade Pro

Little to no change, except that it puts the input hardware on an xhci interface rather than ehci. For some reason, this skips any change to usbhid and so the keyboard fix above may not work.