Plan9 Files -- Notes of Introduction to OS Abstractions Using Plan 9 from Bell Labs(IV)


2.1 Input/Output

Most of the times, standard input, standard output, and standard error go to /dev/cons. This file represents the console for your program.It is the interface to use the device that is known as the console, which corresponds to your terminal.The file interface provided for each process in Plan 9 has a file that provides the list of open file descriptors for the process. For example, to know which file descriptors are open in the shell we are using we can do this.

 term% cat /proc/$pid/fd/usr/glenda
 0 r  M   40 (0000000000000001 0 00)  8192       47 /dev/cons
 1 w  M   40 (0000000000000001 0 00)  8192     3506 /dev/cons
 2 w  M   40 (0000000000000001 0 00)  8192     3506 /dev/cons
 3 r  M    8 (000000000000166b 2 00)  8192      512 /rc/lib/rcmain
 4 r  M   40 (0000000000000001 0 00)  8192       47 /dev/cons

Each time you open a file, the system keeps track of a file offset for that open file, to know the offset in the file where to start working at the next read or write.
The offset for a file descriptor can be changed using the seek system call.

2.2 Write games

A Chan(or Channel) is a data structure, which contains all the information needed to let the kernel reach the file server and perform operations on the file. A Chan is just something used by Plan 9 to speak to a server regarding a file. This may require doing remote procedure calls across the network, but that is up to your kernel, and you can forget. There is one Chan per file in use in the system.

The size of a file corresponds to the highest file offset ever written on it. All the bytes that we did not write were set to zero by Plan 9.
seek(fd, 0, 2); // move to the end
append only permission bit :
; chmod +a /sys/log/diagnostics
; ls -l /sys/log/diagnostics
a-rw-r--r-- M 19 nemo nemo 0 Jul 10 01:11 /sys/log/diagnostics
+a permission bit guarantees that any write will happen at the end of existing data, no matter what the offset is.
Doing a seek in all programs using this file might not suffice. If there are multiple machines writing to this file, each machine would keep its own offset for the file. Therefore, there is some risk of overwriting some data in the file.
The create system call creates one file.
The system call remove removes the named file.
The system call access to check file properties.

2.3 Directory Entry

File metadata is simply what the system needs to know about the file to be able to implement it. File metadata includes the file name, the file size, the time for the last modification to the file, the time for the last access to the file, and other attributes for the file. Thus, file metadata is also known as file attributes.
Plan 9 stores attributes for a file in the directory that contains the file. Thus, the data structure that contains file metadata is known as a directory entry. A directory contains just a sequence of entries, each one providing the attributes for a file contained in it.
To obtain the directory entry for a file, i.e., its attributes, we can use dirstat. This function  uses the actual system call, stat, to read the data, and returns a Dir structure that is more convenient to use in C programs. This structure is stored in dynamic memory allocated with malloc  by dirstat, and the caller is responsible for calling free on it.
Because directories contain directory entries, reading from a directory is very similar to  what we have just done. The function read can be used to read directories as well as files. The  only difference is that the system will read only an integral number of directory entries. If one  more entry does not fit in the buffer you supply to read, it will have to wait until you read again.
The entries are stored in the directory in a portable, machine independent, and not amenable, format. Therefore, instead of using read, it is more convenient to use dirread. This  function calls read to read the data stored in the directory. But before returning to the caller, it  unpacks them into a, more convenient, array of Dir structures.
The function dirwstat is the counterpart of dirstat. It works in a similar way, but  instead of reading the attributes, it updates them. New values for the update are taken from a Dir  structure given as a parameter. However, the function ignores any field set to a null value, to  allow you to change just one attribute, or a few ones. Beware that zero is not a null value for some of the fields, because it would be a perfectly legal value for them. The function nulldir  is to be used to null all of the fields in a given Dir.

2.4 Bio

The bio(2) library in Plan 9 provides buffered input/output. This is an abstraction that,although not provided by the underlying Plan 9, is so common that you really must know how it works. The idea is that your program creates a Bio buffer for reading or writing, called a Biobuf. Your program reads from the Biobuf, by calling a library function, and the library will call read only to refill the buffer each time you exhaust its contents.

#include <u.h>
#include <libc.h>
#include <bio.h>
static void
    fprint(2,"usage: %s [-b bufsz] infile outfile/n", argv0);
main(int argc, char* argv[])
    char* buf;
    long nr, bufsz = 8*1024;
    Biobuf* bin;
    Biobuf* bout;
    case 'b':
        bufsz = atoi(EARGF(usage()));
    if (argc !=2)
    buf = malloc(bufsz);
    if (buf == nil)
        sysfatal("no more memory");
    bin = Bopen(argv[0], OREAD);
    if (bin == nil)
        sysfatal("%s: %s: %r", argv0, argv[0]);
    bout = Bopen(argv[1], OWRITE);
    if (bout == nil)
        sysfatal("%s: %s: %r", argv0, argv[1]);
    for(;;) {
        nr = Bread(bin, buf, bufsz);
        if (nr < 0)
        Bwrite(bout, buf, nr);



regexp -line逐行匹配

以前没注意到Tcl/Tk的正则表达式命令regexp还有一个逐行匹配的选项-line(其实是三个-line, -lineanchor和-linestop,第一个是后两者的综合),因此碰到需要在多行内容中匹配某一行的中的某字符(串)是总是不得不用AWK,PERL等其他工具,现在有了-line,直接regexp -line <pattern> <var>就搞定了!

Plan9 Environment Variables -- Notes of Introduction to OS Abstractions Using Plan 9 from Bell Labs(III)

interface for using environment variables in Plan 9 is a file
All interfaces of environment variables can be found
under /env.

obtain the value for a environment variable, from a C program, we can
use the
system call. If the variable is not defined,
returns a null string. A related call is
which accepts a name and a value, and set the corresponding
environment variable accordingly.

#include <u.h>
#include <libc.h>
void main()
char * path;
sysfatal("path not defined!");
print("PATH is %s /n", path);



some cases it is convenient to define an environment variable just
for a command. This can be
done by defining it in the same command
line, before the command, like in the following exam-ple:

; temp=/tmp/foobar echo $temp
; echo $temp


Environment Variables:

is updated by the shell once it finds out how it went to the last
command it executed.

is a list of paths where the shell should
look for executable files
to run the user commands.

contains the user name

contains the machine name.

file /dev/text represents
text shown in the window (when used within that window). To make
a copy of your shell session,
you already know what to do:

cp /dev/text $home/saved

same can be done for the image shown in the display for your window,
which is also represented as a file, /dev/window.
This is what we did to capture screen images .


Notes of Introduction to OS Abstractions Using Plan 9 from Bell Labs(II)

@page { margin: 0.79in }
P { margin-bottom: 0.08in }

section 1 is for commands, section 8 is fo
not commonly used by users (i.e., they are intended to administer the
system), and

2 is for C functions and libraries.


read a manual page found at a particular

you can type the section number and the page name after the man
command, like in


man 1 ls


used to search manual.


displays the signature, i.e., the prototype for a C function
documented in section 2 of the manual.


to print the name of the user who last modified a file, along with
the file name.


accepts more than one (source) file name to copy to the destination
file name.

can see a dump of the bytes kept within that file using the program
(hexadecimal dump). This program reads a file and writes its contents
so that it is

for us to read. Option
to print the contents as a series of bytes:


xd -b TODO

63 6f 70 79 20 6d 6b 64 65 70 20 66 72 6f 6d 20

6c 65 66 66 65 20 28 2d 72 20 66 6c 61 67 29 0a



the program prints the character for each byte when feasible:


xd -b -c TODO

63 6f 70 79 20 6d 6b 64 65 70 20 66 72 6f 6d 20

c o p y m k d e p f r o m

6c 65 66 66 65 20 28 2d 72 20 66 6c 61 67 29 0a

l e f f e ( - r f l a g ) /n





command nm (name list)
displays the names of symbols (i.e., procedure names, variables) that
are contained or required by our object and executable files.


Plan 9的Manual和Wiki上面关于网络配置的介绍,都是以server为原型,前提条件是这些server都会有固定的IP地址,集成DHCP、DNS乃至自己的子网。可我的Plan 9是在VirtualBox4.0的虚拟机上装的,Host是Fedora 14,通过家用无线路由器上网,IP地址动态获取,不可能有固定IP和固定的DNS、Gateway等等。因此的方法根本无效。

VirtualBox4.0安装Plan9时,由于没有选择正确的网卡,Plan9使用了默认的Am79C970A网卡,而Plan 9自身并没有该网卡的驱动。要使用plan9自带的网卡驱动而无须自己编译内核的方法就是在plan9.ini中更改默认网卡的类型,可以参考。plan9.ini存储在9fat中,默认不挂载到fossil,因此需要在Rio的窗口中输入命令“9fat:”挂载9fat,然后cd /n/9fat/,编辑plan9.ini,加入一行“ether0=type=igbe”。同时VirtualBox的网卡也要选择NAT --> Intel Pro1000系列。重启Plan9之后,可以通过ip/ipconfig检查网卡是否能正常工作——如果不报错,证明网卡正常。


ip/ipconfig -D -d ether /net/ether0


尝试更改/lib/ndb/local多次,仍然无效。无奈之下打开/rc/bin/termrc,发现其中依然有了网络配置的内容,只是默认被注释掉了,去掉if以及ip/ipconfig两行前面的#后,重启Plan 9,网络竟然正常了!

# start IP on the LAN, if not already configured.  diskless terminals
# are already configured by now.  It's commented out to avoid a long timeout
# on startup waiting for DHCP.
# If your site provides DHCP service,
#if(! test -e /net/ipifc/0/ctl)
#	ip/ipconfig
# Otherwise, see /cfg/$sysname/termrc (/cfg/example/termrc is an example).












Plan 9安装Go


首先是在term中输入9fs sources, 然后cd到/n/sources/contrib下,参照Plan 9的contrib index,找到"From fgb's contrib"的python用户名。

% 9fs sources
% /n/sources/contrib/fgb/root/rc/bin/contrib/install fgb/contrib
% contrib/install -f bichued/python
% contrib/install -f bichued/hg


% bunzip2 python.iso.bz2
% 9660srv -f python.iso
% 9fs 9660
% cd /n/9660
% cat README

然后参照README中的说明来安装python。需要注意的是在执行setup脚本之前,应该9fs kfs,否则会出错。



% hg clone -r release go


plan9 hg error

后来在contrib index中找到了contrib/ericvh目录下的go-plan9,尝试用dircp拷到自己目录下,总是会报各种各样的问题。几次失败之后,决定用tar cvf $home/go.tar /n/sources/contrib/ericvh/go-plan9试试。



在VirtualBox的Plan 9虚拟机中按照contrib/install来安装Python, Mercurial和执行hg clone go时并未出现任何错误。看来9vx和Plan9比起来还是很不稳定的。可惜的是Go默认的编译脚本是bash写的,而Plan 9只支持rc,看来只能等将来有时间再研究如何把bash的脚本改成rc了。

Plan 9中使用Abaco

Abaco是Plan 9的一个非常原始的浏览器,要想使用它,必须首先按照下列步骤:

  1. term%  webcookies (可选,如果webfs可以直接运行的话,不必运行webcookies)
  2. term%  webfs
  3. term%  abaco


term% abaco
*abaco: can't initialize webfs: '/mnt/web/ctl' does not exist*


一个困扰了我很久得问题:xterm中<backspace>或<delete>键无法删除敲错的字符,只能使用Ctrl+H或者VI删除模式,很不方便。操作系统是Red Hat Enterprise Linux 5.5。




stty erase <backspace>


当然在设置之前要先用stty -a查看erase=XX是不是已经设置成了<backspace>,即^?。


如果不想每次打开一个新的xterm之后都要手动输入stty erase <backspace>,可以在.env中加入


stty erase ^?








The Linux Hall of Shame
version 0.6 
Last updated 11/18/2008 13:08:02



These pages were originally written to address a nagging problem which bothered many people using Linux. It has to do with the default behaviour of the BackSpace and Delete keys, which did not behave as expected. The goal of this document was and still is to make [<---] (i.e. the backspace-key on your keyboard) to erase to the left, and make [Delete](i.e. the delete-key) erase under the cursor. It seems all Linux distributions I am aware of have effectively dealt with the issue by now. However still lots of people visit these pages, presumably because the information presented here is applicable to other UNIX flavors and cross-platform environments and applications.

The keymapping problem can be traced back to the time when computers used punched tapes. The only way to correct a wrongly punched character was to punch additional bits in the tape (or rather, punch additional bits _out_ of the tape). Characters with all the bits punched were treated as deleted characters. See 'man ascii' for a list of the ASCII characterset, you'll see that DEL, (octal 177, decimal 127 and hexadecimal 7F) is the one with all the bits punched in (the ASCII code with the highest value). To be able to overwrite a character it is necessary to undo the feed between the characters first. For this the ASCII BS (octal 010, decimal 8, hexadecimal 08) was used. So to erase the last-typed character, you would have to press first BS to move back one character, and then DEL to delete the character. In newer computers either BS or DEL was chosen to move back and delete in one press.

The question to use BS or DEL was (and is...) just a matter of choice, just as different operating systems chose different ways to represent newlines, which was done by first issuing a carriage return (CR) and then a line-feed (LF). UNIX chose ASCII LF (hexadecimal 0A) to do both at the same time, Macintosh chose CR and MS-DOS both. Unfortunately, in the BS-DEL case, Linux ended up with two possibilities.

The essential point in this issue is to go for one way consistently. This page describes a way to consistently use DEL to erase the previous character, the page called The Alternative Way describes a way to consistently use BS. On the latter page there are some tips which may be useful regardless of what approach you take.

Since starting this page in 1997, most distributions have sorted out the issue. Still, some of the fixes/workarounds can be useful when working in a mixed environment, or when working on older systems. And evidently, given the number of hits the page still gets, it's a situation common to more then a few people ;-)

If you miss an application on this page, it's either because the keys are ok in the application ("If it ain't broken, don't fix it"), or because I don't know about it. In either case, don't hesitate to mail me about it.

Throughout this document, [<---] and [Delete] are used to denote the physical keys on the keyboard, the things you actually press to erase characters. There are a few things to keep in mind: ASCII values can be represented in several equivalent ways. This means that ASCII BS is equivalent to 010 in octal, 8 in decimal and 08 in hexadecimal notation. To show that a number is in hexadecimal notation '0x' is put in front of it. Finally it should be noted that BS and DEL are known to applications by their corresponding control sequences. To sum it up:

ASCII BS == 0x08 == ^H
ASCII DEL == 0x7f == 0177 == ^?

The reason the keys (generally) do not work out-of-the-box is partly lack of configuration (as you will see later, simply creating .inputrc/.cshrc already helps a lot) and a more difficult issue which I will try to describe below.

The linux console emulates a vt220 terminal which has the following key-mapping:

Linux console/VT220
Key            KeySymName       Console characters
  Ctrl+H   --->  Control_H  --->  ASCII  BS (0x08)
  [<---]   --->  Backspace  --->  ASCII DEL (0x7f)
  [Delete] --->  Delete     --->  "/e[3~"

Note 1: BS (0x08) is equivalent to ^H, which is left to be used by applications (e.g. for help menus in emacs, but it could be anything). DEL is equivalent to ^?, or 0177 (octal) and 0x7f (hex) and "/e[3~" will show up in your xterm (using the ^v-trick) as ^[[3~. Xterms on the other hand, emulate the vt100 terminal, which didn't have a [Delete]. It did have a [<---] which generated ASCII BS (but it was in an awkward position and did not serve as rubout).

Key            KeySymName       Console characters
  Ctrl+H   --->  Control_H  --->  ASCII  BS (0x08)
  [<---]   --->  Backspace  --->  ASCII DEL (0x7F)

Now here's how xterm emulates the VT100 terminal:

Xterm's emulation of VT100
Key            KeySymName       Console characters
  Ctrl+H   --->  Control_H  --->  ASCII  BS (0x08)
  [<---]   --->  Backspace  --->  ASCII BS (0x08)
  [Delete] --->  Delete     --->  ASCII DEL (0x7F)

It may be clear that by default the keys are mapped differently on the console and in xterm. This would be ok if it weren't for the fact that while on the console ^H is free to be used by applications, in an xterm it is not (instead it's mapped to the [<---] key). Differences between terminal types are generally dealt with by the terminfo database (see below), mapping terminal specific strings to the correct key. However, in this case, the ^H should not be mapped. Terminfo is not enough, the settings of the terminal (xterm) have to be modified such that ^H is not used.

In my previous attempt at working around the problem, I put most of my effort in trying to map all keys to suit xterm's vt100 emulation. However, I now propose another way to deal with the problem. This basically means getting xterm to work with the consoles' default settings: [<---] will do ASCII DEL (0x7F, or ^?), and [Delete] will do "/e[3~". This way ^H is not used for any terminal specific functions, it can be used by applications.

There is no clear solution, but there are some pretty good work-arounds. What is needed is to tell xterm how to handle the keys, and then to tell other applications about it (i.e. how xterm handles the keys). The terminfo database contains descriptions of how all kinds of terminals handle (terminal specific) keys. Applications look at the TERM variable, and then search the corresponding database for the value of a certain key, e.g. the left-arrow key, and find the string that corresponds to it. This means that the strings in the database had better correspond to your current xterm settings. This involves modifying xterm's terminfo entry.

When you change the keymapping on your own system, you may have problems when accessing other systems. Luckily, this can be worked-around by a script which changes the input it receives to the output that is expected by the application (telnet, rlogin). See the telnet section.

This table summarizes the modifications needed in the different environments, and the tools it is done with:

      Configuration files           
Terminfo          -          terminfo                  infocmp/tic   
Xterm  ~/.Xdefaults (*)  /etc/X11/Xresources  xrdb ~/.Xdefaults (*)
X               -   /etc/X11/xinit/.Xmodmap (**)   xmodmap .Xmodmap  
Bash      ~/.inputrc    /etc/inputrc    export INPUTRC=/etc/inputrc  
Tcsh      ~/.cshrc      /etc/cshrc           bindkey (shellcommand)  

* or .Xresources
** /etc/X11/XF86Config also affects the keyboard settings under X

This is often a problem. When you find that the keys are fine in e.g. vi on the console, but not in an xterm (or vice versa, or both) it means that your xterm-settings do not correspond to the settings listed in the terminfo database. I am not really comfortable with telling you to fiddle with terminfo, please be careful, make backups! If you run the tic command on the modified de-compiled terminfo entry as root, your system's terminfo database will be modified automagically. Put the original file in a save place so you can run tic on it and restore the original state. Read the manpage. First try it as non-privileged user. You can start with testing a modified xterminfo file (see below) as explained, however, since these are likely to differ from your system's entry at other points, it's probably better to modify your own instead. At any rate, first find out whether the terminfo entry for xterm is in accordance with your xterm settings:

infocmp | grep kbs

should return a line which includes kbs=/177. This means DEL (or ^?) is mapped to the backspace key, which is what we want.

infocmp | grep kdch1

should return a line with kdch1=/E[3~. This means that /E[3~ is mapped to the delete key. Often you will find kbs=^H and/or kdch1=/177, or there will be no kdch1 at all. You can either edit the terminfo entry as described on the Troubleshooting-page (simply setting or adding kdch1=/E[3~ and kbs=/177, but make a backup first!). Put the file in ~/.terminfo/x/xterm (for testing purposes) and do for bash:

export TERMINFO=~/.terminfo

and/or for tcsh:

setenv TERMINFO ~/.terminfo

Make sure that the TERM variable is set to xterm:

echo $TERM

should return "xterm". If it works as intended (do 'toe' to check whether the terminfo dir you specified is indeed used, toe will return a list of available terminfo types, only xterm in this case), you can run tic as root, which will copy the file to


(debian) or


(redhatslackware). Make backups first, and test it before you replace any files!

The xterm (and friends) only needs little configuration. In the /etc/X11/Xresources or ~/.Xdefaults (or wherever it's merged with the other xresources) add the line:

*VT100.Translations: #override /
              <Key>BackSpace: string(0x7F)/n/
              <Key>Delete:    string("/033[3~")/n/
              <Key>Home:      string("/033[1~")/n/
              <Key>End:       string("/033[4~")
*ttyModes: erase ^? 

Rxvt only uses Xresources if it is compiled with this option. Since rxvt uses readline, to get home and end to work you will have to edit .inputrc, see the Bash section). Redhat users can pick up the SRPM (source) and compile rxvt themselves with this feature.h, ensuring the right keybindings.

Putting xterm or nxterm in front of *vt100.translations makes the settings specific for xterm or nxterm. Sometimes this does not seem to work properly, in that case try using bothnxterm*VT100.Translations and xterm*VT100.Translations.

BTW, have I told you that Ctrl-v <key> will tell you what sequence is sent to the shell? Try Ctrl-v [Delete], it should give a ^[[3~ in your xterm or console (try it with [ESC] and you'll find ^[, which corresponds to /e for readline apps, and /033 for Xresources).

1. The syntax of the Xresources files is very strict, make sure you don't leave blank spaces after the backslash on each line. Also watch the newline (/n/) sequences, there shouldn't be one at the last line of an entry.
2. The sections are named, if you only use *VT100.Translations it will work for all xterm and friends.
3. For info about Xresources and other X related stuff refer to 'man X'.


If you use XFree86, make sure you have enable the XKB extensions in /etc/X11/XF86Config. It is enable by default, so it should be okay. Note the different keyboard layout-options. Now XFree86 will translate the console mapping, and everything should work in X. If you have problems, or want to fiddle with additional characters and things, create an Xmodmap. Also if you want the keyboard to generate special characters in X, xmodmap can also be used to configure the function-keys. This is adequately described in the manual page ('man xmodmap'. Make sure that the following lines are included in yourXmodmap:

keycode 22 = BackSpace
keycode 107 = Delete

Note that the keycodes in X are not the same as in a VT. Use showkey to see the keycodes generated by the keyboard in a VT, and xev in X. There is an excellent graphical front end for X-keyboard configuration: xkeycaps. Refer to the Netscape section.

Another way of generating special characters in X (without using xmodmap) is by defining a Compose-key (for use as a "dead key") in XF86Config in the Keyboard section:

  RightCtl        Compose

Now you have a compose-key with the same properties as the one described in the VT section. Remember to set the environment variable LC_CTYPE=iso-8859-1 (see VT optional...). Consult 'man XF86Config' if you want to know more. Note: this doesn't seem work rxvt.
Alternatively, owners of a windows keyboard (one with extra buttons, it need not be a M$ natural keyboard) can enable the XKEYBOARD extension (enabled per default) in XF86Config and uncomment the line (follow the instructions in the file):

  XkbModel    "microsoft" 

Now you can use the button with the windows flag on it to produce a great number of exotic characters, just press it in combination with e.g. a, producing á (a clear disadvantage is that there is no logic in the location of the special characters at all...).

Yet another way to use "dead keys" in X is by installing a modified version of libX11 which includes support for dead keys (transparent for all apps). First, get the modified version of libX11 (make sure you get the right version, if you use glibc replace both libX11, ELF-libc5 and ELF-libc6). Now, deactivate the XKB extension of XFree86 (edit XF86Config and run xmodmap on a Xmodmap file with dead keys like dead_acute, dead_grave, dead_cedilla, dead_ogonek and a Multi_keys one too.

A special case is if you use xdm, you need to deactivate XKB from the /etc/X11/xdm/Xservers file, passing a -kb parameter to the server like this:

:0 local /usr/X11R6/bin/X -kb

then in /etc/X11/xdm/Xsetup_0 file add a line to load the Xmodmap, like this:

if [ -r /etc/X11/xinit/.Xmodmap ]; then
        /usr/X11R6/bin/xmodmap /etc/X11/xinit/.Xmodmap

Now chars accesible by AltGr, dead keys or compose are usable in xdm too.

More Composing Talk

A problem common to all compose schemes is that while some composing systems make more sense than others, none of them make all of the iso_8859_1 characters readily accessible, simply because it is impossible to remember the combinations for all characters. So instead of, or in addition to getting special libraries, it is often desirable to simply have a list of characters you can copy from, a poor man's iso_8859_1 table so to speak. Just grab you favorite editor, open a file called iso_8859_1 (or any other name, but check the name and path) and put in all iso_8859_1 characters. Wait, here they are (you may want to create a different order):

¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± &sup2; &sup3; ´ µ ¶ · ¸ &sup1; º » &frac14; &frac12; &frac34; ¿ À Á Â Ã Ä Å Æ Ç
È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î
ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ 

Now you need a way to display them (millions of options here, I bet you can do all kinds of crazy things with fonts, colors, pixmaps, borders...). The script assumes the file with the characters is in/usr/local/lib.



9vx tutorial: running a cpu server from kfs (RFC)





本文是yiyus发布在9fans上的一篇教程。文中用到的9vx是yiyus维护的分支:。根据yiyus在9fans中的说明,他的9vx分支是从ron的分支上更改的。vx32/9vx的创始人Russ Cox最近在9fans中声明他本人已经放弃了对9vx的维护,准备将所有权限转交给ron minnich(八卦一下:Russ Cox现在是Google Go语言的核心成员之一,正与Rob Pike,Ken Tompson等原plan9的元老一起维护Go……)。



9vx tutorial: running a cpu server from kfs (RFC)  

This tutorial is a work in progress (it will eventually be added to the 9vx documentation and probably to the Plan 9 wiki). Please let me know if you see anything I'm doing wrong (unfortunately I don't have too much experience with real Plan 9 systems of more than one machine). In particular, I don't know why I could not use mkfs instead of dircp. The line 


 % disk/mkfs -s /n/9660 /sys/lib/sysconfig/proto/allproto 


gave me this error:  

    mkfs: /sys/lib/sysconfig/proto/allproto:1: can't move tmp file to /n/kfs/dist/replica/plan9.compressed.db: wstat -- unknown type/mode 

Anyway, these instructions are working here. Please, let me know if they work for you too. 

By the way, this tutorial is only the first one, but I'd like to have some more. For example, to run several 9vx instances in a private network using the tap device and to run 9vx from fossil backed up by p9p's venti. Contributions are welcomed ;-) 


This is a brief tutorial on how to run a 9vx cpu server from a kfs file system. You will need 9vx, a plan9.iso and some free disk space. 

First, go to the destination directory and install 9vx: 


$ hg clone 
$ cd vx32/src/ 
$ make 9vx/9vx && sudo make 9vx/install 


(Commands run on the host are preceded by $, commands run from inside 9vx are preceded with %

You can check that 9vx is working running the minimal system embedded in the executable. The rcvx script should take you to a vx32% rc prompt in the current directory. Once you have played a bit with a rootless 9vx type exit to go back to your host system. 

rcvx is cool but you will want a full Plan 9 tree to have real fun.  

Let's boot from the iso file: 


 $ 9vx -r plan9.iso -u glenda "CWD=#Z`pwd`" "nvram=#Z`pwd`/plan9.nvr" 


You should be in rio now, have an acme and a rio window, stats, faces... This is the live system in the iso that you probably already know. The CWD=... and nvram=... arguments are interpreted as plan9.ini lines and passed as environment variables, we will use them later. 

Open a new rio window: 


% cd $CWD 
% dd -if /dev/random -of plan9.nvr -bs 512 -count 1 
% dd -if /dev/zero -of plan9.kfs -bs 1024 -count 320000 


Those files will be our nvram and kfs partitions (check the size of your kfs file, 320Mb is not too much, but will be enough). Nvram needs to be initialized: 

    % auth/wrkey 
    authid: bootes 
    authdom: 9vx 
    secstore key: 


We can populate the file system now: 

% 9660srv -f plan9.iso 
% 9fs 9660 
% disk/kfs -f plan9.kfs 
File system main inconsistent 
Would you like to ream it (y/n)? y 
% 9fs kfs 
% dircp /n/9660 /n/kfs 

The system is now installed. You should be able to open a new 9vx instance from your new root: 


$ 9vx "nvram=#Z`pwd`/plan9.nvr" -r plan9.kfs -u glenda 


You can also boot a cpu server. We will use the canopenpath option, so that only the files which begin with `pwd`/plan9 can be opened from 9vx, the -ic flags tell 9vx to pass -c to /386/init: 


$ 9vx -gic -r plan9.kfs "nvram=#Z`pwd`/plan9.nvr" "canopenpath=`pwd`/plan9" -u bootes 


When you see the vx32# prompt add a key so that you can cpu as glenda: 


vx32# echo 'key proto=p9sk1 dom=9vx user=glenda !password=password' >/mnt/factotum/ctl 


Now you can cpu to your new server. From another 9vx instance (for example, booted from the iso): 


% cpu -h 



If it worked we are done. 


Now you will probably want to adjust to your needs the 9vxc script to launch cpu servers (also, think about adding a /cfg/vx32/cpurc file). 

You could be interested in the options localroot, canopenpath, cpulimit and memsize. Or maybe you want to setup a virtual ethernet device (have a look at the tap script and the 9vx man page). 

Have fun! (and please, report bugs) 



- yiyus || JGL .   


Tools for Manipulating Object Files


There are a number of tools available on Unix systems to help you understand and manipulate object files. In particular, the GNU binutils package is especially helpful and runs on every Unix platform.


  1. AR : Creates static libraries, and inserts, deletes, lists, and extracts members.
  2. STRINGS: Lists all of the printable strings contained in an object file.
  3. STRIP: Deletes symbol table information from an object file.
  4. NM : Lists the symbols defined in the symbol table of an object file.
  5. SIZE: Lists the names and sizes of the sections in an object file.
  6. READELF: Displays the complete structure of an object file, including all of the information encoded in the ELF header. Subsumes the functionality of SIZE and NM.
  7. OBJDUMP: The mother of all binary tools. Can display all of the information in an object file. Its most useful function is disassembling the binary instructions in the .text section.
  8. LDD : Lists the shared libraries that an executable needs at run time.
--- From Computer Systems: A Programmer's Perspective.


  1. A very good webpage introducing Linux libraries: Static, Shared Dynamic and Loadable Linux Libraries
  2. How to Write Shared Libraries?
  3. Program Library HOWTO: