## Saturday, December 9, 2017

### DIY laptop

Some time ago, laptops have displaced desktops as primary machines for many, perhaps most, users who don't go in for high-end gaming, and I am no exception. Now my trusty Thinkpad T500 has been getting a bit long in the tooth, and recent models coming on the market have been less than inspiring — I had hopes for Thinkpad Retro, but it turned out to be just a very expensive T470 with a better keyboard — so I was toying with the idea of a DIY laptop. This post is a dump of my research (such as there was) and considerations pertaining thereto.

My list of requirements for a DIY laptop is

1. good 15" display
2. good keyboard
3. powerful: good upgradeable CPU, lots of memory
4. be presentable and approach laptop-class size and thickness

1. For the first point, there is nothing better than the LP154WT1-S* or LSN154YL0* "retina" LCDs that are installed in MacBook Pro 15.4" A1398 models. Like my T500, these are 16:10, a rarity in an age when every other maker has given up and is putting 16:9 (or even wider) movie panels into their laptops. I (and a lot of other people) need the laptop for work, not for goddamn movies! Anyway. These panels have a standard 30-pin eDP interface, but use a rare connector part need a custom board for the lighting controller/power supply. Fortunately for the DIY laptop project, a couple of hardware geeks have figured it out and shared schematics, part numbers and so on. Replacement panels can be bought on panelook and eBay; a bare panel costs $160-$180 and would need diffusers and backlight LEDs, while a complete display assembly is now north of \$300 and isn't usable as such anyway due to branding. However, diffusers and backlights from MBPs with totaled LCDs aren't difficult to find. MBP's complete display assembly is 7mm thick in the thickest place — the bulge with the logo — so 5mm is probably a reasonable target thickness for a DIY display assembly.

2. Replacement classic 7-row Thinkpad keyboards with trackpoint are excellent quality, cheap and easily obtainable, and being so popular other hardware geeks have figured out how to connect them to computers. The trackpoint has a PS/2 interface, but the keyboard itself needs a microcontroller with firmware to read the key matrix and generate appropriate messages. This calls for a custom board, but any DIY laptop would need one, so it's not a big deal. The biggest problem with the keyboard is that it has to be screwed to the case, and the geometry can get tricky. More on this later.

3. This basically means socketed server-grade CPUs and slotted memory, and rules out soldered Atom CPUs, Celerons etc. Discrete graphics cards are probably out of the question, but modern integrated graphics should be good enough if you aren't editing video or playing high-end games.

Cool, but not really what I'd like to pack around.

4. The requirement of laptop-class thickness (say less than 40mm) drastically limits one's choices. A motherboard with DIMM memory is already a hair above that limit by itself; add 5-6mm for the display, 5-6mm for the keyboard and a couple millimeters for the case, and you're looking at something over two inches thick. Barring completely impractical options, this means Thin Mini-ITX motherboards with SoDIMM memory. The motherboard with all components (including memory) is constrained by standard to be at most 20mm thick, and a few millimeters must be allowed for bottom side stand-offs. Unfortunately, the Thin Mini-ITX standard seems to be dead in the water. There are few products on the market that support eDP and Skylake/Kaby Lake (Socket 1151) CPUs simultaneously, and nothing at all for AMD; about the only consumer-grade choice is Asus Q170T and its variants (the V2 upgrade, which is apparently not yet sold anywhere, has a bonus "disable ME" jumper — good to have even though firmware geeks have learned how to turn it off on the firmware level like the big boys in the spy agencies do). For cooling a CPU with interesting (read: more than 15W) TDPs, passive heat sinks are out. Given the stringent height limit, the most reasonable solution I have discovered is Intel HTS1155LP, targeted at half-unit rack servers. Its thickest part — its off-board heatsink, connected to the CPU plate with three heat pipes — measures 26mm. If this turns out to be too thick, heatsinks can be modded with some care.

The basic elements of the design are thus: 16:10 15" display, Q170T motherboard with Socket 1151 (up to i7-8xxx), up to 32GB DDR4-2133 SoDIMM DRAM and a M.2 NVMe SSD, HTS1155LP heat sink, one or two custom boards for display connectors, keyboard controller, battery controller/regulator and incidentals. The tricky part is to find a suitable geometry of all the key components. After some consideration and scribbling some layouts, I have settled on one where the motherboard's I/O shield faces backwards, and the heat sink sits under the left palm rest. (Other options either sacrifice 6-7mm of thickness as the keyboard goes on top of the heat sink, or sacrifice 20% of the heat sink, which I'm not willing to do.) A millimeter of cork or similar thermal insulation on top and bottom of the heat sink should suffice to keep surfaces at reasonable temperatures as long as the fan is working. The hot-air outlet is on the left side. Since the design uses the Thinkpad keyboard, it might as well use the Thinkpad palm rest (with its PS/2 trackpad), the top bezel, and the matching display bezel from a dead "donor" laptop. The keyboard is located mostly above the motherboard, where it can be supported by HTS1155LP's motherboard mount via some struts. Other keyboard mounting holes can be arranged to fall outside motherboard footprint. The bottom of the body (as well as the top of the display assembly) can be cut out of 1mm sheet aluminium, folded, welded together and spray-painted with plasti-dip or similar finish at an auto body repair shop. Body thickness is then 30-31mm — 1mm/case/+1mm/insulation/+26mm/heat sink/+1mm/insulation/+1-2mm/palm rest/. With a 5-6mm display assembly, this is, of course, nowhere as thin as today's ultrabook butter-knives, but neither is it monstrous; T-series Thinkpads measure around 34mm depending on model. As for peripherials, one can add them to taste — front ports, SD and smart card readers, NFC, wi-fi, broadband modem, etc. For the battery, laptop batteries are based on standard 11865 3.7V 3400mAh Li-ion elements anyway, so one can add as many as fits one's desired weight. Six will give 75Wh for 300 grams.

## Wednesday, April 25, 2012

### How to present to an executive

Good article by Gray Knowlton, hope it will come in useful some day.

## Tuesday, April 24, 2012

### Three excellent articles about the state of IT

Frighteningly Ambitious Startup Ideas (Paul Graham)

This Tech Bubble Is Different (Bloomberg Business Week)

Choice quote: "The best minds of my generation are thinking about how to make people click ads," [Hammerbacher] says. "That sucks."

## Friday, January 20, 2012

### Russian programmers

Russian programmers got a nice plug over at Marginal Revolution in the comment section:
My experience with Russians are that they are the best hackers. They trust themselves, they are self-contained and they work with meager resources and really sweat the details. I’ve worked with a few and I would love for all of my code to be eyeballed by a Russian programmer who’d make it work in less memory. I like the fatalism built into Russian engineering, makes stuff robust.
Being one, I heartily concur. Thanks!

## Sunday, July 3, 2011

### LINQ Expressions and Reflection.Emit: an uncomfortable union

The other day I needed a component for a project of mine, which would rewrite methods into state machines like the CTP C# compiler does for async methods. The rewriter would accept a callback to identify the sites where a continuation must be created, and another one to emit glue code for the site using two primitives: SAVE_STATE() which returns the continuation delegate and RESTORE_STATE() which returns the value passed to the continuation. This approach permits the users of the rewriter to avoid the overhead of saving and restoring state when the continuation turns out to be unnecessary (in async terms, when the awaited thing is already complete). The new CTP compiler implements this optimization. My component would eventually have to work with IL methods either via Reflection.Emit or Cecil, but I thought it would be interesting to make it work with LINQ Expressions first. Besides, the DLR has a similar rewriter for yield which I could scavenge for useful hints. The DLR rewriter uses a nested lambda to create the 'environment', shifting the work to the LINQ Expression compiler (EC). Probably because of permission issues, EC does not create new closure classes and instead uses a thinly veiled object[] to store closure locals. I did not want this, I wanted to generate a proper closure class. After all, EC can compile a lambda expression into a MethodBuilder!

Although I more-or-less made it work, I must report that LINQ Expressions don't work all that well with Reflection.Emit:

1. A LambdaExpression cannot have parameters of unbaked type. EC appears to have no problems with this, but Expression.CreateLambda uses generic lambda factories and an unbaked type cannot serve as a type argument. One must have the lambda accept a suitable base class or object.

2. It is impossible to generate a call to any method which has not been 'baked' because LINQ Expression constructors insist on validating a method's parameters and call MethodBase.GetParameters(). This extends to object construction as Expression.New validates constructor parameters. These two problems are very obnoxious and make any serious use of LINQ Expressions with Reflection.Emit impossible.

As a side note, I find it puzzling and inconvenient that MethodBuilder does not expose its parameter list.

3. EC has no problems emitting constants referring to a TypeBuilder or a MethodBuilder, but one must tell Expression.Constant the correct types, viz. Type and MethodInfo. Otherwise EC happily emits casts to TypeBuilder which blow up at runtime. Just a minor gotcha, but still.

4. There is no DelegateCreationExpression. This is strictly speaking not related to Reflection.Emit, but it is annoying to have to generate a call to CreateDelegate, complete with casts and stuff, instead of a ldftn-new combo.

5. EC cannot compile lambda expressions into member methods even if the method signature is compatible. The target method has to be static, period.

This was a useful excercise and working directly with IL should not be much more complicated.

## Wednesday, March 16, 2011

### Bakunin fulminates

"Etatism and anarchy" (1873)
Let us respect [social] scientists for their achievements, but for the sake of their reason and moral integrity we must not give them any privileges and only recognize their right, common to all, to freely preach their convictions, thoughts and knowledge. We should give power neither to them nor to anybody else, for whoever has power becomes, by an immutable law of sociology, an oppressor and exploiter of the society.
Woe unto mankind should theoretical speculation become the only source of guidance for society, should science alone take charge of all social administration. Life would wither, and human society would turn into a voiceless and servile herd. The domination of life by science can have no other result than the brutalization of mankind.