2009年6月3日 星期三

vivi原始碼分析 stage1

1.vivi原始碼分析
vivi的原始碼包括arch,init,lib,drivers和include等幾個目錄,共200多個文件。

Vivi主要包括下面幾個目錄:

arch:此目錄包括了所有vivi支持的目標板的子目錄,例如s3c2410目錄。

drivers:其中包括了引導內核需要的設備的驅動程序(MTD和串口)。 MTD目錄下分map、nand和nor三個目錄。

init:這個目錄只有main.c和version.c兩個文件。和普通的C程序一樣,vivi將從main函數開始執行。

lib:一些平台公共的接口代碼,比如time.c裡的udelay()和mdelay()。

include:頭文件的公共目錄,其中的s3c2410.h定義了這塊處理器的一些寄存器。 Platform/smdk2410.h定義了與開發板相關的資源配置參數,我們往往只需要修改這個文件就可以配置目標板的參數,如波特率、引導參數、物理內存映射等。
1.2 vivi的運行
vivi的運行也可以分為兩個階段:
1.2.1 vivi的第一階段
完成含依賴於CPU的體系結構硬件初始化的代碼,包括禁止中斷、初始化串口、複製自身到RAM等。相關代碼集中在head.S(viviarchs3c2410目錄下):Head.S:
#include "config.h"
#include "linkage.h"
#include "machine.h"
@ Start of executable code
ENTRY(_start)
ENTRY(ResetEntryPoint)
@
@ Exception vector table (physical address = 0x00000000) ;異常向量表物理地址
@
@ 0x00: Reset ;復位
b Reset
@ 0x04: Undefined instruction exception ;未定義的指令異常
UndefEntryPoint:
b HandleUndef
@ 0x08: Software interrupt exception ;軟件中斷異常
SWIEntryPoint:
b HandleSWI
@ 0x0c: Prefetch Abort (Instruction Fetch Memory Abort) ;內存操作異常
PrefetchAbortEnteryPoint:
b HandlePrefetchAbort
@ 0x10: Data Access Memory Abort ;數據異常
DataAbortEntryPoint:
b HandleDataAbort
@ 0x14: Not used ;未使用
NotUsedEntryPoint:
b HandleNotUsed
@ 0x18: IRQ(Interrupt Request) exception ;慢速中斷處理
IRQEntryPoint:
b HandleIRQ
@ 0x1c: FIQ(Fast Interrupt Request) exception;快速中斷處理
FIQEntryPoint:
b HandleFIQ
@
@ VIVI magics
@
@ 0x20: magic number so we can verify that we only put
.long 0
@ 0x24:
.long 0
@ 0x28: where this vivi was linked, so we can put it in memory in the right place
.long _start
@ 0x2C: this contains the platform, cpu and machine id
.long ARCHITECTURE_MAGIC
@ 0x30: vivi capabilities
.long 0
#ifdef CONFIG_PM ;vivi考慮不需要使用電源管理
@ 0x34:
b SleepRamProc
#endif
#ifdef CONFIG_TEST
@ 0x38:
b hmi
#endif @
@ Start VIVI head
@
Reset:
@ disable watch dog timer;禁止看門狗計時器
mov r1, #0x53000000 ;WTCON寄存器地址是
0x53000000,清0
mov r2, #0x0
str r2, [r1]
#ifdef CONFIG_S3C2410_MPORT3 ;不符合條件,跳到下面的關中斷
/****在/vivi/include/autoconf.h中#undef CONFIG_S3C2410_MPORT3******/
mov r1, #0x56000000 ;GPACON寄存器地址是
0x56000000
mov r2, #0x00000005
str r2, [r1, #0x70] ;配置GPHCON寄存器
mov r2, #0x00000001
str r2, [r1, #0x78] ;配置GPHUP寄存器
mov r2, #0x00000001
str r2, [r1, #0x74] ;配置GPHDAT寄存器
#endif
@ disable all interrupts ;禁止全部中斷
    mov r1, #INT_CTL_BASE
    mov r2, #0xffffffff
    str r2, [r1, #oINTMSK] ;關閉所有中斷
    ldr r2, =0x7ff
    str r2, [r1, #oINTSUBMSK]
    @ initialise system clocks ;初始化系統時鐘
mov r1, #CLK_CTL_BASE
    mvn r2, #0xff000000
str r2, [r1, #oLOCKTIME]

@ldr r2, mpll_50mhz
@str r2, [r1, #oMPLLCON]
#ifndef CONFIG_S3C2410_MPORT1 ;滿足條件,向下執行
/****在/vivi/include/autoconf.h中#undef CONFIG_S3C2410_MPORT1******/
@ 1:2:4
mov r1, #CLK_CTL_BASE
mov r2, #0x3
str r2, [r1, #oCLKDIVN]
mrc p15, 0, r1, c1, c0, 0 @ read ctrl register
orr r1, r1, #0xc0000000 @ Asynchronous
mcr p15, 0, r1, c1, c0, 0 @ write ctrl register
@ now, CPU clock is 200 Mhz ;CPU的頻率是200MHz
mov r1, #CLK_CTL_BASE
ldr r2, mpll_200mhz
str r2, [r1, #oMPLLCON]
#else
@ 1:2:2
mov r1, #CLK_CTL_BASE
ldr r2, clock_clkdivn
str r2, [r1, #oCLKDIVN]
mrc p15, 0, r1, c1, c0, 0 @ read ctrl register
orr r1, r1, #0xc0000000 @ Asynchronous
mcr p15, 0, r1, c1, c0, 0 @ write ctrl register
@ now, CPU clock is 100 Mhz ;CPU的頻率是100MHz
mov r1, #CLK_CTL_BASE
ldr r2, mpll_100mhz
str r2, [r1, #oMPLLCON]
#endif
bl memsetup ;跳轉到memsetup函數
/*****************************
Memsetup函數的實現:
ENTRY(memsetup)
@ initialise the static memory
@ set memory control registers ;設置內存控制寄存器的初值
mov r1, #MEM_CTL_BASE
adrl r2, mem_cfg_val
/*******************
@
@ Data Area
@
@ Memory configuration values
.align 4
mem_cfg_val: ;定義好的13*4=52個字節初值
.long vBWSCON ;在/vivi/include/platform/smdk2410.h
/****** SDRAM從32位變成16位,需要修改vBWSCON的值******/
.long vBANKCON0
.long vBANKCON1
.long vBANKCON2
.long vBANKCON3
/**********網卡控制器vBANKCON3的值可能需要修改**************/
.long vBANKCON4
.long vBANKCON5
.long vBANKCON6
/****** SDRAM從32位變成16位,可能需要修改vBANKCON6的值******/
.long vBANKCON7
.long vREFRESH
.long vBANKSIZE
/****** SDRAM從64MB變成32MB,需要修改vBANKSIZE的值******/
.long vMRSRB6
.long vMRSRB7
********************/
add r3, r1, #52
1: ldr r4, [r2], #4
str r4, [r1], #4
cmp r1, r3
bne 1b ;循環操作,直到13個寄存器寫入完成
mov pc, lr
/*******************************/
#ifdef CONFIG_PM ;vivi考慮不需要使用電源管理
@ Check if this is a wake-up from sleep
ldr r1, PMST_ADDR
ldr r0, [r1]
tst r0, #(PMST_SMR)
bne WakeupStart ;查看狀態,判斷是否需要跳轉到WakeupStart
#endif
#ifdef CONFIG_S3C2410_SMDK ;SMDK開發板使用
@ All LED on ;點亮開發板上的LED
mov r1, #GPIO_CTL_BASE
add r1, r1, #oGPIO_F ;LED使用GPIOF組的管腳
ldr r2,=0x55aa ;使能EINT0,EINT1,EINT2,EINT3,
;另四個管腳配置成輸出,屏蔽EINT4,5,6,7
str r2, [r1, #oGPIO_CON]
mov r2, #0xff
str r2, [r1, #oGPIO_UP] ;disable the pull-up function
mov r2, #0x00
str r2, [r1, #oGPIO_DAT]
#endif
#if 0
@ SVC
mrs r0, cpsr
bic r0, r0, #0xdf
orr r1, r0, #0xd3
msr cpsr_all, r1
#endif
@ set GPIO for UART ;設置串口
mov r1, #GPIO_CTL_BASE
add r1, r1, #oGPIO_H ;設置GPIO_H組管腳為串口
ldr r2, gpio_con_uart
str r2, [r1, #oGPIO_CON]
ldr r2, gpio_up_uart
str r2, [r1, #oGPIO_UP]
/*************************

2009年5月7日 星期四

在pc上製作jffs2 image及mount jffs2在loop back上

1.製作jffs2 image
請確認有mkfs.jffs2指令或事先安裝mtd-tools套件
假設 /jffs2 目錄製作成 jffs2.img 如下
#mkfs.jffs2 -d /jffs2 -o /jffs2.img -l iVU

2.mount jffs2.img在loopback上
請載入以下modules
modprobe mtdcore
modprobe jffs2
modprobe mtdram
modprobe mtdchar
modprobe mtdblock
確認以上modules會產生/dev/mtd0 及/mtd/mtdblock0檔案
dd if=/jffs2.img of=/dev/mtd0
mount -t jffs2 /dev/mtdblock0 /mnt
完成

2009年4月20日 星期一

u-boot 開機程式流程

64M SDRAM     地址是 0x30000000---0x33FFFFFF
------------------------------------------------------------------------------------------------------------------

我們在flash的開始處燒寫了u-boot.bin,這是可執行的二進制文件
注意和ELF可執行性文件是有區別的, 可察看 u-boot.map 參照記憶體位址是否正確.

cpu上電後可以從直接從flash地址0處取指令來執行

開始的代碼在 u-boot\cpu\arm920t\start.S中

這裡需要提一下編譯鏈接時用到的一個很重要的鏈接文件
u-boot/board/smdk2440/u-boot.lds
這個文件給出了代碼中各標號的基地址,和各個段的鏈接順序
ENTRY(_start)
SECTIONS
{
        . = 0x00000000;

        . = ALIGN(4);
 .text      :
 {
   cpu/arm920t/start.o (.text)
   *(.text)
 }

        . = ALIGN(4);
        .rodata : { *(.rodata) }

        . = ALIGN(4);
        .data : { *(.data) }

        . = ALIGN(4);
        .got : { *(.got) }

 armboot_end_data = .;

        . = ALIGN(4);
        .bss : { *(.bss) }

 armboot_end = .;
}
可以看到程序的入口是 _start 標號指示的,而 cpu/arm920t/start.o
則被安排在程序最開始的地方,這個標號就是在start.s中
但是還有一點是需要特別注意的,開始我也是因為這個地方而沒有很好地理解程序
雖然lds中有 . = 0x00000000 這一句,指示鏈接基地址,不過其實這句是不起作用的,
真正的鏈接基地址在 board/samsung/smdk2440/config.mk 中指定的
LDFLAGS += -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE)
其中-Ttext $(TEXT_BASE)就是指定鏈接地址為TEXT_BASE的值




因而是可變的,TEXT_BASE在 board/samsung/smdk2440/config.mk中定義
TEXT_BASE = 0x33F00000
board/samsung/smdk2440/config.mk 是包括到Makefile中的,
在Makefile中有$(LD) $(LDFLAGS) $(OBJS) $(LIBS) $(LIBS) -Map u-boot.map -o u-boot
所以說起來真正的鏈接地址是0x33F00000,其實這樣在把u-boot拷到Ram中就可以實現無縫跳轉了
.globl _start
_start: b       reset
跳到renset
reset: ldr     r0, =pWTCON
 mov     r1, #0x0
 str     r1, [r0]
..........................
 bl cpu_init_crit  //bl跳轉會回來
relocate: //下面開始要把u-boot拷到Ram中
 adr r0, _start  /* r0 <- current position of code */
 ldr r2, _armboot_start
 ldr r3, _armboot_end
 sub r2, r3, r2  /* r2 <- size of armboot */
 ldr r1, _TEXT_BASE  /* r1 <- destination address */
 add r2, r0, r2  /* r2 <- source end address */
以上代碼需要注意的一點是 adr 和 ldr 的區別
adr取得是當前pc相關的偏移地址,在這里程序還是在flash中運行
所以取得地址是以0x0為基址的
而ldr取的是_armboot_start所指的值
.globl _armboot_start
_armboot_start:
 .word _start
看到它的值也是_start的地址,不過我們這裡取的是絕對地址,是在鏈接是確定的以
TEXT_BASE為基址的.由於_start的偏移是0,所以r0是0,r2就是TEXT_BASE
copy_loop:
 ldmia r0!, {r3-r10}
 stmia r1!, {r3-r10}
 cmp r0, r2
 ble copy_loop
循環copy
 ldr r0, _armboot_end  /* set up the stack */
 add r0, r0, #CONFIG_STACKSIZE
 sub sp, r0, #12  /* leave 3 words for abort-stack */

 ldr pc, _start_armboot
_start_armboot: .word start_armboot

//通過這一句跳轉到u-boot\lib_arm\board.c中的start_armboot函數去執行了
start_armboot的絕對地址也是以TEXT_BASE為基址的,所以可以順利的實現無縫跳轉了.
接著下來就是一系列初始化的工作了
首先定義了一個全局的數據結構 gd_t gd_data;
DECLARE_GLOBAL_DATA_PTR 這個宏定義的是一個全局的gd_t類型的指針gd
gd = &gd_data;
這樣以後就可以用gd來訪問gd_data這個數據結構了
 for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
  if ((*init_fnc_ptr)() != 0) {
   hang ();
  }
 }
init_fnc_ptr中是一系列初始化函數的指針
init_fnc_t *init_sequence[] = {
 cpu_init,  /* basic cpu dependent setup */
 board_init,  /* basic board dependent setup */
 interrupt_init,  /* set up exceptions */
 env_init,  /* initialize environment */
 init_baudrate,  /* initialze baudrate settings */
 serial_init,  /* serial communications setup */
 display_banner,
 dram_init,  /* configure available RAM banks */
 display_dram_config,

 NULL,
};
基本上serial_init後我們就可以用printf函數來打印信息了.
 for (;;) {
  main_loop ();
 }
進入了主循環,在M:\u-boot\common\main.c中
 {
  char c = 'y';
  unsigned long timedata;
  printf("start linux now(y/n):");
  timedata = 0;
  for (;;) {
   while (!tstc()) { /* while no incoming data */
    if (timedata++ > 3000 * 100 *3)
     goto bootm; /* timed out */
   }
  c = getc();
  }
tstc()是測試串口是否有數據輸入,顯然沒有的話就會等待time out跳出
bootm:
  if(c == 'y'||c == 'Y'){
   strcpy(lastcommand , "bootm 30008000 30800000\r");
   flag = 0;
   rc = run_command (lastcommand, flag);
   if (rc <= 0) {
    /* invalid command or not repeatable, forget it */
    lastcommand[0] = 0;
   }
  }
  else{
   printf("\n\n");
  }
 }
這樣如果串口沒有輸入或者輸入時y Y 的話,就會去執行bootm 30008000 30800000\r這條命令
否則就會到u-boot的命令行等待輸入.
執行bootm 30008000 30800000\r這條命令會調用u-boot\common\cmd_bootm.c中的
do_bootm函數,具體的命令怎樣被分解,選擇調用函數的機制我就不多說了,追著run_command去就是了
在do_bootm中調用了do_bootm_linux函數,這個函數在u-boot\lib_arm\armlinux.c中
    ret = memcpy((void *)0x30008000, (void *)0x40000, 0x100000);
    if (ret != (void *)0x30008000)
     printf("copy kernel failed\n");
    else
    printf("copy kernel done\n");   

    ret = memcpy((void *)0x30800000, (void *)0x140000, 0x440000);
    if (ret != (void *)0x30800000)
              printf("haha failed\n");
    else
              printf("copy ramdisk done\n");

首先把kernel和ramdisk都拷到Ram相應的地方去.
    setup_linux_param(0x30000000 + LINUX_PARAM_OFFSET); //也在armlinux.c中
    #define LINUX_PARAM_OFFSET 0x100
建立要傳給內核的參數,參數的地址都是固定的,所以內核也知道去這裡取參數
參數格式比較複雜,我這裡好像傳得參數不多
void setup_linux_param(ulong param_base)
{
 struct param_struct *params = (struct param_struct *)param_base;
...............
}
只是通過一個param_struct的結構體來傳參數的,不過現在一般都用另一種tag標記的傳參方法
一個主要的參數時char linux_cmd[] = "initrd=0x30800000,0x440000  root=/dev/ram init=/linuxrc console=ttyS0";
 if (linux_cmd == NULL) {
  printf("Wrong magic: could not found linux command line\n");
 } else {
  memcpy(params->commandline, linux_cmd, strlen(linux_cmd) + 1);
  printf("linux command line is: \"%s\"\n", linux_cmd);
 }
是比較重要的.移植的時候常常需要修改
接著call_linux(0, 0xc1, 0x30008000); 看出來是準備調到linux去了
0xc1是machine type,這三個參數分別給了r0,r1,r2,這些都是調用內核的約定
void  call_linux(long a0, long a1, long a2)
{
__asm__(
 "mov r0, %0\n"
 "mov r1, %1\n"
 "mov r2, %2\n"
 "mov ip, #0\n"
 "mcr p15, 0, ip, c13, c0, 0\n" /* zero PID */
 "mcr p15, 0, ip, c7, c7, 0\n" /* invalidate I,D caches */
 "mcr p15, 0, ip, c7, c10, 4\n" /* drain write buffer */
 "mcr p15, 0, ip, c8, c7, 0\n" /* invalidate I,D TLBs */
 "mrc p15, 0, ip, c1, c0, 0\n" /* get control register */
 "bic ip, ip, #0x0001\n"  /* disable MMU */
 "mcr p15, 0, ip, c1, c0, 0\n" /* write control register */
 "mov pc, r2\n"
 "nop\n"
 "nop\n"
 : /* no outpus */
 : "r" (a0), "r" (a1), "r" (a2)
 );
}
mov pc, r2 就是這句吧,調到了30008000去執行內核了

接下來就到內核了吧

2009年4月2日 星期四

Embedded Linux Booting Process

往往開發embedded linux device的開發者都會面臨到一個大問題就是開機過程太久,
Linux在開機時會將一連串的程序叫起並啟動, 所以會花許久的時間等待所有程序被一一叫起,
在這邊介紹兩種方法可以平行處理初始化的程序.






先介紹傳統PC上linux開機流程是如何運作的




BIOS –> Kernel Boot –> System Init



  • BIOS 初始化硬體週邊, 例如主機板, CD-ROM, …
  • Kernel Boot



第1階段的Boot程式是存放在MBR之中, 第1階段的Boot loader透過partition
table找到第二階段的Boot loader程式, 並將他load進SDRAM並執行它, 接下來會將kernel
image和initial RAM disk image (initrd)也會被load到SDRAM上.




Kernel Boot雖然是很複雜的過程, 但幾乎都寫成機器語言了, 所以Kernel Boot執行的時間相當短,
執行完後第一個被執行的程序是init, 是所有程序之母



  • System Init



Linux是利用Init程序去初始化所有服務跟應用程式, 會開啟/etc/inittab檔案, 裡面可以設定如何初始化整個系統,
下面是個configuration example, 裡面的格式為id:runlevel:action:process



# The default runlevel


id:2:initdefault






# Boot-time system configuration/initialization script


si::sysinit:/etc/init.d/rcS






# Runlevels


l0:0:wait:/etc/init.d/rc 0


l1:1:wait:/etc/init.d/rc 1


l2:2:wait:/etc/init.d/rc 2


l3:3:wait:/etc/init.d/rc 3


l4:4:wait:/etc/init.d/rc 4


l5:5:wait:/etc/init.d/rc 5


l6:6:wait:/etc/init.d/rc 6


z6:6:respawn:/sbin/sulogin






# How to react to ctrl-alt-del


ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now



Init程序是有缺點的,所花的時間是串列累加的, 若能改成連漪式累加時間是最佳的選擇, 下一篇會介紹3種改進boot時間的程序:
Initng, Upstart, Monitoring init performance with bootchart




參考文獻:




1.
http://www.ibm.com/developerworks/linux/library/l-boot-faster/




2. http://209.85.175.104/search?q=cache:aU49jDJGEhUJ:www.zhuaxia.com/pre_channel/4806028/%3FlogId%3D181+openmoko+%E6%B5%81%E7%A8%8B&hl=zh-TW&ct=clnk&cd=7&gl=tw

2009年3月7日 星期六

ubuntu8.04 開發環境建置

ubuntu 針對8.04版~開發環境設置







1. 安裝 C/C++的 Man 手冊,。






   sudo apt-get install manpages-dev


2. 安裝 gcc,g++,make





   sudo apt-get install build-essential


3. 安裝頭文件和庫(因為安裝4.2版會缺少底下的檔案!所以要先下載安裝!)








 wget http://ftp.twaren.net/Linux/Ubuntu/ubuntu/pool/main/l/linux/linux-libc-dev_2.6.24-19.41_i386.deb




   sudo apt-get install libc6-dev libstdc++6-4.2-dev




4. 安裝 libncurses5-dev





   sudo apt-get install libncurses5-dev


5. 安裝 gdb 調試器






   sudo apt-get install gdb


6. 安裝安裝圖形界面 ddd 調試器






   sudo apt-get install ddd


7. 安裝 automake 工具





sudo apt-get install automake



sudo apt-get install autoconf



sudo apt-get install autogen





8. 安裝 indent





sudo apt-get install indent


    調整 C 原始代碼文件的格式。






sudo apt-get install libtool


    

9. 安裝文檔





sudo apt-get install binutils-doc cpp-doc gcc-4.2-doc gcc-doc glibc-doc libstdc++6-4.2-doc stl-manual




cpp-4.2-doc


10. 安裝編輯器






sudo apt-get install emacs21






以上十個步驟 如果已經安裝過無數次 請下載環境懶人包


 環境懶人包使用方法如下:



 下載環境懶人包 123.sh 儲存到/home



 進入/home 執行 sh 123.sh 就可以開始安裝了!! 



安裝交叉編譯器








   cd /home/ubuntu




   wget http://192.192.6.66/webhd/u-boot/cross_4.0.3.tar.bz2




   sudo mkdir /usr/local/arm
   cd /usr/local/arm

   sudo tar jxvf /home/ubuntu/cross-4.0.3.tar.bz2




Note:  toolchains的檔案不一定是 arm-linux-toolchains.tgz



例如: arm-linux-gcc-3.4.1.tar.bz2 or cross-4.0.3.tar.bz2



請在執行完成后查看是否存在/usr/local/arm 文件夾。

把交叉編譯器的路徑加入到 PATH,以方便使用:





   sudo vi /etc/bash.bashrc


加入如下代碼:





   if [ -d /usr/local/arm ] ; then

   PATH=/usr/local/arm/4.0.3/bin:"${PATH}"

   fi



 

2009年2月9日 星期一

minigui

安裝 qvfb 在 qt3-dev-tools-embedded 這個套件中就有 qvfb 程式:
$apt-get install qt3-dev-tools-embedded
安裝libjpeg-dev 資料庫 
$sudo apt-get install libjpeg-dev
 ------->>
執行 qvfb 必須調整設定
   640*480-32bpp display mode. 
範例程式必須在640*480以上模式才能正常顯示!!
Installing resource files of MiniGUI
    必須按照下列步驟安裝:
        1) Use `tar' to extract minigui-res-1.6.x.tar.gz. You can use
           the following command:
           $ tar zxf minigui-res-1.6.x.tar.gz
        2) Change to new directory and run `make' as a super user:
           $ sudo make install

Configure and compile MiniGUI
    MiniGUI uses `automake' and `autoconf', so configuration and compilation
    of MiniGUI are very easy:
        1) Use `tar' to extract `libminigui-1.6.x.tar.gz' to a new directory:
           $ tar zxf libminigui-1.6.x.tar.gz
        2) Change to the new directory and run `./configure':
           $ ./configure
        3) Run the following commands to compile and install MiniGUI:
           $ make;sudo make install;
        4) By default, libraries of MiniGUI will be installed in
           `/usr/local/lib'. You should make sure that this directory
           is listed in `/etc/ld.so.conf' file. And after having installed
           them, you should run the following command to update the cache
           of shared library system:
           $ sudo ldconfig
        5) If you want to specify which features MiniGUI provides, you
           can run
           $ ./configure --help
           to see the complete configuration options listed, then disable or
           enable some features by using command line switches. For example,
           if you do not want MiniGUI to load JPEG pictures via the function
           LoadBitmap, you can use
           $ ./configure --disable-jpgsupport
      
 執行範例程式
 $ tar zxvf mde-1.6.10.tar.gz
 $ cd mde-1.6.10
 $ ./configure
 $ make
 $ cd same
 $ ./same
----->> 底下是範例 mgis
  1. Unpack proj-4.4.7.tar.gz
    • ./configure
    • make
    • sudo make install
  2. Unpack gdal-1.2.6.tar.gz
    • ./configure --withou-pg --without-python --without-jasper --without-odbc
    • make
    • sudo make install
  3. Unpack mgis-1.0.tar.gz
    • ./configure
    • make

所須要的程式都在這個網址http://www.minigui.org/downloads/

2009年2月6日 星期五

VIVI Bootloader 如何新增指令?

 STEP1.




先來設定一下工作目錄所在位置, 在這裡我的 Bootloader 資料放在  /home/dclab/bootLoader/vivi  ,所以後面就用 $VIVI表示




# export VIVI=/home/dclab/bootLoader/vivi




 STEP2.




首先我們新增一個檔案 led.c  , 這個檔案內容負責宣告新增指令用!




# vim $VIVI/lib/led.c







[檔案]  $vivi/lib/led.c:




#include <config.h>
#include <command.h>
#include <types.h>
#include "printk.h"

void command_led(int argc, const char **argv){
    printk("show led....\n");               //    當執行指令後, 螢幕顯示出來的資訊內容!
}   

user_command_t led_cmd = {                                //    宣告一個指令結構
    "led",                                                               //     命令的名稱   
    command_led,                                                  //     實現該命令的具體函數
    NULL,                                                              //     指向下一條命令的指
    "help led [{cmds}]\t\t\t -- Led show program"    //     命令的使用說明
};







[參閱]  $vivi/include/command.h:




typedef struct user_command {
const char *name;
void (*cmdfunc)(int argc, const char **);
struct user_command *next_cmd;
const char *helpstr;
} user_command_t;













 STEP3.



[檔案]  修改 $vivi/lib/command.c 檔案, 尋找 int init_builtin_cmds(void)  處, 新增以下內容:





+ :351    extern user_command_t led_cmd;  // 新增於 int init_builtin_cmds(void) 上方

+ :398    add_command(&led_cmd);             // 新增於 int init_builtin_cmds(void) 內








[檔案]  修改 $vivi/lib/Makefile 檔案, 新增以下內容





+ :10   obj-y += led.o








 STEP4.




接著就可以編譯 vivi 看看




# make clean
# make








開發版上測試指令, 輸入上方宣告的指令  " led "




# led




























參考資料:
http://blog.csdn.net/hansir007/archive/2007/08/29/1764077.aspx




http://www.cublog.cn/u/21948/showart.php?id=379460