by QuickMouse quickmouse@263.net
前两天居然碰到一个及其郁闷的事情:从美国寄过来的服务器太新了,Redhat ES3的版本居然有很多的地方不支持它。先是不支持ICH7的硬件,导致没法使用SATA硬盘。等把这个问题解决了,又发现关机没法自动切断电源。
服务器是DELL的Power Edge 850,1U的机器,打算拿来上架用的。经过检查发现这个机器的BIOS不支持APM,仅仅支持ACPI。再回去检查ES3的内核,发现2.4.21-4的内核不支持ACPI,只支持APM。虽然/usr/src/linux里的kernel source有ACPI的代码,可就是没法弄到内核里面去。总不能把机器卖给用户,命令行上有shutdown却不能切断电源吧?
只好抱着试试的态度把ACPI关于power off的那段看了看。跟着2.6.9的内核代码走了一下,发现真是麻烦,不是一点点的麻烦。ACPI除了一堆的定义以外最罗嗦的是所谓的名字空间,namespace。反正到现在都没有看懂这个namespace是怎么搞定的。但是ACPI对于关机的部分看似麻烦,其实也就是几句话。即进入_S5_的状态。首先从PM1Control寄存器读出数据,然后清掉SLEEP_EN位和SLEEP_TYPE位,接着把数据中对应_S5_的sleep_type_a位或上,写回寄存器,再或上SLEEP_EN位,再写回寄存器就ok了。
不过这个方法目前只能暂时解燃眉之急。因为取得寄存器的地址需要通过低地址0xe0000~0xfffff读取到ACPI的RSDP,接着从其中得到FADT的位置,从而读取到PM1Control寄存器的端口。另一方面需要通过RSDP得到RSDT的地址,从RSDT当中得到namespace,并对其进行解析,以便获得sleep_type_a的数值。这里有几个问题以后需要解决,其一如何得到HIGHMEM当中的数据,这个暂时好像不能从/dev/mem当中读取;其二是如何解析namespace,2.6.9的kernel代码看了很久也没看明白,真麻烦 :(
看来同志仍须努力啊。
Trackback: http://tb.donews.net/TrackBack.aspx?PostId=669631