Solrex's profileSolrex Shuffling.LifeBlogListsNetwork Tools Help

Blog


    8/31/2007

    Temporarily Be Quiet


    明天就要开学了,今天是我在公司的最后一天。现在自己还没有个人电脑,以后大概就失去了持续的 Internet access,所以标题就叫做暂时安静。博客更新频率、信箱登录频率、IM 上线频率、BBS 和 SNS 网站刷新频率都会放慢,等十一后我买了电脑再说吧~_~

    由于个人时间安排和公司接受程度,暂时不会在公司继续兼职了。以后是否有机会再出来做事,就得看情况了。刚开学这段时间应该比较忙,再加上我还有 7 本正在读的书没有读完 [href: http://www.douban.com/do/Solrex/book/ ],空闲的时间恐怕还是很少滴。

    不知道要住什么样的宿舍,不知道要学什么样的课程,不知道要做什么样的研究,一个数学系的学生去读工程方向的网络安全,应该还是有很多东西要学,最基本的通信和编码这块就有很多需要弥补的差距。我想刚进实验室时导师是不会对我太满意的,不过咱数学系的学生,数分高代常微偏微离散数值概率运筹泛函近世实变复变都学过,还怕什么?

    最近身体也不是很好,因为吃饭麻烦,饮食总不是那么有规律,期望开学以后会好一些。十一要回南京,去看 xixi,嘿嘿还有一个额外的计划是教她学 Tex,这样以后我就不用干排版的活了~~~

    今天徐宥的 Gtalk 签名改成了"中国网,封天下",唉,我也深刻地体会到了。和"墙"打交道也很久了:刚开始 Blog 用 MSN Space,因为 Space 没有到信息产业部备案,05年下半年和06年上半年访问都不正常,直到咱们主席造访盖茨家为止,总算没再出大问题;个人主页用 Google Page,隔三岔五总要封几天,这不这两天正封着呢;后来 Blog 用 Blogspot,封的时间比能访问的时间多;正想到 Flickr 上开个相册,被封掉了;刚用上 Feedburner,这两天又被封了,这次封得更绝,不封主页封子域名;Wikipedia 就不用说了,祈祷吧!

    所以我的博客现在在三个地方同步更新:http://blog.solrex.cn , http://solrex.spaces.live.com , http://solrex.blogspot.com ,我只能希望不会被同时"墙"三个,这样我还有点写博客的念想。另外我也劝各位使用 Feedburner 烧制的 RSS feed 订阅别人博客的同学(不管是订阅谁的),把阅读器换成 Google Reader(已经支持离线功能,下载浏览器插件即可)吧,那样不管怎么"墙"你都可以得到博客更新(如果这个世界上还有 Google 服务器不能抓到的网页,那么这台服务器 80% 的可能是物理层隔离于 Internet 的)。

    罗嗦完了,我 peace out~~~~~~
    8/26/2007

    Crossroads


    说十字路口其实也不对,只不过是又到了一个转折点。下周五工作完以后,周六就会到中科院新生报到了。今天上午才到沃尔玛把"一寸正身免冠彩色光面纸(通知书上原话)"照片给照了,剩下的证件什么的都已经准备好了。徐洋洋和我都是到中科院中关村园区报到,他大概 30 日到北京,可能还要把行李放我那,因为我住的地方离青年公寓很近。

    同时比较焦虑的是不知道还能不能在公司继续兼职,从我的角度讲,是比较乐意做下去的,主要是因为有一笔额外的收入会让自己在经济上宽裕很多,毕竟现在是自负盈亏。虽然听师兄说一年级课并不忙,但是时间分配能否合理,公司能否接受都是一个问题,大概经理下周会和我谈。

    其实考虑来考虑去都是钱的问题,如果纯粹是为了锻炼,自己单独参加一些开源项目等等也可以得到很好的机会,只不过那样是不会有收入进帐的。科学院基本是导师如果项目多,学生就忙,得的钱也多,如果项目少,学生就比较闲,得的钱也比较少。而一年级都是集中学习,除了个别变态的老师,很少有让学生做项目的,也就比较有时间去兼职。现在也算是成人了,花钱的事情比较多,当然赚钱越多越好了。所以就算这面公司不能继续做下去,还是要找些其它的路子去赚钱,年轻时候把太多空闲时间花在玩上也不好。

    开学又会认识一批新同学,可能也会有些新朋友。面对变化的时候,人总是有一点点恐惧又有一点点向往,很矛盾的心理。不过等适应下来,一切仍然会都好。其实我算是好的了,已经在北京待了大半年了,可以称作"北漂"族的。而且住处就在青年公寓附近,这周围的情况摸得熟得不行,在环境上起码不陌生了,已经比其他的同学好很多了。
    8/24/2007

    Writing x86 PC Bootloader With Free Software 2


    1. Hacking 《自己动手写操作系统》Chapter 1&2
    ——Writing x86 PC Bootloader With Free Software
    [href: http://blog.solrex.cn/articles/writing-x86-pc-bootloader-with-free-software.html ]

    2. Hacking 《自己动手写操作系统》Chapter 4
    ——Writing x86 PC Bootloader With Free Software 2

    强烈建议随《自己动手写操作系统》这本书读本篇文章,基础知识:x86 汇编指令,AT&T 汇编格式,FAT12 文件系统格式。

    由于《自己动手写操作系统》第三章讲的是保护模式,示例代码全是 DOS 可执行代码,和直接的 Bootloader 没有太大关系,所以这次继续下来从第四章开始。

    前两章中写的 Bootloader 其实严格意义上只算是一个 Boot sector(扇区),因为它只是简单地打印了一个字符。第四章的 Bootloader 实现了从软盘中读写一个文件并加载运行的功能。

    总共有以下几个文件:boot.S loader.S solrex_x86_boot.ld solrex_x86_dos.ld Makefile

    下面解释每个文件的作用:
    boot.S:
    它生成的 .bin 文件就是软盘镜像的第一个扇区。由上一篇文章提供的 boot.S 只有启动功能,生成的软盘镜像文件只能作为启动器而不能作为可读写软盘来使用,因为在那个镜像里面没有将软盘格式化。其实格式化说白了就是在软盘的第一个扇区添加一些头信息,这样系统就知道如何处理这张软盘,在 boot.S 中的 Floppy header 就是做这个工作的。而在软盘的前 3 个 byte 是一句跳转指令,这样在启动时候系统会跳过 floppy header,也解决了如何启动的问题。这样这张软盘既可以作为启动盘,又可以作为文件盘使用了。因为启动扇区只有 512 个字节,不可能依赖它作为启动功能,这样我们可以将另一个程序 LOADER.BIN 放入软盘,启动后,从软盘读取它进入内存并执行。

    所以 boot.S 代码的主要内容是,首先将软盘主目录复制到内存中,并在其中搜索 LOADER.BIN,搜索到以后,将 LOADER.BIN 加载入内存并执行。

    loader.S:
    就是一个普通的打印程序,在屏幕第一行中间打印一个 'L'

    solrex_x86_boot.ld:
    boot.S 的连接脚本,将 boot.S 代码段连接到 0x7c00 的位置(x86 PC 操作系统启动的位置)。

    solrex_x86_dos.ld:
    loader.S 的连接脚本,将 loader.S 代码段连接到 0x1000 的位置,和普通 DOS 程序一样。

    Makefile:
    不说了,大家都知道。

    这个 hacking 系列我准备继续写下去,示例代码可以从我的个人主页 http://solrex.cn 打包下载,包括《自己动手写操作系统》的部分源代码,以 .asm 为后缀。对 Intel(MASM,NASM,TASM) 和 AT&T(GAS)汇编语言语法在 x86 平台的实现如何转换感兴趣的朋友,可以对比阅读 .asm 和 .S 文件。

    [solrex@NJU-CAS Solrex]$ more boot.S loader.S solrex_x86_boot.ld solrex_x86_dos.ld Makefile
    ::::::::::::::
    boot.S
    ::::::::::::::
    .code16
    .set    BaseOfStack,    0x7c00    /* Stack base address, inner */
    .set    BaseOfLoader,    0x9000    /* Section loading address of LOADER.BIN */
    .set    OffsetOfLoader,    0x0100    /* Loading offset of LOADER.BIN */
    .set    RootDirSectors, 14        /* Root directory sector count */
    .set    SecNoOfRootDir,    19        /* 1st sector of root directory */
    .set    SecNoOfFAT1,    1        /* 1st sector of FAT1 */
    .set    DeltaSecNo,        17        /* BPB_(RsvdSecCnt+NumFATs*FATSz) -2 */
    /* Start sector of file space =*/
    .text
    /* Floppy header of FAT12 */
        jmp    LABEL_START /* Start to boot. */
        nop                /* nop required */
    BS_OEMName:            .ascii    "WB. YANG"    /* OEM String, 8 bytes required */
    BPB_BytsPerSec:        .2byte    512            /* Bytes per sector */
    BPB_SecPerCluse:     .byte    1            /* Sector per cluse */
    BPB_ResvdSecCnt:    .2byte    1            /* Reserved sector count */
    BPB_NumFATs:        .byte    2            /* Number of FATs */
    BPB_RootEntCnt:        .2byte    224            /* Root entries count */
    BPB_TotSec16:        .2byte    2880        /* Total sector number */
    BPB_Media:            .byte    0xf0        /* Media descriptor */
    BPB_FATSz16:        .2byte    9            /* FAT size(sectors) */
    BPB_SecPerTrk:        .2byte    18            /* Sector per track */
    BPB_NumHeads:        .2byte    2            /* Number of magnetic heads */
    BPB_HiddSec:        .4byte    0            /* Number of hidden sectors */
    BPB_TotSec32:        .4byte    0            /* If TotSec16 equal 0, this works */
    BS_DrvNum:            .byte    0            /* Driver number of interrupt 13 */
    BS_Reserved1:        .byte    0            /* Reserved */
    BS_BootSig:            .byte    0x29        /* Boot signal */
    BS_VolID:            .4byte    0            /* Volume ID */
    BS_VolLab:            .ascii    "Solrex 0.01" /* Volume label, 11 bytes required */
    BS_FileSysType:        .ascii    "FAT12   "    /* File system type, 8 bytes required */

    /* Initial registers. */
    LABEL_START:
        mov        %cs,%ax
        mov        %ax,%ds
        mov        %ax,%es
        mov        %ax,%ss
        mov        $BaseOfStack, %sp

        /* Clear screen */
        mov        $0x0600,%ax    /* %ah=6, %al=0 */
        mov        $0x0700,%bx    /* Black white */
        mov        $0,%cx        /* Top left: (0,0) */
        mov        $0x184f,%dx    /* Bottom right: (80,50) */
        int        $0x10        /* BIOS int 10h, ah=6: Initialize screen */
       
        /* Display "Booting**" */
        mov        $0,%dh
        call    DispStr        /* Display string(index 0)*/

        /* Reset floppy */
        xor        %ah,%ah   
        xor        %dl,%dl        /* %dl=0: floppy driver 0 */
        int        $0x13        /* BIOS int 13h, ah=0: Reset driver 0 */

        /* Find LOADER.BIN in root directory of driver 0 */
        movw    $SecNoOfRootDir, (wSectorNo)

    /* Read root dir sector to memory */
    LABEL_SEARCH_IN_ROOT_DIR_BEGIN:
        cmpw    $0,(wRootDirSizeForLoop)    /* If searching in root dir */
        jz        LABEL_NO_LOADERBIN            /* can find  LOADER.BIN ?   */
        decw    (wRootDirSizeForLoop)
        mov        $BaseOfLoader,%ax
        mov        %ax,%es                        /* %es <- BaseOfLoader*/
        mov        $OffsetOfLoader,%bx            /* %bx <- OffsetOfLoader */
        mov        (wSectorNo),%ax                /* %ax <- sector number in root */
        mov        $1,%cl
        call    ReadSector
        mov        $LoaderFileName,%si            /* %ds:%si -> LOADER  BIN */
        mov        $OffsetOfLoader,%di            /* BaseOfLoader<<4+100*/
        cld
        mov        $0x10,%dx

    /* Search for "LOADER  BIN", FAT12 save file name in 12 bytes, 8 bytes for
       file name, 3 bytes for suffix, last 1 bytes for '\20'. If file name is
       less than 8 bytes, filled with '\20'. So "LOADER.BIN" is saved as:
       "LOADER  BIN"(4f4c 4441 5245 2020 4942 204e).
    */
    LABEL_SEARCH_FOR_LOADERBIN:
        cmp        $0,%dx                        /* Read control */
        jz        LABEL_GOTO_NEXT_SECTOR_IN_ROOT_DIR
        dec        %dx           
        mov        $11,%cx

    LABEL_CMP_FILENAME:
        cmp        $0,%cx
        jz        LABEL_FILENAME_FOUND    /* If 11 chars are all identical? */
        dec        %cx
        lodsb                            /* %ds:(%si) -> %al*/
        cmp        %es:(%di),%al
        jz        LABEL_GO_ON
        jmp        LABEL_DIFFERENT            /* Different */

    LABEL_GO_ON:
        inc        %di
        jmp        LABEL_CMP_FILENAME        /* Go on loop */

    LABEL_DIFFERENT:
        and        $0xffe0,%di                /* Go to head of this entry */
        add        $0x20,%di
        mov        $LoaderFileName,%si        /* Next entry */
        jmp        LABEL_SEARCH_FOR_LOADERBIN

    LABEL_GOTO_NEXT_SECTOR_IN_ROOT_DIR:
        addw    $1,(wSectorNo)
        jmp        LABEL_SEARCH_IN_ROOT_DIR_BEGIN

    /* Not found LOADER.BIN in root dir. */
    LABEL_NO_LOADERBIN:
        mov        $2,%dh
        call    DispStr        /* Display string(index 2) */
        jmp        .            /* Infinite loop */

    /* Found. */
    LABEL_FILENAME_FOUND:
        mov        $RootDirSectors,%ax
        and        $0xffe0,%di            /* Start of current entry, 32 bytes per entry */
        add        $0x1a,%di            /* First sector of this file */
        mov        %es:(%di),%cx
        push    %cx                    /* Save index of this sector in FAT */
        add        %ax,%cx
        add        $DeltaSecNo,%cx        /* LOADER.BIN's start sector saved in %cl */
        mov        $BaseOfLoader,%ax
        mov        %ax,%es                /* %es <- BaseOfLoader */
        mov        $OffsetOfLoader,%bx    /* %bx <- OffsetOfLoader */
        mov        %cx,%ax                /* %ax <- Sector number */

    /* Load LOADER.BIN's sector's to memory. */
    LABEL_GOON_LOADING_FILE:
        push    %ax
        push    %bx
        mov        $0x0e,%ah
        mov        $'.',%al    /* Char to print */
        mov        $0x0f,%bl    /* Front color: white */
        int        $0x10        /* BIOS int 10h, ah=0xe: Print char */
        pop        %bx
        pop        %ax

        mov        $1,%cl
        call    ReadSector
        pop        %ax            /* Got index of this sector in FAT */
        call    GetFATEntry
        cmp        $0x0fff,%ax
        jz        LABEL_FILE_LOADED
        push    %ax            /* Save index of this sector in FAT */
        mov        $RootDirSectors,%dx
        add        %dx,%ax
        add        $DeltaSecNo,%ax
        add        (BPB_BytsPerSec),%bx
        jmp        LABEL_GOON_LOADING_FILE

    LABEL_FILE_LOADED:
        mov        $1,%dh       
        call    DispStr        /* Display string(index 1) */

    /*******************************************************************
       Jump to LOADER.BIN's start address in memory.
    */
        jmp        $BaseOfLoader,$OffsetOfLoader
    /*******************************************************************/

    /* ==================================================================
       Variable table
    */
    wRootDirSizeForLoop:    .2byte    RootDirSectors
    wSectorNo:                .2byte    0        /* Sector number to read */
    bOdd:                    .byte    0        /* odd or even? */

    /* ==================================================================
       String table
    */
    LoaderFileName:        .asciz    "LOADER  BIN"        /* File name */
    .set    MessageLength,9
    BootMessage:        .ascii    "Booting**"            /* index 0 */
    Message1:            .ascii    "Loaded in"            /* index 1 */
    Message2:            .ascii    "No LOADER"            /* index 2 */

    /* ==================================================================
       Routine: DispStr
       Action: Display a string, string index stored in %dh
    */
    DispStr:
        mov        $MessageLength, %ax
        mul        %dh
        add        $BootMessage,%ax
        mov        %ax,%bp                /* String address */
        mov        %ds,%ax
        mov        %ax,%es
        mov        $MessageLength,%cx    /* String length */
        mov        $0x1301,%ax            /* ah = 0x13, al = 0x01(W) */
        mov        $0x07,%bx            /* PageNum 0(bh = 0), bw(bl= 0x07)*/
        mov        $0,%dl                /* Start row and column */
        int        $0x10                /* BIOS INT 10h, display string */
        ret

    /* ==================================================================
       Routine: ReadSector
       Action: Read %cl Sectors from %ax sector(floppy) to %es:%bx(memory)
         Assume sector number is 'x', then:
           x/(BPB_SecPerTrk) = y,
           x%(BPB_SecPerTrk) = z.
         The remainder 'z' PLUS 1 is the start sector number;
         The quotient 'y' devide by BPB_NumHeads(RIGHT SHIFT 1 bit)is cylinder
           number;
         AND 'y' by 1 can got magnetic header.
    */
    ReadSector:
        push    %ebp
        mov        %esp,%ebp
        sub     $2,%esp        /* Reserve space for saving %cl */
        mov        %cl,-2(%ebp)
        push    %bx            /* Save bx */
        mov        (BPB_SecPerTrk), %bl    /* %bl: the devider */
        div        %bl            /* 'y' in %al, 'z' in %ah */
        inc        %ah            /* z++, got start sector */
        mov        %ah,%cl        /* %cl <- start sector number */
        mov        %al,%dh        /* %dh <- 'y' */
        shr        $1,%al        /* 'y'/BPB_NumHeads */
        mov        %al,%ch        /* %ch <- Cylinder number(y>>1) */
        and        $1,%dh        /* %dh <- Magnetic header(y&1) */
        pop        %bx            /* Restore %bx */
        /* Now, we got cylinder number in %ch, start sector number in %cl, magnetic
           header in %dh. */
        mov        (BS_DrvNum), %dl
    GoOnReading:
        mov        $2,%ah
        mov        -2(%ebp),%al    /* Read %al sectors */
        int        $0x13
        jc        GoOnReading    /* If CF set 1, mean read error, reread. */
        add        $2,%esp
        pop        %ebp
        ret

    /* ==================================================================
       Routine: GetFATEntry
       Action: Find %ax sector's index in FAT, save result in %ax
    */
    GetFATEntry:
        push    %es
        push    %bx
        push    %ax
        mov        $BaseOfLoader,%ax
        sub        $0x0100,%ax
        mov        %ax,%es            /* Left 4K bytes for FAT */
        pop        %ax
        movb    $0,(bOdd)
        mov        $3,%bx
        mul        %bx                /* %dx:%ax = %ax*3 */
        mov        $2,%bx
        div        %bx                /* %dx:%ax/2 */
        cmp        $0,%bx            /* remainder %dx = 0 ? */
        jz        LABEL_EVEN
        movb    $1,(bOdd)

    LABEL_EVEN:
        xor        %dx,%dx            /* Now %ax is the offset of FATEntry in FAT */
        mov        (BPB_BytsPerSec),%bx
        div        %bx                /* %dx:%ax/BPB_BytsPerSec */
        push    %dx
        mov        $0,%bx
        add        $SecNoOfFAT1,%ax    /* %ax <- FATEntry's sector */
        mov        $2,%cl            /* Read 2 sectors in 1 time, because FATEntry */
        call    ReadSector        /* may be in 2 sectors. */
        pop        %dx
        add        %dx,%bx
        mov        %es:(%bx),%ax
        cmpb    $1,(bOdd)
        jnz        LABEL_EVEN_2
        shr        $4,%ax

    LABEL_EVEN_2:
        and        $0x0fff,%ax

    LABEL_GET_FAT_ENTRY_OK:
        pop        %bx
        pop        %es
        ret

    .org 510        /* Skip to address 0x510. */
    .2byte 0xaa55    /* Write boot flag to 1st sector(512 bytes) end */
    ::::::::::::::
    loader.S
    ::::::::::::::
    .code16
    .text
        mov        $0xb800,%ax
        movw    %ax,%gs
        mov        $0xf,%ah
        mov        $'L',%al
        mov        %ax,%gs:((80*0+39)*2)
        jmp        .
    ::::::::::::::
    solrex_x86_boot.ld
    ::::::::::::::
    SECTIONS
    {
      . = 0x7c00;
      .text :
      {
        _ftext = .;
      } = 0
    }
    ::::::::::::::
    solrex_x86_dos.ld
    ::::::::::::::
    SECTIONS
    {
      . = 0x0100;
      .text :
      {
        _ftext = .;
      } = 0
    }
    ::::::::::::::
    Makefile
    ::::::::::::::
    CC=gcc
    LD=ld
    OBJCOPY=objcopy

    CFLAGS=-c
    TRIM_FLAGS=-R .pdr -R .comment -R.note -S -O binary

    LDFILE_BOOT=solrex_x86_boot.ld
    LDFILE_DOS=solrex_x86_dos.ld
    LDFLAGS_BOOT=-e c -T$(LDFILE_BOOT)
    LDFLAGS_DOS=-e c -T$(LDFILE_DOS)

    all: boot.img LOADER.BIN

    boot.bin: boot.S
        $(CC) $(CFLAGS) boot.S
        $(LD) boot.o -o boot.elf $(LDFLAGS_BOOT)
        $(OBJCOPY) $(TRIM_FLAGS) boot.elf $@

    LOADER.BIN: loader.S
        $(CC) $(CFLAGS) loader.S
        $(LD) loader.o -o loader.elf $(LDFLAGS_DOS)
        $(OBJCOPY) $(TRIM_FLAGS) loader.elf $@

    boot.img: boot.bin
        dd if=/dev/zero of=emptydisk.img bs=512 count=2880
        dd if=boot.bin of=boot.img bs=512 count=1
        dd if=emptydisk.img of=boot.img skip=1 seek=1 bs=512 count=2879
        rm emptydisk.img

    # You must have the authority to do mount, or you must use "su root" or
    # "sudo" command to do "make copy"
    copy: boot.img LOADER.BIN
        mkdir -p /tmp/floppy;\
        mount -o loop boot.img /tmp/floppy/ -o fat=12;\
        cp LOADER.BIN /tmp/floppy/;\
        umount /tmp/floppy/;\
        rm -rf /tmp/floppy/;

    clean:
        @rm -f *.o *.elf *.bin *.BIN

    distclean:
        @rm -f *.img
    8/19/2007

    7 7 Qi Xi


    恩,今天是中国情人节,大家大概都知道。但我这里不是想写这个话题的,只是采用了标题党的惯用作法 :-)

    其实我现在不太想写字,最近的生活没什么波澜,码字的激情少了许多。算了,还是写点儿和七夕有点儿联系的事儿吧。

    昨天在豆瓣上看到一篇对《与二哥书》的评论:乡下人,来喝杯甜酒吧。(href: http://www.douban.com/review/1194811/ )

    这句话是张兆和答应沈从文婚事的一封电报,源于沈从文托她征询父亲对婚事的意见:"如爸爸同意,就早点让我知道,让我这个乡下人喝杯甜酒吧。"多美的文字,可以载入传奇的一句话!

    看到这句话,真想读读这本书,看看那个时代的爱情。每天面对电脑十小时以上,走出写字楼仍然觉得眼神呆滞的程序员,还能不能理解那是什么东西呢?

    我真的不懂生在乱世的人,怎么能那么执着地追求一份看起来飘渺的爱情?大概他们也不可能理解我们,这些生在红旗下长在新中国沐浴在改革开放春风里的 80 后一代,小小年纪却都已如此现实如此势利。美丽的爱情,善变的人,可能远不及沉甸甸的孔方兄让人觉得心里踏实。如若不信,君可以到各大BBS 的某些版面,看看哪天没有类似的讨论?伪君子也好,真小人也罢,问问自己,能不能真的贫贱富贵均相濡以沫。于男人来讲,最着心者恐怕不过"才""财"二字。又说多了,打住打住。

    藉此也想起大学一年级那段与好友书信相通的日子,上次回家还翻出一个小本儿,最后一页上记录着谁谁谁哪天来过封信,很美好的回忆。不知道等我五十年后再翻开,心情又会怎样?

    看来真的没什么想说的了,写到这里吧。
    8/14/2007

    The Importance of Email Signature


    首先,非常感谢 Eric You Xu 师兄在博客里推荐我的博客[href: http://blog.youxu.info/2007/08/13/recommend2/ ],但嵌入式开发高手不敢当,我只能说在 GDB 的移植和远程调试方面有比较多的经验,离高手还有很大距离(不是谦虚,我一直想成为那种无论在哪儿都能独挡一面的程序员,努力中 ^_^)。

    下面我开始发牢骚:
    有一个人,中国某家公司的员工,大概也从事 GDB 的移植,前段时间一直问我有关 GDB 移植方面的问题,我也一直非常耐心的回答他。但是,但是,搞得我非常非常不爽,条缕如下:
    1. 刚开始通过 Gtalk 与我联系,在我的状态为 busy 时给我发消息,而我工作时总是使用全屏的远程桌面,自然看不到消息。
    2. 问我问题前不知道自我介绍一番,在我强调更喜欢邮件联系时仍给我发送 Gtalk 消息。
    3. 由于对方没有自我介绍,我委婉地劝他最好使用公司信箱跟我联系,他说公司信箱不准向外发信,但你邮件总得有个签名吧,连签名都没有。
    4. 在我使用公司信箱和他联系后,仍然发送工作邮件到我的私人信箱中,谁想在私人信箱中看到工作上的联系啊?
    5. 后来总算有了签名,却是英文名,但没有公司信息,没有个人联系方式;我给他签名叫做 Wenbo,他抬头仍然使用 Hi Yang。
    6. 最后我回答了他很多问题,忍无可忍了,因为谁也不希望帮助的人是自己的竞争对手,就算是义务劳动,也得搞清楚对方是谁吧。请他告诉我他的中文名字和公司,并且开玩笑说说不定哪天我可以到他们那里找工作呢。结果呢,就没有回应了。我猜,难道是怕我抢他的饭碗?太荒谬了吧。

    其实我最不爽的就是他没有自我介绍,因为我觉得这是提问时,尤其是一对一提问时候起码的礼貌,唉!

    所以我真的很希望大家都能看看 How To Ask Questions The Smart Way [href: http://catb.org/~esr/faqs/smart-questions.html ],晓得怎么做才是礼貌的问问题的方法。为别人也为自己,想想要是自己碰到这样的情况会有什么感觉。

    至于自我介绍其实也不一定需要,只要养成在邮件中附加自己联系方式签名的习惯,像下面这样:
    --
    Wenbo Yang

    The State Key Lab. of Information Security
    Graduate School of CAS, 19A Yuquan Road, Beijing, China
    Homepage: http://solrex.cn

    SimpLight Nanoelectronics Ltd. 6 Zhichun Road, 10th Floor, Beijing, China
    Phone: +86-10-5126-6989   ---  Email: wenbo.yang@simplnano.com

    一是方便别人,从邮件签名就能了解你的基本情况;二是方便自己,省得专门的自我介绍;三是宣传自己和宣传公司,不相信你 Google 一下 "Wenbo Yang" 和 "simplnano"。有这么多好处,为什么不使用呢?

    8/10/2007

    Trace O Trace


    一周无事,要实现一个支持双硬件线程的 gdb stub,全是在写 interrupt 和 exception handler ,纯汇编编程,纯 trace 调试,16 和 32 bits 指令夹杂,总会有千奇百怪的问题,机器代码看得眼睛痛苦地要命,下班以后一会儿也不想多呆。有 GDB 用是多么幸福的事情啊,可是我需要给 GDB remote debug 提供支持,好歹算完了,大概只需要解决最后几个 BUG。

    回去会看一会儿高达,因为室友喜欢看,而对于我这个定力不足的人来说,计算机书自然没那个有吸引力。还挺刺激,大机器就是男人的玩具啊!唉,下星期我一定要把我的美嘉影城的兑换券给兑了,变形金刚也好哈里波特也好,不然真浪费了。

    买了几本书,Design Pattern,Artificial Intelligence,师兄豆列中推荐的。不过还是眼高手低,看完不知要何时了。

    周末会出去走走,最近感冒的人挺多,要小心。

    至于奥运那档子事,管它一周年也罢,几百天也罢,确定了,不掺和。什么东西到中国总会变味,既然被打上 me generation 的标签,还是 me 下去吧。