到 PPI 半年了,COREMU 终于在 sourceforge 上发布了。COREMU 的主要工作是王肇国(我本科同学,现在也在 PPI)完成的,其他开发人员可以在 PPI 的 COREMU 项目主页上找到。
简单说 COREMU 把 Qemu 并行化了。原先的 Qemu 只能使用一个物理 CPU,COREMU 则是使用多个物理 CPU 来模拟虚拟 CPU。
目前 COREMU 只能在 x86_64 Linux 系统上运行,支持模拟 x86_64 和 ARM Cortex A9 MPCore。在我们的测试用的 4 核系统上能模拟出 255 核,并且成功运行 Linux。
在这里宣传一下。半年来一直与 bug 做斗争,现在终于发布了,希望 COREMU 能够发挥些作用。有什么问题的话欢迎发邮件联系 :) cyfdecyf at gmail dot com
推荐一篇 IBM developerworks 上的文章,Linux initial RAM disk (initrd) overview,很详细一篇介绍,包括了内核里哪些函数涉及到启动过程。另外 man initrd 也有相关的介绍。
不过文章的内容已经有点过时,内核启动过程调用的函数发生变化,默认执行的 initrd 里的程序也从 /linuxrc 变成 /init。另外现在 Linux 发行版大多用 cpio 格式的 initrd),这篇文章介绍的是 ext2 格式的。如何提取和创建 cpio 格式的 initrd 可以参考下面这篇文章Debian Lenny 5.0.1 PXE initrd update,主要的命令如下:
# 提取
zcat ../initrd.gz | cpio -iv
# 创建
find . -print0 | cpio -0 -H newc -ov | gzip -c > ../initrd.gz
如果有 Linux 内核源码的话还可以参考 Documentation/initrd.txt,里面有启动过程的介绍和创建和提取 initrd 的说明,内容比 man initrd 更详细,不过也有一点过时。
zsh 下新装了一个软件,tab 补全时新装软件的命令不会出现。以前的解决办法是执行 export PATH=$PATH 让 zsh 去更新缓存。
今天在 Pylons 的 activate 脚本里看到了一条 builtin 命令 hash (man zshbuiltins),这条命令可以直接修改 command hash table。$PATH 路径下的内容发生变化时可以用 hash -r 来更新。
screen 提供多个 shell 来回切换是很方便,不过有时会忘记应该切换到哪个 window。如果可以根据执行的命令和当前目录来动态设置 window title 的话来回切换时就会可以方便的找到目标 window。其实 zsh-lovers 里就有说明。
screen 可以通过 echo 特殊的字符来设置 window 的 title,而 zsh 有两个特殊的函数 preexec 和 precmd,前者在用户输入命令按下回车但 zsh 还未执行命令前被调用,后者在 zsh 更新 prompt 前被调用(具体说明见 man zshmisc)。把 zsh 和 screen 的功能结合起来就可以在执行命令时把 screen window 的标题设置成当前执行的命令,而在 zsh 等待用户命令时,将 title 设置成当前目录。
先贴 zsh 的相关配置,PS1 的配置不喜欢可以去掉。
autoload colors
colors
case $TERM in
screen*)
function sctitle() { print -Pn "\ek$1\e\\"}
function precmd() { sctitle "%20< ..<%~%<<" }
function preexec() { sctitle "%20>..>$1%< <" }
export PS1="%{${fg[cyan]}%}[%D{%H:%M} %20<..<%~%<<]%{$reset_color%} "
;;
*)
export PS1="%{${fg[cyan]}%}[%D{%H:%M} %n@%m:%20<..<%~%<<]%{$reset_color%} "
;;
esac
有时命令或者当前目录很长,screen 的 status bar 宽度会不够,zsh 有内置的截短字符串的功能,用 %20< ..<%~%<< 限制目录最长为 20 个字符,把左边的多余字符去掉,截短后用两个点表示,%~ 表示当前目录,如果包含 HOME 目录则用波浪号表示,%<< 标志截短操作的结束。%20>..>$1%< < 类似,preexec 的第一个参数是完整的命令行输入,同样截短成 20 个字符,不过是去掉右边的多余字符。sctitle 就是打印特殊字符来设置 screen window title 的函数。
接下来是 .screenrc。
startup_message off
# use visual bell
vbell off
# replace Ctrl-A by `
escape ``
# set a big scrolling buffer
defscrollback 5000
# Set the caption on the bottom line
caption always '%{= kg}[%{G}%H%{g}][%= %{= kw}%?%-Lw%?%{+b r}(%{y}%n %t%?(%u)%?%{r})%{= w}%?%+Lw%?%?%= %{g}][%{B} %d/%m %{W}%c %{g}]'
# %{= kG} first set default color (=), back ground black (k), foreground green (G)
# [%{G}%H%{g}] color bright green, host name (%H), color green
# [%= ...] padding (%=), window left to the current focus window if exists,
# (current focus window with color yellow), window to the right of the
# focus window
# [%{B} %m/%d %{W}%c %{g}] color bright blue, month/date (%m%d), color bright white,
# current time(%c), color green
# open several terminals at startup
screen 5
screen 4
screen 3
screen 2
screen 1
因为我用 vim,而且我觉得切换 window 时要按数字键,所以我把 escape 设置成 back tick。这个配置最关键的就是 caption 了,忘记从哪里 copy 过来的了(用 hardstatus 的话 screen 的消息也是在 hardstatus 上显示,所以我喜欢用 caption)。我直接在配置文件里加了点注释,语法很恶心,我都看晕了。关于 caption/hardstatus 里的转义字符说明见 man screen 的 string escape 一节。
试试看吧,这个配置还是很炫而且也蛮实用的。
Unix 的管道实在是一个好用的东西,利用管道可以很方便的把一些简单的工具结合起来完成一些复杂的任务。这里不想解释什么是 Unix 的管道,也不举具体的例子来展示管道的方便之处,只是想通过一个现实中管道的例子来说明为什么管道是好东西,为下一篇文章写管道的思想在写程序时的应用做准备。
正如其名字暗示的,Unix 的管道其实跟现实生活中的管道非常类似。要注意的是这里讨论的管道不只是为了传送液体(或者气体),还可能对液体进行一些处理。构成管道最主要的东西其实就是一节一节管子/过滤器。液体从管道的一端流入,经过各个过滤器的处理,从另一端流出时可能已经是另外的液体了。流出什么样的液体取决于流入的液体和组成管道的过滤器,很显然决定管道功能的是构成管道的每一个过滤器。
现在假设我要进行污水处理,污水里有沙子,还有各种溶解在其中的物质。我可以做一个只含一个过滤器的管道,这个过滤器可以把沙子和溶解物一次性全部过滤掉。

污水处理-一个过滤器
但如果再来一批污水,只含有沙子,那用之前的这个过滤器显然太浪费了;或者,新的污水含有原先污水中没有的溶解物,那只用原先的过滤器是不够的。
比较好的做法是用一个过滤器过滤沙子,每种溶解物用一个过滤器(现实中的污水处理当然不可能这么简单,这里只是以此为例子),污水里需要过滤什么就在管道上加上什么过滤器。

污水处理-多个过滤器
这样做的好处有几个:
- 每个过滤器做起来都比较简单,因此每个过滤器的制造成本降低了
- 过滤器更可能被重复使用
- 易于处理各种不同的污水,只需要重新组合下过滤器就可以了,而不需要为每种污水设计一个过滤器
Unix 的管道其实就是模仿了现实生活中的管道,只不过流经管道的是数据(多数时候是文本),构成过滤器的是 Unix 下的那些小工具。Unix 中使用管道的好处与污水处理的例子里是类似的
- 每一个工具只完成一个很简单的任务,因此每个工具都很容易实现
- 每个工具更有可能被用到,而工具重用的成本几乎为 0
- 更加灵活(见下面的例子)
有些管道的用法真是让人感叹,比如现在的 Linux 版 QQ 收到消息是没有声音的,有人用
tcpdump, sed, aplay 组合自己山寨了这个功能出来。还有听小百合的 lv 说他用 mplayer,gzip, netcat 等工具做了一个视频监控系统出来。QQ 的那个例子做法如下:
sudo tcpdump -i ppp0 -l udp src port 8000 and ip[0x20]=0x17 | \
sed -u '/.*$/s//aplay msg.wav/' | sh
前面说过,管道的功能是由过滤器决定的。光由操作系统提供一个构建管道的机制是没有什么大用处的。Unix 管道的强大关键还在于那些小工具的设计。
从一开始,那些小工具的设计就考虑到了通过管道来配合使用(我觉得应该是管道的存在影响了这些工具的设计,而不是反过来,不知道 Unix 的历史是否的确如此),因此这些工具有几个显著的特点
- 功能简单,有的工具简单到单独看觉得根本就没什么用
- 以文本作为交互的数据,人能读,程序也能读
- 功能上尽可能正交,每个工具完成自己的任务,不跟其他工具的功能重复(awk,sed 这样的程序功能上还是有些重复的,当然有时候一件事情能用多种方式完成也是好事。)
软件开发的成本与其复杂度不是线性关系,再加上每个工具都得到了更多的重用,组合起来还可以实现新的功能,考虑到这几点,使用管道可以节省的系统工具开发成本就不是一点点了。当然,光节省成本而不好用那也没意义,但事实是管道很有用。
每个工具都只执行简单的任务也有一点麻烦,一些相对简单的任务也可能需要调用好几个工具,此时可以把常用的命令组合可以存到脚本里。这就相当于把管道存起来,以后直接用这个管道而不用再重新把过滤器搭起来了。另一个方面是用户需要花相对来说比较多的时间来学习这些工具,对于经常要使用电脑的人来说,考虑下学习这些工具以后能得到的收益,花些时间是完全值得的。(对那些偶尔使用的人来说可能就不划算了。)
关于管道和 Unix 的设计哲学,在 Eric S. Raymond 的 "The Art of UNIX Programming" 中有着更多的介绍。(该死的 GFW 把 Raymond 的主页都墙了。)
Unix 管道的好处我们已经看到了,那可不可以在写程序时也使用这样的思想呢?当然可以!下一篇文章我就要谈在程序中如何使用管道的思想。以 Python 为例,介绍 generator,还有为什么 lazy evaluation 也是好东西 :)
昨天用 python 写 insertion sort 练练手,在用 for 循环的时候遇到了一点小问题。
Dive Into Python 这本书的确不适合初学程序设计的人,我看完第 6 章都没有看到 python 中的 while 语句,所以最初我用了两个 for 循环来实现,xrange 也是我看别人的程序的加上查文档才知道怎么用的。对有经验的人来说这样也没什么不好,python 的语言和类库参考都不错,直接查也很方便。
最初的实现出错了,代码如下:
def insertion_sort(list):
for i in xrange(1, len(list)):
key = list[i]
for j in xrange(i - 1, -1, -1):
if key < list[j]:
list[j + 1] = list[j]
else:
break
list[j + 1] = key
return list
随便试了几个就错了,很奇怪为什么会出错。后来才意识到使用 for 遍历的是一个列表,如果没有 break,遍历完之后 j 是列表中的最后一个元素 0,而不是 -1。如果因为列表遍历完成而非 break 中断循环,则最后应该执行 list[0] = key,但实际执行的是 list[1] = key。
这样就有个问题,如何判断 for 循环是正常遍历结束还是被 break 中断的?在 C 中写 for (j = i - 1; j > -1; j--) 最后循环结束的时候 j 为 -1,所以检查 j 的值就可以了。但在 python 里面,j 最小只可能到 0,循环结束时 j 为 0 可能是因为 key >= list[j] 而 break,也可能因为 0 是最后一个元素而终止循环,所以通过检查 j 的值是没法做到的。(因为 python 中 for 的作用是遍历列表等容器,所以不能让 for 与 C 中有相同的行为。)
查了下语言参考,发现 for 语句可以跟一个 else 块,觉得有点奇怪,还没有见过哪个语言有这样的语法的。文档说 else 后面的块在循环条件为假时执行一次,但如果 for 后面的块中因为 break 导致循环结束则这个块不执行。一开始觉得这个 else 没什么用,除非死循环,否则条件总是会变为假,那直接把代码放在 for 外面不就可以了。后来想到这个特性正好可以用来判断循环终止的原因,用个条件变量即可,在 else 代码中改变这个条件变量,然后在后面的代码中检查条件变量的值即可。
最后的代码如下:
def insertion_sort(list):
for i in xrange(1, len(list)):
key = list[i]
outbound = False
for j in xrange(i - 1, -1, -1):
if key < list[j]:
list[j + 1] = list[j]
else:
break
else:
list[0] = key
outbound = True
if not outbound:
list[j + 1] = key
return list
当然用一个 while 循环就可以不用这么麻烦了,不过我就是想知道用 for 该怎么解决这个问题。
PS:
wordpress 有没有什么贴代码用的插件?
After using Sawfish for some time and seeing the amazing new effects provided by compiz-fusion, I switched to compiz-fusion. (I switch window managers about every two months ;-) ) Every thing goes smoothly. The installation of compiz-fusion on Arch is simple, no extra configuration for X is needed since I’ve used beryl before. It just works :-)
One feature I love for compiz & beryl is window switching: You get a preview of each window so it’s much easier to select the desired window. However, the switching operation is not quite smooth on my box no matter what window switcher I am using. I tried to change the configuration for the shift switcher and found that using none overlay icon dramatically increases the performance. I tried this on other window switchers and it also works. Anyway, the overlay icon is not very useful to me, so I can still be happy without it.
Another option I suggest to toggle on is Mipmaps. You will get much better preview without any noticeable performance degeneration.
看 Adam Leventhal 的 Blog 时,在他讲 Debian 的创始人 Ian Murdock 到 Sun 工作的那篇文章中跳到了 Ian 的 Blog 去了。
在他 Blog 的 about 里面他提到 Debian 其实是他妻子的名字和他自己名字的组合,他妻子叫 Debra。令我佩服的是 Ian 在 1993 年创建 Debian,而他在 Purdue 获得科学学士学位是在 1996 年,那个时候 Debian 就叫 Debian?如果是的话他和他妻子在他大学二年级就应该已经认识了。当然佩服的不是他们从大二就开始恋爱,而是他大二就已经开始创建一个 Linux 发行版了,而我大二才开始接触 Linux。(abcx 看到这句话又要狂笑了吧……)
关心自由软件的人应该都知道 Linus 对 GPL v3 不是非常支持。今天看了 Linus 的这封邮件以后大概明白了他的理由。
…
Laws (like copyright law) and legal issues, on the other hand, are fundamentally *not* about “personal” things, they are about interactions that are *not* personal. So laws need to be fundamentally different from morals. A law has to take into account that different people have different moral background, and a law has to be _pragmatic_. So trying to mix up a moral argument with a legal one is a fundamental mistake. They have two totally different and separate areas.
The GPLv2 is a *legal* license. It’s not a “moral license” or a “spiritual guide”. Its raison-d’etre is that pragmatic area where different peoples different moral rules meet. In contrast, a persons *choice* to use the GPLv2 is his private choice. Totally different. My choice of the GPLv2 doesn’t say anything about my choice of laws or legal issues.
…
License 是 legal issue,它会对许多人产生影响,必须考虑实际的问题。而 RMS 在 GPL v3 加入道德上的东西,但道德是很个人的事情,法律跟道德完全是两码事。Linus 在邮件的后面还举了纳粹士兵、甘地、罗宾汉的事例来说明 moral 的未必就是 legal 的,因此在 license 中混入道德上的东西从根本上来说就是一个错误。
还没有看过 GPL v3,有时间要去看看。对这些争论以我的阅历没有资格去做什么评论,能做的只能是关注而已,并做些思考。
Tags:
reddit 今天有两个相关的 post。
第一篇讲 Linux 上的 linux-gate.so.1 是怎么回事,其实也就是 sysenter 和新的系统调用方式了,我之前也遇到过。
第二篇的作者看了这篇文章以后发现他的 64bit 的系统上没有 linux-gate.so.1,于是就开始了他的探索,最后发现在 x86-64 上只有 syscall 一种系统调用方式。我自己的机器是 64bit 的,但是装的操作系统是 32bit 的,所以表现和 32bit 的是一样的。
呵呵,看 Blog 长见识了,不是第二篇文章的话还不知道 syscall 呢 :-)
Tags:
Recent Comments