Tuesday, September 09, 2008

操作 memory mapping register I/O

在寫 driver 時,最基本的動作通常是練習控制簡單的 I/O 動作讓某個裝置起作用。
在此便解釋如何控制,以及一些簡單的範例,取自:

  • 現代嵌入式系統開發專案實務:菜鳥成長日誌與專案經理的私房菜
  • linux-ldp-v1.2

操作 memory mapping register I/O

  • Memory Mapping Register: 寫驅動程式時,要控制接在 CPU 外部的晶片勢必是透過 CPU 的 PIN 腳,可能只是單純的將 GPIO pin 設為 high/low 來控制外部的 chip,同理外部的設備也可以透過 GPIO pin 將訊號傳給 CPU;或者驅動程式可以透過某種通訊協定來控制 I/C,例如 SPI 或 I2C等。但無論是何種 protocol,CPU 和 外部 chip 之間的資料與命令傳遞還是得透過 CPU 的 pin 腳。
  • 程式寫法
    *(volatile unsigned char *)(0x302CF)=0x00;
    • register 其實是一個位址,使用指標就可以對其設值或取值,要注意的是一定要用 volatile 關鍵字,否則 compiler 的最佳化功能很可能會把某些程式當作是沒意義的。

範例

  • 以下為一 LED driver example
    /* drv_LED.c
    - 假設 CPU 用 P1 這樣 pin 與 LED 相接
    - 當 P1 為 high/low 時, LED 會 on/off
    */

    void drv_init_LED(void)
    {
    //設定 P1 為 output pin
    *(volatile unsigned char*)0x200023 |= 0x02; //0000 0010

    //default: P1 is low, LED off
    *(volatile unsigned char*)0x200022 &= ~0x02; //1111 1101
    }

    void drv_LED_off()
    {
    //set P1 is low, LED off
    *(volatile unsigned char*)0x200022 &= ~0x02; //1111 1101
    }

    void drv_LED_on()
    {
    //set P1 is low, LED off
    *(volatile unsigned char*)0x200022 |= 0x02; //0000 0010
    }
  • 解釋 *(volatile unsigned char*)0x200022 |= 0x02;
    void drv_LED_on(void)
    {
    volatile unsigned char data; // value of register context
    volatile unsigned char* reg; // the point to register

    reg = (volatile unsigned char*) 0x200022;
    data = *reg; // get the value of the register in 0x200022
    data = data | 0x2; // set 1 to 2th bit
    *reg = data; // set the new data to register
    }
  • linux-ldp-v1.2 例子
    • omap_writel((omap_readl(OMAP2_CONTROL_PBIAS_1) | 0x6) & ~0x1, OMAP2_CONTROL_PBIAS_1);
    • /*
      * Functions to access the OMAP IO region
      *
      * NOTE: - Use omap_read/write[bwl] for physical register addresses
      * - Use __raw_read/write[bwl]() for virtual register addresses
      * - Use IO_ADDRESS(phys_addr) to convert registers to virtual addresses
      * - DO NOT use hardcoded virtual addresses to allow changing the
      * IO address space again if needed
      */
      #define omap_readb(a) (*(volatile unsigned char *)IO_ADDRESS(a))
      #define omap_readw(a) (*(volatile unsigned short *)IO_ADDRESS(a))
      #define omap_readl(a) (*(volatile unsigned int *)IO_ADDRESS(a))

      #define omap_writeb(v,a) (*(volatile unsigned char *)IO_ADDRESS(a) = (v))
      #define omap_writew(v,a) (*(volatile unsigned short *)IO_ADDRESS(a) = (v))
      #define omap_writel(v,a) (*(volatile unsigned int *)IO_ADDRESS(a) = (v))
    • #define IO_OFFSET 0x90000000
      #define IO_ADDRESS(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */

Build Ramdisk for ARM


目標

  • 建置一個基本的 Ramdisk for arm,以便了解整個 file system 的開機流程。
  • ramdisk 主要程式由 busybox 提供,並包含基本的設定檔。
  • 建置平台為 Qemu: ARM Integrator/CP board 的模擬平台上。

Preview

  • 參考之前 Linux 2.6 的 initramfs 機制,了解 initramfs 的觀念。
  • Linux 2.6 核心將一個小的 ram-based initial root filesystem(initramfs) 包進核心,且若這個檔案系統包含一隻程式 /init,核心會將它當作第一隻程式執行。此時,找尋其他檔案系統並執行其他程式已不再是核心的問題,而是新程式的工作。

開機及初步 ramdisk

  • 由於Linux 2.6 核心已將一個小的 ram-based initial root filesystem(initramfs) 包進核心,所以我們可以先建立一個假的 ramdisk,只包含 init 來測試是否 kernel boot 成功與否。Ref: Jserv's blog: 深入理解 Linux 2.6 的 initramfs 機制 (上)
    mkdir hello-initramfs
    cd hello-initramfs
    vi init.c
    arm-none-linux-gnueabi-gcc -static -o init init.c # 編成 static 省麻煩
    file init # 確認編譯完成的檔案格式是否正確
    #init: ELF 32-bit LSB executable, ARM, version 1 (SYSV), for GNU/Linux 2.6.14, statically linked, not stripped
    mkdir dev
    cd dev
    mknod -m 600 console c 5 1
    cd ..

    • init.c, 將開機停在執行 /init 時,以驗証我們的動作是否成功
      #include 
      int main()
      {
      printf("Hello World!\n");
      sleep(9999);
      return 0;
      }

  • Build Kernel
    • 取得最近的 kernel source,linux-2.6.26.3
    • 嚐試用 kernel source 裡的 integrator_defconfig 編譯 kernel,但在測試時發現沒有任何反應,所以先從 qemu 網站上可以下載的 arm-test-0.2.tar.gz 裡取出 .config 來編譯。
    • 修改 Makefile 以符合我們用的 cross compile
      ARCH            ?= arm
      CROSS_COMPILE ?= arm-none-linux-gnueabi-
    • make menuconfig,記得選取 initramfs 並填上 path
      [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
      (/home/ryan/qemu/hello-initramfs) Initramfs source file(s)
    • make zImage
    • 測試: qemu-system-arm -kernel linux-2.6.26.3/arch/arm/boot/zImage。可以看見開機時有成功執行 Hello World! 這個 fake init
      TCP cubic registered
      NET: Registered protocol family 17
      RPC: Registered udp transport module.
      RPC: Registered tcp transport module.
      802.1Q VLAN Support v1.8 Ben Greear
      All bugs added by David S. Miller
      VFP support v0.3: implementor 41 architecture 1 part 10 variant 9 rev 0
      Hello World!

  • 以 busybox 建置 ramdisk,將 busybox 編譯為 static。
    • 取得最新 soruce BusyBox 1.11.2
    • 修改 Makefile
      CROSS_COMPILE ?= arm-none-linux-gnueabi-
      ARCH ?= arm
    • make menuconfig。記得選取 static libnary
      [*] Build BusyBox as a static binary (no shared libs)
    • make install。會在目錄下產生 _install 目錄,這也是待會我們要移進 ramdisk 的內容
    • 檢查檔案格式
      file _install/bin/busybox
      #_install/bin/busybox: ELF 32-bit LSB executable, ARM, version 1 (SYSV), for GNU/Linux 2.6.14, statically linked, stripped
  • 建置初步 ramdisk
    mkdir busybox-initramfs
    cd busybox-initramfs/
    cp -av ../busybox-1.11.2/_install/* .
    ln -s sbin/init init
    find ./ | cpio -o -H newc | gzip > ../busybox.initramfs.cpio.gz
    cd ..
  • 啟動
    qemu-system-arm -kernel linux-2.6.26.3/arch/arm/boot/zImage -initrd busybox.initramfs.cpio.gz
    • 此時會一直 argue 缺少 device 。此時可是自建相關的 device node,則可正常啟動。
    • 但我希望能由系統自行建立,所以先 copy arm_test 裡 file system 的 etc 目錄 來用,待之後再來分析流程。成功開機。
      cd busybox-initramfs
      cp ../arm-test/arm_root.img arm_root.img.gz
      gunzip arm_root.img.gz
      mkdir tmp
      cd tmp
      cpio -i -F ../arm_root.img
      cp -av etc ../
      touch mdev.conf # 這是因為開機時 complain 沒有這個檔,所以先做個假的。這是因為開始時有執行 mdev,而 mdev.conf 為它的設定檔。
      mkdir root
      cd ..
      rm -rf arm_root.img tmp
      find ./ | cpio -o -H newc | gzip > ../busybox.initramfs.cpio.gz
      qemu-system-arm -kernel linux-2.6.26.3/arch/arm/boot/zImage -initrd busybox.initramfs.cpio.gz

開機流程剖析

  • Linux kernel 在掛載 ramdisk 後,預設會尋找 /init 這隻程式,除非在内核傳遞参數裡有設置 init=/linuxrc 來指定要找的第一個程式。
  • 目前 /init 是由 busybox 所提供的,其預設行為可以參考 init (重要,read it)。
  • 建立 /etc/inittab,/init 預設會先分析此 script
    ::sysinit:/etc/init.d/rcS

    ::respawn:/sbin/getty -L 38400 tty1
    ::respawn:/sbin/getty -L 38400 tty2
    ::respawn:/sbin/getty -L 38400 tty3
    ::respawn:/sbin/getty -L 38400 tty4

    ::respawn:/sbin/getty -L ttyAMA0 115200 xterm
  • 由 /etc/inittab 所指定 (或 /etc/inittab 不存在時,init 的預設行為),會去執行 /etc/init.d/rcS。
    • 其執行的內容為
      • 掛載 virtual file system,參考Magic Linux开发入门指南(五),基本說明的蠻清楚的。
      • mdev: 初始 device node 及自動更新,參考 busybox 附帶的文檔 busybox-1.11.2/docs/mdev.txt
      • 其除為網路設定部份,這就先不處理了。
    • #! /bin/sh

      mkdir -p /proc
      mount -t proc proc /proc
      mkdir -p /sys
      mount -t sysfs sysfs /sys
      mkdir -p /dev/pts
      mount -t devpts devpts /dev/pts
      echo /sbin/mdev > /proc/sys/kernel/hotplug
      mdev -s
      hostname qemu
      ifconfig lo 127.0.0.1 up
      # This board doesn't have a hardware clock, so system time is way off.
      # The bugsybox dhcp client doesn't work when the clock is wrong.
      # Oh well.
      ifconfig eth0 10.0.2.15 up
      rdate 10.0.2.2
      ip route add default via 10.0.2.2
  • inittab 其餘的部份為本機端終端機啟動的個數,參考 Util-linux (getty 和login) 及 man getty。
    • 允許登錄系統(log in)和得到命令行提示符(bash prompt)。
    • 准備一個密碼文件/etc/passwd.login 登錄程序正是通過查詢該文件來確認您是否允許登錄的。我們可以只設置根系統用戶就夠了,而且不需要任何密碼!! 只需要在目標系統的密碼文件/etc/passwd加上此行 "root::0:0:root:/root:/bin/bash"即可。(/etc/group 也要加入 "root:x:0:")
  • /etc/issue: 在終端機介面登入的時,顯示提示的字串。(如果想要讓使用者登入後取得一些訊息,可以寫在 /etc/motd)
  • /etc/nsswitch.conf: name-server switch,用來控制名稱資訊轉換,例如,當系統要取得 password、group、host 等資訊時,會參考這個檔案以決定要從哪裡得到資訊。參考 man nsswitch.conf。
    # /etc/nsswitch.conf
    #
    # Example configuration of GNU Name Service Switch functionality.
    # If you have the `glibc-doc' and `info' packages installed, try:
    # `info libc "Name Service Switch"' for information about this file.

    passwd: compat
    group: compat
    shadow: compat

    hosts: files dns
    networks: files

    protocols: db files
    services: db files
    ethers: db files
    rpc: db files

    netgroup: nis
  • /etc/resolv.con: 參考簡介,man resolv.conf
    nameserver 10.0.2.3

Thursday, August 28, 2008

Blogger 有用的功能

針對目前的 Google Blogger 有些覺得不太滿意的地方。
以下便是針對這些點,找到的 solution。
之後應該會陸續將覺得有需要的功能一一找補強吧。

第一個 cross compile 成功的 kernel module - hello

第一個 kernel module - hello

The Linux Kernel Module Programming Guide 文上所說的,編寫第一個kernel module

  • hello.c
    #include  /* Needed by all modules */
    #include /* Needed for KERN_INFO */
    #include /* Needed for the macros */
    #define DRIVER_AUTHOR "Peter Jay Salzman "
    #define DRIVER_DESC "A sample driver"

    static int __init init_hello(void)
    {
    printk(KERN_INFO "Hello, world\n");
    return 0;
    }

    static void __exit cleanup_hello(void)
    {
    printk(KERN_INFO "Goodbye, world\n");
    }

    module_init(init_hello);
    module_exit(cleanup_hello);

    MODULE_LICENSE("GPL");
    MODULE_AUTHOR(DRIVER_AUTHOR); /* Who wrote this module? */
    MODULE_DESCRIPTION(DRIVER_DESC); /* What does this module do */
    MODULE_SUPPORTED_DEVICE("testdevice");

  • Makefile
    obj-m += hello.o
    all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
    clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

確定是可以在 X86 host 上成功編譯,運作也一切正常。
但問題來了,我該如何改寫 Makefile,使其能 cross compile 呢?
目前還不知道該如何解決,因為對 Makefile 及 cross compile 步驟還在粗淺的認識階段,以前也都是利用套件所提供的 configure 工具來代勞。
所以就想到將新增的 module 加到 kernel source 中,這樣就可以利用 kernel source 所提供 cross compile 的功能來幫我做相關設定了。


利用 kernel source 來 cross compile 新增的 module

  • 環境設定
    • Target Board 是 arm,所以在Makefile 裡: ARCH=arm, CROSS_COMPILE=arm-none-linux-gnueabi-
    • 新增一個 module,在 driver 目錄下新增一個測試目錄 rayn,測試 module 位於 driver/ryan/hello.c。
  • 編輯 configure 的選項
    • 修改 arch/arm/Kconfig (因為我們的target 為 arm,所以必需改在 arch/arm 裡的 Kconfig 才有用)
      • 加入這一行 source "drivers/ryan/Kconfig",將新增的測試目錄加到 configure 選項中
    • 修改 drivers/{Kconfig,Makefile}
      • Kconfig
        • 新增 source "drivers/ryan/Kconfig"
      • Makefile
        • 新增 obj-$(CONFIG_RYAN_TEST) += ryan/
    • 新增目錄,driver/ryan 及所需的檔案
      • Kconfig

        menu "RYAN test devices"

        config RYAN_TEST
        bool "RYAN test"

        config RYAN_TEST_HELLO
        tristate "The first kernel module - hello"
        depends on RYAN_TEST

        endmenu

      • Makefile
        obj-$(CONFIG_RYAN_TEST_HELLO)           += hello.o
      • hello.c
  • make menuconfig,將 hello 編為 module。可以看見新增的選項
    [*] RYAN test            
    The first kernel module - hello
  • make modules。可以看見 hello.ko 已生成。
    Building modules, stage 2.
    MODPOST 4 modules
    CC drivers/ryan/hello.mod.o
    LD [M] drivers/ryan/hello.ko
    CC fs/jffs2/jffs2.mod.o
    LD [M] fs/jffs2/jffs2.ko

  • 在 target 上測試

    bash-3.2# insmod ./hello.ko
    <6>Hello, world
    Hello, world
    bash-3.2# rm
    rm rmdir rmmod
    bash-3.2# rmmod hello
    <6>Goodbye, world
    Goodbye, world

完畢…

Wednesday, August 27, 2008

vi 命令速查

用 vi 時常忘記一些偶爾用到的指令,列出以下二個網址可以快速參考

vi 命令速查

使用 vi

Friday, August 22, 2008

LFS (Linux From Scratch) 初體驗

LFS (Linux From Scratch) 初體驗

  • Version: Linux From Scratch 6.3 Ref
  • 嚐試 LFS 是因為想要了解如何從頭建置一個基本的 Linux 系統,用最精簡的系統來幫助自己對 linux 初始流程的了解。在整個過程中,自己的閱讀方式是不求甚解,就像看本小說似的將它做一次,了解大致上的流程而已。雖然如此,我覺得在對於整個系統的初始流 程的了解(最基本的必要存在)還是很有幫助的。
  • 我嚐試了到了第三次才成功,我猜前二次的失敗應該是因為某次的指令不完整 or something 才會導致到 build packages 就失敗了,所以第三次時我用 LFS 提供的 LiveCD,並在每次都用 cpoy 的方式來執行指令,以降低失誤的機會 (startx 啟動 X-window)。
  • 大部份的時間都花在 build package 上(ch5/ch6),尤其是 GCC/Glibc 上,這部份可以了解幾個重要套件之間的關係、順序、其包含了那些工作。之前失敗在此時,真的不知該如何找出那個環節出錯,所以只好重做了 -_-。
  • 其實在這二個章節裡面,內容不多但很基本,主要在述敘開機的過程,會參考那些設定檔,device 是如何產生並掛載的等等…,對之後需要更進一步了解時應該還蠻俱參考價值的。
    • ch7. Setting Up System Bootscripts
    • ch8. Making the LFS System Bootable

Wednesday, August 20, 2008

MTD study

partition assigning & tools of MTD

Target

  • Assigning MTD partition
    • from kernel source
    • from u-boot
  • 以 jffs2 格式,掛載 mtd device (Nand Flash)
  • Cross Compiling mtd-utils for arm
  • Modify ramdisk by cpio
  • mtd-utils test

Assigning MTD partition

  • from kernel source
    • 預設會讀取 kernel soruce 裡的定義,在此為 arch/arm/mach-omap2/board-2430sdp-flash.c
    • 修改 mtd_partition nand_partitions 以符合所需
      static struct mtd_partition nand_partitions[] = {
      {
      .name = "XLDR",
      .offset = 0,
      .size = 8*(32*512), /* 128 KB */
      .mask_flags = MTD_WRITEABLE /* force read-only */
      },
      {
      .name = "UBOOT",
      .offset = MTDPART_OFS_APPEND,
      .size = 16*(32*512), /* 256 KB */
      .mask_flags = MTD_WRITEABLE /* force read-only */
      },
      {
      .name = "uKernel",
      .offset = MTDPART_OFS_APPEND,
      .size = 1408*1024,
      },
      {
      .name = "uRamdisk",
      .offset = MTDPART_OFS_APPEND,
      .size = 3*1024*1024, /* 3 MB */
      },
      {
      .name = "UnUsed",
      .offset = MTDPART_OFS_APPEND,
      .size = MTDPART_SIZ_FULL,
      },
      };
  • from u-boot
    • 確定 kernel source configure 中有開啟 CONFIG_MTD_CMDLINE_PARTS
    • 確定 u-boot source 中 CONFIG_BOOTCOMMAND 設定正確。(include/configs/omap2430sdp.h)
      #define CONFIG_BOOTCOMMAND "nand read 80F00000 60000 160000;
      nand read 84000000 1C0000 300000;bootm 80F00000 84000000"
      • 將 image 從 flash_address=60000 搬到 ram_address=80F00000, size=160000
        • 0x160000 = 1408K (uKerkel)
      • 將 image 從 flash_address=1C0000 搬到 ram_address=84000000 , size=300000
        • 0x300000 = 3M (uRamdisk)
      • bootm: boot application image from memory
    • mtd 的 name 必需與 kernel source 中定義的名字一樣,才會有效。
      • kernel source, arch/arm/mach-omap2/board-2430sdp-flash.c
        static struct platform_device sdp_nand_device = {
        .name = "omap2-nand",
        .id = -1,
        .dev = {
        .platform_data = &sdp_nand_data,
        },
        };
      • 確定 u-boot source CONFIG_BOOTARGS 設定正確。 u-boot source, include/configs/omap2430sdp.h
        #define CONFIG_BOOTARGS "root=/dev/ram0 console=ttyS2,115200n8
        mtdparts=omap2-nand:128K(XLoad),256K(UBoot),1408K(uKernel),3M(uRamdisk),-(unused)"
  • 確定 mtd partition 是否正確
    • cat /proc/mtd
    • demsg

Mount mtd device (NAND Flash) with jffs2

  • 確定 kernel 中的 CONFIG_JFFS2_FS=y 有選取,否則會造成無法掛載,Errmsg: No Such Device
    mount -t jffs2 /dev/mtdblock3 /mnt

Cross Compiling mtd-utils for arm

  • Cross compile zlib
    wget http://www.zlib.net/zlib-1.2.3.tar.gz
    tar xzvf zlib-1.2.3.tar.gz
    cd zlib-1.2.3
    CC=arm-none-linux-gnueabi-gcc LDSHARED="arm-linux-ld -shared" ./configure --shared
    make
    make prefix=/home/ryan/armlinux/zlib install
  • Cross compile lzo
    wget http://www.oberhumer.com/opensource/lzo/download/lzo-2.03.tar.gz
    tar xzvf lzo-2.03.tar.gz
    cd lzo-2.03
    CC=arm-none-linux-gnueabi-gcc ./configure --host=arm-linux --prefix=/home/ryan/armlinux/lzo
    make
    make install
  • Cross compile mtd-utils
    # apt-get install git-core
    git clone git://git.infradead.org/mtd-utils.git
    cd mtd-utils
    vi Makefile
    make WITHOUT_XATTR=1
    • 必需修改 Makefile
      ryan@ryan-ubuntu8:~/git$ diff mtd-utils/Makefile mtd-utils.git/Makefile -u
      --- mtd-utils/Makefile 2008-08-06 15:05:03.000000000 +0800
      +++ mtd-utils.git/Makefile 2008-08-06 15:06:53.000000000 +0800
      @@ -6,8 +6,14 @@
      SBINDIR=$(EXEC_PREFIX)/sbin
      MANDIR=$(PREFIX)/share/man
      INCLUDEDIR=$(PREFIX)/include
      +ZLIBCPPFLAGS=-I/home/ryan/armlinux/zlib/include
      +LZOCPPFLAGS=-I/home/ryan/armlinux/lzo/include
      +ZLIBLDFLAGS=-L/home/ryan/armlinux/zlib/lib
      +LZOLDFLAGS=-L/home/ryan/armlinux/lzo/lib

      -#CROSS=arm-linux-
      +CROSS=arm-none-linux-gnueabi-
      CC := $(CROSS)gcc
      CFLAGS ?= -O2 -g
      CFLAGS += -Wall
      @@ -47,7 +53,7 @@
      .SUFFIXES:

      all: $(TARGETS)
      - make -C $(BUILDDIR)/ubi-utils
      + make -C ubi-utils

      IGNORE=${wildcard $(BUILDDIR)/.*.c.dep}
      -include ${IGNORE}
      • ZLIBCPPFLAGS, LZOCPPFLAGS, ZLIBLDFLAGS, LZOLDFLAGS 是用來指定所需的 zlib/lzo 的 include/lib 在何處,所以在cross compile時需要由我們自行指定
      • make WITHOUT_XATTR=1,make command to compile without Posix ACL。若無指定時會出現以下錯誤時 Ref
        > mips-linux-cc -I./include -g -O3 -G0 -pipe -fpic -fPIC -msoft-float
        > -mabi=32 -march=mips32r2 -mtune=34kc -g -c -o mkfs.jffs2.o mkfs.jffs2.c
        > -g -Wp,-MD,./.mkfs.jffs2.c.dep
        > mkfs.jffs2.c:69:21: sys/acl.h: No such file or directory
        > mkfs.jffs2.c: In function `formalize_posix_acl':
        > mkfs.jffs2.c:1084: error: `ACL_USER_OBJ' undeclared (first use in this
        .....


Modify ramdisk by cpio

  • 解壓縮
    mkdir ramdisk
    cd ramdisk
    cpio -i -F ../ramdisk.cpio
  • 打包
    find ./ -print | cpio -ivH newc -O ../ramdisk.cpio
  • 當 ramdisk size 有更改,需要調整 size 時,有幾處需要更改 (kernel, uboot, ReadyImageForOST.bat),在此假設 ramdisk 調整為4M
    • u-boot/include/configs/omap2430sdp.h
       #define CFG_NAND_BOOT
      -#define CONFIG_BOOTCOMMAND "nand read 80F00000 60000 160000;
      nand read 84000000 1C0000 300000;bootm 80F00000 84000000"
      +#define CONFIG_BOOTCOMMAND "nand read 80F00000 60000 160000;
      nand read 84000000 1C0000 400000;bootm 80F00000 84000000"
      //#define CFG_NO_FLASH I like to add this one but...
      //#define CFG_NAND_LEGACY
      //#define CFG_ENV_IS_IN_NAND
      @@ -160,7 +160,7 @@
    • 注意kernel 裡定義 mtd partition 的地方 或 u-boot CONFIG_BOOTARGS 要改,不然操作時會出現未知的錯誤(ex: erase/write/read 錯地方,因為 partition 配置錯誤)

mtd-utils test

  • 確認所規劃的 mtd 是否正常, Ref
    bash-3.2# cat /proc/mtd
    dev: size erasesize name
    mtd0: 00020000 00020000 "XLDR"
    mtd1: 00040000 00020000 "UBOOT"
    mtd2: 00160000 00020000 "uKernel"
    mtd3: 00400000 00020000 "uRamdisk"
    mtd4: 00040000 00020000 "Test1"
    mtd5: 00100000 00020000 "Test2"
    mtd6: 0f900000 00020000 "UnUsed"
    #mtd_debug info /dev/mtdX (不能使用mtdblockX, mtdblockX 只是提供用來 mount 而已)
    bash-3.2# mtd_debug info /dev/mtd5
    <6>MTD_open
    MTD_open
    <6>MTD_ioctl
    MTD_ioctl
    <6>MTD_ioctl
    MTD_ioctl
    mtd.type = MTD_NANDFLASH<6>MTD_close
    MTD_close

    mtd.flags = MTD_CAP_NANDFLASH
    mtd.size = 1048576 (1M)
    mtd.erasesize = 131072 (128K)
    mtd.writesize = 2048 (2K)
    mtd.oobsize = 64
    regions = 0
  • 將 /dev/mtd5 裡的資料以 HEX 方式 dump 出來看
    nand_dump -p -f /tmp/mtd3 /dev/mtd3
    less /tmp/mtd5
  • erase 完後,再 dump 出來看看,會發現 erase 的部份,數值均為 ff
    flash_erase /dev/mtd5

  • flashcp,若有出現 Attempt to write not page aligned data 的訊息,表示不按頁對齊的方式是不被允許的 (在此是指 2K)。我們可以以下列來操作,將寫滿了 0 的 2k 檔案寫入 flash 就ok了。
    dd if=/dev/zero of=/tmp/zero.img bs=1k count=2
    flashcp /tmp/zero.img /dev/mtd5
    #會發現寫入成功,此時可以 nanddump 出來看看,發現其值全為0

Linux 2.6 的 initramfs 機制

Linux 2.6 的 initramfs 機制

References


之前在做 qemu 做測試,在製作 ramdisk 時,就不是很了解為何有時是用

  1. 以 dd 制作一固定大小的 size, formate 為 ext2 格式
  2. 以 cpio 制作,再以 gzip 壓縮

透過這幾篇文章,可以了解何其間的差異, initrd v.s. initramfs

  1. 其使用的技術不同,歷史的演進
  2. 在開機過程中所佔的角色
  3. 如何製作 initramfs 及測試

Firefox 快速鍵

常常工作到一半,需要切換 Firefox Tab 就得使用滑鼠 找了一下有無內建的快速鍵 真是不錯丫…

Tuesday, August 19, 2008

安裝 Apache/Subversion/Trac on Windows

安裝 Apache/Subversion/Trac on Windows

主要參考:


軟體持續在更新,所以所需的版本及套件依需求會有不同。以下為此次安裝過程中的軟體

  • apache_2.0.63-win32-x86-no_ssl.msi Ref
  • python-2.5.2.msi Ref
  • svn-win32-1.5.1.zip Ref
  • Trac-0.11.1.win32.exe Ref
  • svn-python-1.5.1.win32-py2.5.exe Ref
  • setuptools-0.6c7.win32-py2.5.exe Ref
  • Genshi-0.5.win32-py2.5.exe Ref

目錄架構,參考 Ref

S:
|
|- AppServ (伺服器相關程式)
| |
| |- Apache2 ( Apache 的主要程式檔)
| |
| |- python ( Python 的主要程式檔)
| |
| |- svn ( Subversion 的主要程式檔)
|
|- Repository (檔案庫)
| |
| |- svn
| |
| |- trac

安裝/設定

  • apache_2.0.63-win32-x86-no_ssl.msi
    • Install to 改到 D:\AppServ ,這樣下方 Apache Runtime 的 Install to 會自動變成 S:\AppServ\Apache2 。
    • 我使用預設的 port:80
    • 測試是否可看見網頁 http://localhost
  • svn-win32-1.5.1.zip
    • decompress the file to AppServ and rename to svn
    • copy mod_authz_svn.so and mod_dav_svn.so from svn/bin to AppServ\Apache2\modules
    • 將 S:\AppServ\svn\bin 加到 PATH 系統環境變數裡。
  • python-2.5.2.msi
    • Install to S:\AppServ\python
    • 安裝好後,將 S:\AppServ\python 加入 PATH 系統環境變數裡
  • 以下這幾個執行檔會自動在 Python 的安裝目錄中註冊該模組
    • Install svn-python-1.5.1.win32-py2.5.exe
    • Install Trac-0.11.1.win32.exe
    • setuptools-0.6c7.win32-py2.5.exe
    • Genshi-0.5.win32-py2.5.exe
    • mod_python-3.3.1.win32-py2.5-Apache2.0.exe
      • 需要指定 Apache2的安裝位址 S:\AppServ\Apache2,這時安裝程式會把 mod_python.so 複製到 S:\AppServ\Apache2\modules 底下。
  • Svn/Trac project 設定,請參照 http://blog.roodo.com/jaceju/archives/2703935.html
    • 我目前並未使用任何 plugin
    • 建立 svn 檔案庫
      S:\>cd Repository\svn
      S:\Repository\svn>svnadmin create projectname
    • 建立 trac 檔案庫
      • S:\Appserv\python\Scripts>trac-admin.exe S:\
        Repository\trac\projectname initenv
    • 設定預設使用者
      • S:\Appserv\python\Scripts>trac-admin.exe S:\
        Repository\trac\projectname permission add admin
        TRAC_ADMIN

使用

  • Svn, Ref
    • 取出專案 (此專案必需在 Serv 已建置好了)
      svn co http://10.2.7.65/svn/test
    • 新增單個 檔案/資料夾
      cd test
      mkdir tmpDir
      svn add tmpDir
      svn ci -m 'message' tmpDir
    • 新增一整個資料夾的內容
      mkdir -pv a/aa/{a1,a2}
      mkdir -pv a/bb/{b1,b2}
      svn import a http://10.2.7.65/svn/test/a
    • svn 做壞了,不想要,重建一個時,需要 resync trac with svn
      • s:\>cd Repository\svn
      • s:\Repository\svn>rm -rf projectname
      • s:\Repository\svn>svnadmin create projectname
      • # 若 svn project name 不同了,需要修改 S:\Repository\trac\zeppelin\conf\trac.ini -> [trac] -> repository_dir = s:\Repository\svn\projectname
      • S:\AppServ\python\Scripts>trac-admin.exe S:\Repository\trac\projectname resync

其它

  • 圖片(header_logo)無法正常顯示: please configure the [header_logo] section in trac.ini
    • assigning 一張預設的圖給 header_logo: source
    • S:\Repository\trac\zeppelin\conf\trac.ini -> [header_logo] -> src = trac_banner.png
    • trac_banner.png in S:\AppServ\python\Lib\site-packages\trac\htdocs

Wednesday, August 13, 2008

Terminal 無法正確顯示文字

在 terminal,有時會無法正確的顯示字元 (但在X-windowns裡的terminal卻顯示正常),



而我通常是用 ssh 連進 server 工作的
所以對我而言,最簡單的調整及是確認語系是否設定正確
echo $LANG
export LANG=en_US
來調整 terminal 的語系設定,即可正常 work