Monday, May 14, 2012

PLL (Phase-locked loop)

  • Phase-locked loop    
    • A phase-locked loop or phase lock loop (PLL) is a control system that generates an output signal whose phase is related to the phase of an input "reference" signal. It is an electronic circuit consisting of a variable frequency oscillator and a phase detector. This circuit compares the phase of the input signal with the phase of the signal derived from its output oscillator and adjusts the frequency of its oscillator to keep the phases matched. The signal from the phase detector is used to control the oscillator in a feedback loop.
    • Frequency is the derivative of phase. Keeping the input and output phase in lock step implies keeping the input and output frequencies in lock step. Consequently, a phase-locked loop can track an input frequency, or it can generate a frequency that is a multiple of the input frequency. The former property is used for demodulation, and the latter property is used for indirect frequency synthesis.


  • 目前此 case 的設計:
    • 1. Most internal clocks originate with a 27MHz off-chip crystal.
    • 2. The system contains two, on-chip spread-spectrum phase-locked loops (SSPLLs) which use the 27MHz crystal oscillator clock as their input.
    • 3. Referring to Figure, PLL0 rate multiplies the 27MHz reference clock up to 1350MHz, and only the primary output of PLL0 is used. This 1350MHz output is used by the main system clock generator (cpu_clkgen).
    • 4. We can set the frequency of other device by dividing the primary output of PLL0/PLL1. Example, we set sdmmcclk to 100MHz and sd0clk to 50MHz and observe the frequency with scope after mapping the frequency to GPIO.

  •  Program. 當我們設定好 PLL0 時及相關的周邊倍頻 clock 時,依文件提及,可以將欲觀察的 device's clock mapping 到某二根 GPIO 觀察。以下為我測試的步驟。
    1. 設定 PLL0 (Regs: PLL0_CR0/PLL0_CR1/PLL0_CR2/PLL0_CR3/PLL0_SR)。這些值的設定主要還是來自原廠的提供,因為沒有相關的 Spec 可查)
    2. Enable Clock Gate (Regs: CGCR)。The Clock Gate Control Register allows various clocks inside the ASIC to be powered down under firmware control, to save power when the parts of the ASIC that use them are not in use。所以在測試時,我先將全部的 clock output 全打開。
    3. 將要觀查的 device frequency map to GPIO (Regs: CDCR1)。文中提及,會將欲觀察的 frequency map to GPIOB[31:30],且必需先將此二pin GPIOB[31:30] 設為 AltFun7,再將要觀察的 device frequency 填相對應的值至 CDCR1 中。
    4. 測試過程
      • evb gate_on // Enable all clock gate
      • evb pll0_set // Set PLL0
      • evb pll1_set // Set PLL1
      • evb io_out val // Set GPIOB[31:30] to AltFunc7 and the related value to CDCR1 to observe  the device's frequency

Friday, January 16, 2009

SVN 與 Trac 的備份、還原

-_-,硬碟竟然用不到半年就毀了,看來還是得有良好的備份習慣丫

  • 依之前建立的,只要將 Repository 目錄下的東西保存,即可在之後將資料回復
  • 假設系統毀了,回復步驟為
    1. 重新安裝所需軟體及設定 path
    2. 修改 httpd.conf (apache2 configure file) #Ryan ==================== start
      // enable mod_dav.so,並 load module for svn/trac
      LoadModule dav_module modules/mod_dav.so

      # For Subversion
      LoadModule dav_svn_module modules/mod_dav_svn.so
      LoadModule authz_svn_module modules/mod_authz_svn.so

      # For Trac
      LoadModule python_module modules/mod_python.so
      #Ryan ==================== end

      #Ryan =================== start
      //設定 svn/trac 可以透過 apache2 的尋訪路徑
      <location>
      DAV svn
      SVNParentPath H:/Repository/svn
      # <limitexcept>
      AuthType Basic
      AuthName "CompanyName"
      AuthUserFile "H:/Repository/project-users.db"
      Require valid-user
      # </limitexcept>
      </location>

      <location>
      SetHandler mod_python
      PythonHandler trac.web.modpython_frontend
      PythonOption TracEnvParentDir H:/Repository/trac
      PythonOption TracUriRoot /trac
      AuthType Basic
      AuthName "CompanyName"
      AuthUserFile "H:/Repository/project-users.db"
      Require valid-user
      </location>

      #Ryan =================== end
    3. 此時應該可以看到之前的 Trac project 了 (http://localhost/trac)。 但 trac project 與 svn project 的連結關係仍有問題。
    4. 針對對個 project, 修改 trac.ini 並 resync 即正常。 修改 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

太扯了,硬碟連續出狀況

昨天下午
本還想著目前的工作看來還蠻順利的
看來應該會有空餘的時間可以來看看 Django (想架站寫些 service 來玩玩)
但…但…

在昨天下午二~三時間,端了一杯水回座位上
疑…怎麼當機了(我的系統很少有異常狀況,performance也覺得能接受)
算了,重開機吧
……開機之後進不出,說是某個系統檔案毀損了,需要回復光碟
只能交給 MIS 處理了
……二十分鐘後,接到電話
天丫,竟說我硬碟毀了,完全捉不到…my god, 我 沒 備 份 丫…
看來 MIS 也沒撒,拿回來自己試,只有救回我的工作記錄而已
我是用 Trac 在記東西的,起碼有這在手,之前做的內容就一定能回復,只是需要時間來完成

於是,只好死了心的把硬碟送修,開始從頭建置工作環境了
但今天,竟然發現昨天才從 MIS 接手的新硬碟&系統
竟然無法刪除多個檔案或一個資料夾…天丫,這是什麼情況丫
檢查過了,也無壞毀情況丫,怎會這樣
只好又拿去給 MIS
但無法釐清是給我時的環境就是如此,還是我新安裝程式的問題
-_-,但我裝的也都是工作必要,且之前的工作環境 & 同事都裝的丫
然後就是終極大法 ==> 重灌

怎麼會這樣,太久沒拜拜了嗎
可是我上周末經過土地公廟時有用手拜一下丫
吼…
找個時間,再來好好的拜一下吧

=================================
備份策略

1. 每周將工作項目備份至隨身碟,需有控制版本的功能
2. 每月將資料整理後,備份至 DVD

至於系統&工作環境的部份,就算了吧,真的遇到再重灌,我不想額外買一顆大硬碟

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

Wednesday, August 22, 2007

iPython

iPython, 在 python interepter 下的一個好用的介面。有 Tab-Completion 的功能,也可以當成 shell 來使用,亦還有其它方便有用的功能。文件中都有敘述,真是個好用的輔助功具 ^^ 。

PythonCE

發現了 Python for WinCE,真是開心,終於除了 VC++ 外還多了個選擇。

PythonCE,
裡面的內容介紹的很不錯哦
可以用ActiveSync直接安裝 PythonCE 到 device 上哦。
目前測試在 UE 上跑 .py 是 OK 的
只是速度好像有點慢。

Try PocketConsole 在 EVC++4.0/Packet Pc 2003 SDK 上跑
目前不論在emulator 或是在 Device (WM6) 上都是不能跑的
Rebuilding failed too.

Friday, April 20, 2007

Programmer 的心態

"學習焦慮"症狀似乎總是不定期的在我身上發生。雖然已經儘量在工作之外,再多看些程式相關書籍了,但感覺就像是從大海中取出一瓢水,永遠有更多的東西等待著你去閱讀,讓我覺得蠻無力的。

我想這有很大部份是因為我目前的心態關係吧。
在工作上,總是急著先做出來就好,所以這時常急就章的找出所需的東西,然後能動就ok了,卻缺乏了大架構的視野、全方面的考量,所以常只知其然而不知其所以然,更惶論為何要這樣設計了。
就這樣常被表面的現象而迷惑,未見事物的本質,