May 07

我们要配一个螺丝,规格和形状是这样的:

这里面有3个数字:1/4,20,和1 31/32。
当我们到了Lowe’s 的 Hardware Section的时候,顿时被琳琅满目的商品给晃花了眼 — 这么多螺丝,上哪里找去啊?没奈何,只好对着那些标签挨个找。可是,大多数标签都只写了两个数字,像1/4 - 2这样子。后来一问才知道,第一个数字1/4是指直径,20是螺纹密度tpi (thread per inch),1 31/32是长度,均以inch为单位。大多数标准螺丝或为20 tpi (coarse),或为28 tpi (fine),而摆放在那里的均为20的,所以就没有在标签上注明了。
我们找不到1 31/32长的,但找到了最接近的长为2英寸的。在店里还有模板可以测量直径、长度、和密度。

有人告诉我们,因为Lowe’s卖的商品太多,买五金器材也许不如去专门的Hardware Store方便,像我们这里有Martin 和 Meadowbrook 都不错。

最后,我对screw (螺丝)和bolt (螺栓)的区别总是搞不太清,查了一下wiki发现确实是没有明显的区别:

Differentiation between bolt and screw

A universally accepted distinction between a screw and a bolt does not exist.

In common usage the term screw refers to smaller (less than 1/4 inch) threaded fasteners, especially threaded fasteners with tapered shafts (貌似指会越来越细呈锥形,有点像钉子) and the term bolt refers to larger threaded fasteners that do not have tapered shafts (貌似指柱形,因此有的会在终端配套一个螺母,nut). The term machine screw is commonly used to refer to smaller threaded fasteners that do not have a tapered shaft.

Various methods of distinguishing bolts and screws exist or have existed. These methods conflict at times and can be confusing. Old SAE and USS standards made a distinction between a bolt and a cap screw based on whether a portion of the shaft was un-threaded or not. Cap screws had shafts that were threaded up to the head and bolts had partially threaded shafts (照此标准我们要找的是bolt). Today a bolt that has a completely threaded shaft might be referred to as a tap bolt.

May 02

gcc -### - show what GCC would have executed
gcc -v - show what GCC is executing
gcc -g x.c -o x; objdump -S x - show the C and generated assembly code
gcc -E -dM - gcc -C -E - show pre-processor output, but leave comments intact
gcc -M - show all include file dependencies (for use in Makefiles)
gcc -MM - like above, but ignore system include files

via LWN.

Apr 28

Our group has some machines running the old Red Hat Linux 7.3. The system is too old, but I didn’t want to wipe off the disk to install a new system. Since I have root access on them, I decided to install the Debian system in a chrooted environment.

This is how I did it:

sudo -s
cd /tmp
wget http://http.us.debian.org/debian/pool/main/d/debootstrap/debootstrap_1.0.8_all.deb
ar -x debootstrap_1.0.8_all.deb
cd /
zcat /tmp/data.tar.gz |tar xv
debootstrap –arch i386 sid /debian
mount -t devpts devpts /debian/dev/pts
mount -t tmpfs shm /debian/dev/shm
mount -t proc proc /debian/proc
mount –bind /dev /debian/dev
LC_ALL=C chroot /debian/

Apr 09

陈冲在华盛顿邮报发表了一篇题为Let the Games Go On文章,说得很好,引用两段如下:

This statement could not be further from reality. For one thing, the Chinese are a proud people. They want freedom and greater rights, but they know they must fight for them from within. They know that no one can grant them freedom and rights from afar. The stigma of Western imperialism and the Opium Wars also remains a strong reminder of the past, and Chinese people do not want their domestic policies to be dictated by outside powers. They also do not want the United States to boycott the opening ceremonies of the Games. The U.S. boycott of the 1980 Games in Moscow and the Soviet boycott of the 1984 Olympics in Los Angeles accomplished nothing. A U.S. boycott of the opening ceremonies in Beijing would be counterproductive for relations between the two countries.

For decades, anti-China human rights groups in Washington have spent millions of dollars denouncing China. To many Chinese, it seems that this lobby is the only voice that’s acceptable or newsworthy in the U.S. media and to the U.S. government. But times are changing. We need to be open-minded and farsighted. We need to make more friends than enemies. Remember what a little ping-pong game did for Sino-U.S. relations in the 1970s? Let’s celebrate the Olympics for what the Games are meant to be — a bridge for friendship, not a playground for politics.

奥运会将把民主带给一个专制国家,为什么呢?再引用一段White Camry的话

Because China is hosting these Olympics … no boycott is necessary. China is a one-party state and, whenever a one-party state hosts an Olympics, ten year later they’re circling the drain if not already down it. To wit:

1936 - Berlin Olympics; 1946 - Allied Occupation.
1980 - Moscow Olympics; 1990 - Warsaw Pact meltdown.
1984 - Sarajevo Winter Olympics; 1994 - Yugoslav Civil War.
2008 - Beijing Olympcs; 2018 - ?

The clock is ticking.

UPDATE 4/16: 本人从即日起不再抵制任何抵制北京奥运的行为,因为中国自己就干过这事1980年莫斯科举办奥运会,中国响应美国号召抵制了奥运。1984年洛杉矶举办奥运会时,苏联和东欧集团以及朝鲜都集体抵制了洛杉矶奥运会,而中国却第一次参加奥运会,并实现了零的突破。而这段历史国内从未提及,真是可笑可叹啊。

Mar 29

昨天 (3/28/2008) RMS来到UVa做题为Free Software in Ethics and in Practice的演讲。主题主要是围绕着GNU和free software movement展开,没有涉及到技术(e.g., Emacs)和法律(e.g., GPLv3)上的细节。与以往我们系的报告不同,这一次的报告特地选在一个很大的教室进行,但还是被感兴趣的老中青三代(faculty、grads、undergrads)占满了。
我们系的chair作为RMS的host先对RMS进行介绍。其中她故意说RMS推动了Linux的发展,RMS立即打断并纠正说应该是GNU/Linux,引来哄堂大笑。chair立即解释说她是故意说错测试RMS的反应:)

RMS作为教主,演讲的功力真的不是盖的。他没有使用幻灯片,而仅仅每隔一段时间低一下头看桌子,估计是演讲提纲。他好像演讲的时候不喜欢穿鞋?还不时的不顾形象的擦鼻子,希望大师不是感冒了。

RMS首先开宗明义,提出software freedom包含四个方面,并就这四个方面花了大部分时间阐述。给予用户自由使用和发布软件的自由,使得他们不受限于license,这在道德方面有着积极的意义。否则,当一个用户被朋友要求分享一个程序时,用户就会面临着一个两难选择:他可以选择拒绝朋友而不分享,也可以选择破坏license而分享。两害相权取其轻,the lesser evil自然就是选择分享了(众笑)。(注:在演讲结束后有人问RMS对分享音乐怎么看,RMS说他坚决赞同应该分享,换来热烈鼓掌。还有人问到他对free chip design怎么看。RMS的回答是,现在一般人即使拿到一个chip design也无力生产芯片,但是如果到以后普通人可以自由复制和生产芯片的时候,他将会支持free hardware)除去道德方面的因素,软件自由还有着很多的益处。软件的自由带来了free market和democracy。Free market指的是,没有了垄断,任何business当需要定制什么软件时,就可以到市场上提出这个需求让程序员来做。Democracy指的是一个软件添加的特性由需求本身去推动,而不是由那些nasty companies来决定。最后,优秀的、最受欢迎的软件自然胜出。

接下来RMS回顾了GNU operating system的历史。GNU的名字是一个recursive name,这在当时是一个比较流行的幽默命名法,用XINY代表XINY Is Not Y。因为RMS想取代UNIX这个私有系统,但又同时兼容UNIX,所以就想取一个XINU代表XINU Is Not Unix。同时又要使得这个名字又是一个合法的英文单词,RMS便drop掉那个I,然后从anu、bnu、cnu开始查字典。查到gnu时,发现这个好(因为和new同音,这样gnu system就是new system可以制造很多笑话),于是GNU’s Not Unix便横空出世了。也许是为了和gnu区别,GNU的G是发音的(现在再称gnu system为new system可就不对啦,哈)。RMS发觉自己一个人写程序很辛苦,于是拉了一些人一起写,FSF也就产生了。为了取代UNIX,FSF开始一块一块的写程序将UNIX的组件取代,直到最后开始着手写kernel,也就是今天的Hurd。RMS将kernel设计成基于Mach的微内核,但没有自己写,而是聘请了别人写,好像是说写了6年都没写好。没有想到的是,Linus自己一年不到写了一个可用的monolithic kernel出来,并吸引了大家的注意力。相信Hurd后来半死不活也有部分原因是大家都去开发linux了。因为Linux系统用的userland程序都是来自GNU,RMS一直坚持称Linux为GNU/Linux。但是这也不能怪大家,gnu-slash-linux多难念啊。Microsoft Windows不也被简称为Windows么。

RMS对大家忘了GNU颇有微词。除了credit外,最重要的是RMS认为GNU体现了freedom的思想。RMS是理想主义者,而Linus比较关心practical的问题,因此喜欢说open source而不说free。RMS则对大家忘了GNU operating system深为痛心。如果大家忘记了RMS西行十万八千里历经九九八十一难得来的freedom的真意,即使现在所有的软件都开源,在5年后,又将会有很多non-free software出现。RMS很不满的是,在流行的GNU/Linux系统为了吸引用户,都允许加入proprietary software。他现场推销了一些纯自由的GNU/Linux系统,例如Utoto, gNewSense, 和BLAG。RMS非常希望大家能为free software movement做出贡献,哪怕是向别人传播GNU philosophy也是一种贡献。就算抽不出10分钟介绍,每次也应多花一秒钟把GNU/加在Linux之上。例如LAMP架构就应被称为GLAMP架构。

RMS语重心长的大家说,自由平等的概念已经深入人心,但计算机产业由于出现时间太短,很多人都没有意识到自由的重要性。在这一点上我对RMS特别佩服:他第一个认识到这一问题,并为了解决这一问题提出了一套行之有效的方案,指出了我们前进的方向。你也许可以argue about GPL的过于严格,你可以更喜欢BSD license,但你无法否认RMS对free software movement起到的精神导师的作用。

RMS非常健谈,一转眼就谈了一个半小时,chair都快要坐不住了,已经站起来准备提醒他。RMS看到chair的这一举动,立即说我还有几个topics来end this talk。chair非常尴尬,引来全场爆笑鼓掌。RMS想要强调free software对education的作用,并希望所有的学校禁止使用私有软件,即使是赠送的。最后,RMS还解释说free software并不会导致IT job的减少。减少的只是私有软件的开发的job,但增加了custom software development的job、提供服务的job、和software freedom对社会的促进带来的更多机会。

RMS的保留节目,也就是教主身份的展示。



可爱老头:

正在bless我们的computers:

在为the Church of Emacs传教时,他还讲了几个关于VI的老笑话,例如”Using a free-software version of vi is not a sin; it is a penance.” 笑话中vi-vi-vi is the “editor of the beast” 引来的笑声最大。

演讲完毕时,现场爆发长时间的热烈鼓掌,为这个可爱的固执老头表达了极大的敬意。

Mar 17

由Tourist Pictures制作。
先来一段关于蜜蜂的电影Evil Bee,颇有点The Matrix的味道。

接下来是一段食品大战Food Fight,比较考验历史、地理的知识。

Mar 09

特别是北方人说“那个”的时候,会引起人误解。
以前就听说这样不好,没想到Russell Peters还编进了笑话里面。

Mar 05

1. Dumping out compiler intermediate structures

I think the order in which the options are listed is along the same line as the real order of the passes.

For example, ghc -ddump-to-file -ddump-asm a.hs would dump the assembly to file a.dump-asm.
The option “-ddump-to-file” tells ghc to dump to a file, instead of to stdout. This feature does not seem to be documented.

2. The runtime system

GHC compiles Haskell source code down to native code, and then links in necessary Haskell libraries (written in Haskell) and RTS (written in C and C–). To see what libraries are linked in, pass -v to ghc.

Therefore, the lifetime of a Haskell program roughly looks like this:

The C Runtime (CRT) gets started first, which passes control to main. For C programs, main is defined by programmers; while for Haskell programs, main is defined by RTS in rts/Main.c. Next, RTS is initialized by calling startupHaskell in RtsStartup.c. Eventually, the computation that resides in mainIO_closure (a macro defined in Prelude.h that resolves to &ZCMain_main_closure) is kicked off from real_main. The closure data structure is defined as StgClosure/HaskellObj in includes/RtsAPI.h and includes/Closures.h.

In fact, because RTS is C code, you can play with its Makefile to produce a libHSrts.a with debugging information in it. Then you can link your Haskell program with this library to walk through the source of RTS in gdb.

3. Static linking vs dynamic linking

The Haskell libraries are statically linked by default. In fact, shared Haskell libraries are only supported on Mac OS X. There are good reasons for that.

The C libraries are not statically linked by default. To produce a completely static binary, run ghc -optl-static -optl-pthread a.hs. Any string following “-optl” is passed to gcc for the final linking step. Without “-optl-pthread”, you get errors like this:

wh5a@flitwick:/tmp$ ghc -optl-static a.hs
compilation IS NOT required
/usr/lib/gcc/i486-linux-gnu/4.2.3/../../../../lib/librt.a(timer_create.o): In function `timer_create’:
(.text+0×111): undefined reference to `pthread_once’
/usr/lib/gcc/i486-linux-gnu/4.2.3/../../../../lib/librt.a(timer_create.o): In function `timer_create’:
(.text+0×165): undefined reference to `pthread_attr_init’
/usr/lib/gcc/i486-linux-gnu/4.2.3/../../../../lib/librt.a(timer_create.o): In function `timer_create’:
(.text+0×1ab): undefined reference to `pthread_attr_setdetachstate’
/usr/lib/gcc/i486-linux-gnu/4.2.3/../../../../lib/librt.a(timer_routines.o): In function `__start_helper_thread’:
(.text+0×49): undefined reference to `pthread_attr_init’
/usr/lib/gcc/i486-linux-gnu/4.2.3/../../../../lib/librt.a(timer_routines.o): In function `__start_helper_thread’:
(.text+0×5c): undefined reference to `pthread_attr_setstacksize’
/usr/lib/gcc/i486-linux-gnu/4.2.3/../../../../lib/librt.a(timer_routines.o): In function `__start_helper_thread’:
(.text+0xab): undefined reference to `pthread_create’
/usr/lib/gcc/i486-linux-gnu/4.2.3/../../../../lib/librt.a(timer_routines.o): In function `__start_helper_thread’:
(.text+0xde): undefined reference to `pthread_attr_destroy’
/usr/lib/gcc/i486-linux-gnu/4.2.3/../../../../lib/librt.a(timer_routines.o): In function `__start_helper_thread’:
(.text+0xfa): undefined reference to `pthread_atfork’
/usr/lib/gcc/i486-linux-gnu/4.2.3/../../../../lib/librt.a(timer_routines.o): In function `timer_helper_thread’:
(.text+0×19d): undefined reference to `pthread_exit’
/usr/lib/gcc/i486-linux-gnu/4.2.3/../../../../lib/librt.a(timer_routines.o): In function `timer_helper_thread’:
(.text+0×1e5): undefined reference to `pthread_create’
/usr/lib/gcc/i486-linux-gnu/4.2.3/libgcc_eh.a(unwind-dw2.o): In function `uw_init_context_1′:
(.text+0×1904): undefined reference to `pthread_once’
collect2: ld returned 1 exit status

Looking at the above error, you may think passing “-optl-lpthread” instead of “-optl-pthread” would help, too. But as you can see in the verbose mode, “-lpthread” is passed to gcc too early. Another way to work around this error is to pass “-threaded” to ghc, which automatically adds “-lpthread” to the end of gcc’s command options because ghc knows you’re using the threaded Haskell library.

For more advanced tricks, refer to the script “kernel/ldhouse” from the House project.

Mar 02

via VPedia

Feb 25

This is a literate Haskell file, inspired by the paper
“Functional Programming with Overloading and Higher-Order Polymorphism” and Chapter 20 of TAPL.

In almost all programming languages, recursive types can be easily defined.
For example, a list of naturals can be defined as NatList = nil | cons Nat NatList.
This equation is not a simple definition, the right-hand side mentions the very name that we are defining.
This is just like how we ran into the difficulties of defining (anonymous) recursive functions!

Let us review how to define recursive functions first.
We can abstract this recursive equation as x = f x.
Suppose we have a magical fixed-point combinator, let’s call it Y, that for any f, Y f = f (Y f).
If such Y exists, Y f specifies the fixed point of the recursive equation x = f x.
It turns out such Y does exist for untyped lambda calculus : Y = \f.(\x.f(x x)) (\x.f(x x))

For recursive types, we make up a new combinator Mu, such that Mu f = f (Mu f).
Note that f here denotes a type constructor instead of a function.
NatList is the fixed-point of the equation X = nil | cons Nat X.
So it can be defined as NatList = Mu (\X. (nil | cons Nat X)). (”\” is overloaded here for abstraction at type level)

We do not explicitly define Mu because we cannot abstract over type constructors in Haskell.
If we could, the type system would be undecidable, *I think*.
Instead we’ll cheat and simply live with this definition: Mu f = f (Mu f).
Because Haskell requires a constructor for types, we have to define it in Haskell this way:

> newtype Mu f = In (f (Mu f))

This extra layer of In doesn’t change the mathematical property, because we can view In as an isomorphism.
And here’s the reverse isomorphism:

> out :: Mu f -> f (Mu f)
> out (In x) = x

Let’s see how Nat plays out. We first define the equation, and then pass the equation to Mu:

> data NatF b = Zero | Succ b
> type Nat = Mu NatF

The elements in Nat are: In Zero, In $ Succ (In Zero), In $ Succ (In $ Succ (In Zero)), …

This extra layer of indirection helps formalize recursive types. But does it have any practical applications?

The first application was illustrated in the paper “Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire”
In fact, rumor has it that there was a PhD who ate so many bananas that his eyes bugged out, now he needs new lenses!
(”The Evolution of a Haskell Programmer”)

We note that NatF happens to be a functor:

> instance Functor NatF where
> fmap f Zero = Zero
> fmap f (Succ x) = Succ (f x)

Fold on lists generalizes the pattern of performing some repetitive operations on a homogeneous structure.
Why not generalize fold to any recursively defined structure?
As it turns out, we have catamorphism and anamorphism.

> cata :: Functor f => (f a -> a) -> Mu f -> a
> cata phi = phi . fmap (cata phi) . out

> ana :: Functor f => (a -> f a) -> a -> Mu f
> ana psi = In . fmap (ana psi) . psi

With bananas (cata) and lenses (ana) we can start defining many REALLY higher-order functions:

> zero :: Nat
> zero = In Zero

> elim z s Zero = z
> elim z s (Succ n) = s n

> intro z s 0 = z
> intro z s n = s (n-1)

> instance Enum Nat where
> succ = In . Succ
> toEnum = ana (intro Zero Succ)
> fromEnum = cata (elim 0 (1+))

> instance Show Nat where
> show = cata (elim “Zero” (”Succ “++))

try out:
zero, succ $ succ $ succ zero, toEnum 3 :: Nat, etc.

> instance Eq Nat where
> x == y = (fromEnum x) == (fromEnum y)

> instance Num Nat where
> (+) m = cata (elim m succ)
> (*) m = cata (elim zero (m+))
> fromInteger = ana (intro Zero Succ)

Let’s see another example: polymorphic lists.

> data L a b = Nil | Cons a b
> type List a = Mu (L a)

> instance Functor (L a) where
> fmap f = lelim Nil (\a b -> Cons a (f b))

> lelim n c Nil = n
> lelim n c (Cons a b) = c a b

> toList = cata (lelim [] (:))

> instance Show a => Show (List a) where
> show = show . toList

try out:
In Nil, In $ Cons 3 $ In $ Cons 2 $ In Nil

Another benefit is one way to address the so called Expression Problem raised by Philip Wadler:

The Expression Problem is a new name for an old problem. The goal is
to define a datatype by cases, where one can add new cases to the
datatype and new functions over the datatype, without recompiling
existing code, and while retaining static type safety (e.g., no
casts). For the concrete example, we take expressions as the data
type, begin with one case (constants) and one function (evaluators),
then add one more construct (plus) and one more function (conversion
to a string).

Whether a language can solve the Expression Problem is a salient
indicator of its capacity for expression. One can think of cases as
rows and functions as columns in a table. In a functional language,
the rows are fixed (cases in a datatype declaration) but it is easy to
add new columns (functions). In an object-oriented language, the
columns are fixed (methods in a class declaration) but it is easy to
add new rows (subclasses). We want to make it easy to add either rows
or columns.

By pushing the indirect way of defining types further, Wouter Swierstra in his paper “Data types (a la carte)” talks about an approach to decoupling rows (cases in a datatype declaration).
In the paper, every cases get their own data type declaration (rather than being packed together as an union type), and then are injected into a coproduct that acts as the final type.

Read this doc on Scribd: DataTypesALaCarte

“If you don’t understand and use monads, you are at best a quarter of a Haskell programmer. A corollary of this is that, since using monad transformers is the only (or at least the approved) way to use two or more monads together, if you don’t understand and use monad transformers you are at best half a Haskell programmer.”

“Monad transformers are like onions. At first, they make you cry but then you learn to appreciate them.”

I recently came across a monad transformer tutorial by Martin Grabmüller and found it quite enjoyable.
I felt it may be even more helpful to add some discussion on the design of the monad transformer library.
So I added two subsections (Section 2.2 and 2.5) based on my understanding.
As I myself is still learning Haskell, there could well be many errors.

The literate haskell file can be proprocessed by lhs2Tex and then used to generate a PDF.
The typesetting in the PDF file is screwed at some places for some reason I don’t know, but that’s OK.

PS: If you want to see the code of Monad Transformer Library, note that it’s in ghc’s extralibs, not corelibs.
If you’re running debian, apt-get source libghc6-mtl-dev.

There is a course that covers monad transformers.

Feb 22

截至目前,网友们喜闻乐见的很X很XX格式的流行语包括:很好很强大、很黄很暴力很傻很天真

现在,在国务院新闻办公室网络局副局长彭波同志的带领下,我们不难预见到很美很绿色、很棒很健康这些词汇也将应用到人民的日常生活当中,成为耳熟能详的和谐用语。

Feb 06

Feb 06

UPDATE Feb 11:
这里是一段解释caucus的录像:

今天Hillary Clinton受邀来到UVa,可是凭票才能进入。:(
UPDATE ENDS

美国总统候选人的初选正在紧锣密鼓的进行当中,其中各州错综复杂的规定让我丈二和尚摸不着头脑。尹文先生写了一篇很好的文章,特此转载如下:
Continue reading »

Jan 19

Do not trust the kernel build tools on macosforge if you want to build Leopard.
Their tools are outdated (as of today) and will give you tons of errors when compiling.
So, better to compile the tools (kext_tools and cctools) from source.
The “Mac OS X Internals” book gives detailed information in Section 6.10.
To fine tune the compile settings, refer to the README file in the xnu package.

After successfully compiling xnu, you need to copy your kernel to the root directory and fix the permissions:

sudo cp BUILD/obj/RELEASE_I386/mach_kernel /my_kernel
sudo chmod 644 /my_kernel && sudo chown root:wheel /my_kernel

Now, on reboot simply tell the boot loader to load your kernel instead of the default mach_kernel:
> my_kernel

PS: There are some annoying complaints about missing of ctfconvert.
ctfconvert is supposed to come with dtrace, but when I tried to build dtrace from source I got errors about missing header files from libiberty. I didn’t investigate further beyond that. THe missing of ctfconvert seems irrelevant here.

Jan 16

A good thread at LtU.

Jan 14

名字比较复杂,怕忘了,特此记之。它们是:
Sorry! Parcheesi Jenga
Jenga相对来说还是比较常见的,是个积木游戏。
严格说来,Parcheesi是源自印度的游戏。

Jan 10

Apple has hidden a poem inside OS X that warns users not to pirate the operating system.

There once was was a user that whined
his existing OS was so blind,
he’d do better to pirate
an OS that ran great
but found his hardware declined.
Please don’t steal Mac OS!
Really, that’s way uncool.

What’s the deal?

Basically, Apple wants to make it hard to run its Intel-based OS X on PCs, by AES-encrypting some key applications like Finder, Dock, and Rosetta (ha, sounds like instruction-set randomization again!). Of course, there must be something behind the scene to restore (read: decrypt) the scrambled binaries. Apple uses a kernel extension dsmos (/System/Library/Extensions/Dont Steal Mac OS X.kext) to do this job. For now this decryption is all done in software, and I suppose the binaries are statically encrypted with fixed keys. So this extra protection doesn’t help much with defeating piracy. In the future though, I’d expect Apple to make use of TPM to authenticate the hardware and do the decryption.

The major obstacle of OS X86 (aka Hackintosh), is that legacy PCs only come with BIOS, but OS X only runs on EFI. Hackers had to either patch the kernel to remove its dependence on EFI, or patch the bootloader to emulate EFI so that the vanilla kernel can run. Ironically, Apple had the same problem the other way around: it upgraded its EFI to include BIOS support so that Windows XP can run. Besides the EFI hack, SSE3 instructions in the kernel have to be patched or emulated on old CPUs.

Dec 21

Recently, there have been a lot of discussions around how WP stores authentication cookies.
It is nice that the developers are addressing this design flaw.
The change was made on Dec 17 (revision 6387).

However, this change made my blog management pages fail to show up, rendering my blog completely unusable.
I don’t know what happened, but I temporarily worked around this issue by rolling back the revision to an earlier date.
The command for that is:
svn up -r {2007-12-16}

PS: A little bit about how I ran into this problem and found the cause.
Although I was aware of the cookie bug of WP, I didn’t know the developers had already started to fix it.
I simply do a svn up every few days when I feel like it.
So, today I did a routine update and found my blog unusable.
Then, I tried every date before today and nailed down the problem in the 12-17 version.
The next thing I did was to examine the change logs and the diffs:
svn diff -r {2007-12-16}:{2007-12-17}
svn log -r {2007-12-16}:{2007-12-17}

Judging from the change logs, my immediate gut feeling was that there must be something wrong with the “new secure cookie protocol”.

Dec 02

消息来源:mitbbs.com,现正引发热烈讨论。
参见这里这里
第九条 在境外居住1年以上的中国公民,入境时应当到检验检疫机构设立的口岸艾滋病监测点进行健康检查或者领取艾滋病检测申请单,1个月内到口岸检验检疫机构或者县级以上的医院进行健康体检。
第十条申请出境1年以上的中国公民以及在国际通航的交通工具上工作的中国籍员工,应当持有检验检疫机构或者县级以上医院出具的含艾滋病检测结果的有效健康检查证明。
第十一条申请来华居留的境外人员,应当到检验检疫机构进行健康体检,凭检验检疫机构出具的含艾滋病检测结果的有效健康检查证明到公安机关办理居留手续。

据说以前一直到90年代的时候都是要检查的,扎一针收15美元,后来终于取消了,不知何故此规定又死灰复燃了。

有些好玩的八卦,节选如下:
一开始人人平等,没多久老外有意见,不能查了就查拿中国护照的。又过了一阵,拿绿卡的意见反映到教委了,这批人也不能查。最后就是拿中国护照没绿卡加上港澳台的。那年出国开会刚回来,交健康申报表的时候那小姑娘头的不抬:那边抽血去。嘿,小那谁,麻烦您抬一下头,上个月办学习班的时候还老师老师的那。
虎老师没被抽血,别人就没那么幸运了。国家农业部长到中亚转一圈,回来时候考察一下边贸吧,从新疆那山口进来。到那儿抽血,部长也抽?人家那里铁面无私,抽。回来跟卫生部抱怨,让卫生部糊囔过去了。本来吗国家的检疫规定哪一条写了部长以上就可以不抽血检疫了?
这件事刚过去,广东那边又出事了,这回被抽的是李嘉诚的保镖。按理说不算什么呀,部长都抽了几个马仔算啥?李超人有意见,一个电话老邓家里去了:你们这样我的人还怎么来来往往?以后广东的关我不进了,汕头大学那一个亿我也不出了。这一下雷厉风行,不光广州的老周挨批评,抽血的规定马上取消。那几天包括部里是个人都眉开眼笑的,检疫那夥人民愤太大。
下飞机的不能抽了怎么办?抽上飞机的。于是中华人民共和国就成为世界上最国际主义的,尽管十几亿人艾滋病感染者当时一百个都不到,每个出国的都要抽血化验。于是国家的卫生检疫法就标明了防止传染病由国外传入或者由国内传出。
出国留学的不算多,偷渡的不少可是人家不过关,因此主要是劳工。几大公司招农民去非洲当劳工,出去的起码查了几十万,一个阳性都没有。回来的时候还要查,阳性的就开始出现了。于是国境卫生检疫终于出成绩,成功地发现艾滋病喽。发现了还得让他进来,因为这本来就是国家派出去的不能再把他送回非洲去,“防止传染病由国外传入” 就不要细琢磨了。