系統移植手冊


實驗一  交叉工具鏈的安裝    
實驗二  u-boot的燒寫及使用    
實驗三  u-boot-2010.03的移植    
實驗四 內核的配置和編譯    
實驗五 網卡驅動的移植    
實驗六 LED驅動的移植    
實驗七  Nand flash驅動的移植    
實驗八 LCD驅動的移植    
實驗九 USB驅動的移植    
實驗十  SD卡驅動的移植    
實驗十一  yaffs2文件系統的移植    
實驗十二 內核調試    
實驗十三 內存調試    
實驗十四 文件系統的移植    

php

實驗一 交叉工具鏈的安裝

【實驗目的】node

       瞭解交叉工具鏈的編譯過程及其使用。linux

       說明:在實驗中命令行提示符「$」表示在主機上運行,「#」表示在目標板上運行c++

【實驗環境】shell

一、  ubuntu 10.10發行版編程

二、  FS_S5PC100平臺ubuntu

【實驗步驟】vim

       一、若是要本身編譯工具鏈,從如下連接下載源碼數組

       crosstools-ng下載地址bash

http://ymorin.is-a-geek.org/download/crosstool-ng/

       同時對每個版本都有相應的補丁咱們儘可能把這些補丁打上,這些補丁的下載地址是

http://ymorin.is-a-geek.org/download/crosstool-ng/01-fixes/

 

二、工具的安裝

在使用以前先安裝下列軟件

$ sudo  apt-get  install  gawk  autotools-dev  automake  texinfo  libtool  cvs  patch  bison  flex  libncurses5-dev

爲了節約時間,咱們已下載了相關的安裝包,你們能夠在本地安裝

$ sudo  dpkg  -i  tools/*.deb

 

三、   解壓工具鏈壓縮包

$  cd  ~

$ tar  xvf  arm-cortex_a8-linux-gnueabi.tar.bz2

$ mv  arm-cortex_a8  toolchain

 

四、   環境變量的添加

修改文件/etc/bash.bashrc添加以下內容

export  PATH=$PATH:/home/linux/toolchain/bin

重啓配置文件

$ source  /etc/bash.bashrc

 

五、   工具鏈的測試

$ arm-cortex_a8-linux-gnueabi-gcc  –v

Using built-in specs.

Target : arm-cortex_a8-linux-gnueabi

Configured with: /home/linux/src/gcc-4.4.6/configure --build=i686-build_pc-linux-gnu --host=i686-build_pc-linux-gnu --target=arm-cortex_a8-linux-gnueabi --prefix=/home/linux/toolchain --with-sysroot=/home/linux/toolchain/arm-cortex_a8-linux-gnueabi//sys-root --enable-languages=c,c++,fortran --disable-multilib --with-arch=armv7-a    --with-float=soft --with-pkgversion=crosstool-NG-1.12.4-none --disable-sjlj-exceptions --enable-__cxa_atexit --disable-libmudflap --with-gmp=/home/linux/toolchain/toolchain-build/targets/arm-cortex_a8-linux-gnueabi/build/static --with-mpfr=/home/linux/ toolchain/toolchain-build/targets/arm-cortex_a8-linux-gnueabi/build/static --enable-threads=posix --enable-target-optspace --with-local-prefix=/home/linux/toolchain/arm-cortex_a8-linux-gnueabi//sys-root --disable-nls --enable-symvers=gnu --enable-c99 --enable-long-long

Thread model: posix

gcc version 4.4.6 (crosstool-NG  1.12.4)

這樣咱們的交叉工具鏈就安裝好了

實驗二 u-boot的燒寫及使用

【實驗目的】

       瞭解u-boot的經常使用命令和linux內核的引導。

【實驗環境】

一、  ubuntu 10.10發行版

二、  u-boot-2010.03

三、  FS_S5PC100平臺

四、  交叉編譯器 arm-cortex_a8-linux-gnueabi-gcc

【實驗步驟】

一、  u-boot的燒寫

         先認真閱讀FS_S5PC100平臺用戶手冊

 

    運行串口通訊程序(putty)

 

關閉開發板電源,將撥碼開關SW1調至0001(usb啓動模式)後打開電源

         

加載運行USB Installer_DDR2.bin

USB Port à Transmit à Transmit,選中image目錄下的USB Installer_DDR2.bin  

        

        

 

加載運行u-boot.bin

USB Port à Transmit à Transmit,選中image目錄下的u-boot.bin  以下圖所示

 

 

串口終端下能看到以下內容(若是有倒計時數字,按任意鍵出現提示符)

        

設置並保存環境變量

# printenv     // 查看環境變量的值並按以下設置

# setenv  baudrate  115200

# setenv  ethaddr  11:22:33:44:55:66

# setenv  gatewayip  192.168.1.1

# setenv  serverip  192.168.1.100        //  serverip要和虛擬機的ip相同

# setenv  ipaddr  192.168.1.200       //  ipaddr也能夠是192.168.1.x其餘值

# setenv  netmask  255.255.255.0

 

保存環境變量

# saveenv

 

拷貝image/u-boot.bin到虛擬機/tftpboot目錄下

 

        測試網絡是否連通  //  只能經過u-boot去ping虛擬機

        #ping  <serverip>

 

燒寫u-boot.bin到nand flash起始地址

# tftp  20008000  u-boot.bin

# nand  erase  0  40000

# nand  write  20008000  0  40000

 

關閉開發板電源,將撥碼開關SW1調至0000(nand啓動模式)後打開電源

 

二、  經過網絡加載內核和文件系統

設置內核啓動參數

# setenv  bootargs  root=nfs  nfsroot=192.168.1.100:/source/rootfs  ip=192.168.1.200  init=/linuxrc  console=ttySAC0,115200

# saveenv

 

設置虛擬機

拷貝/image/zImage到虛擬機/tftpboot目錄下

解壓rootfs.tgz到虛擬機/source目錄下

修改虛擬機nfs配置文件/etc/exports,添加以下內容並重啓nfs服務

/source/rootfs  *(rw,sync,no_subtree_check,no_root_squash)

$sudo  /etc/init.d/nfs-kernel-server  restart

 

下載、啓動內核

# tftp  20008000  zImage

# go  20008000

 

三、  從nand flash加載內核和文件系統

拷貝rootfs.cramfs到虛擬機/tftpboot目錄下

燒寫內核鏡像到nand flash

# tftp  20008000  zImage

# nand  erase  100000  300000

# nand  write  20008000  100000  300000

 

      燒寫文件系統鏡像到nand  flash

# tftp  20008000  rootfs.cramfs

# nand  erase  400000  400000

# nand  write  20008000  400000  400000

 

設置啓動參數

# setenv  bootdelay  3

# setenv  bootcmd  nand  read  20008000  100000  300000\; go 20008000

# setenv  bootargs  root=/dev/mtdblock2  ip=192.168.1.200  init=/linuxrc  console=ttySAC0,115200

# saveenv

 

四、 從新啓動開發板,u-boot自動加載、執行內核

 

 

五、  u-boot其餘命令

u-boot支持的命令咱們能夠經過在終端上輸入」?」查看

 

 

六、  交叉編譯和交叉調試

  • 編輯程序源碼myapp.c
  • 交叉編譯後複製到/source/rootfs   (編譯時添加選項-g)
  • 複製gdbserver到/source/rootfs/bin    (gdbserver在工具鏈安裝路徑下查找)
  • 在開發板上以下運行

# gdbserver  192.168.1.200:1234  myapp &

  • 在主機上運行交叉調試器

$ arm-cortex_a8-linux-gnueabi-gdb  myapp

  • 在交叉調試器下和開發板gdbserver創建鏈接

(gdb)  target  remote  192.168.1.200:1234

  • 設置斷點,輸入命令c開始調試程序(注意觀察串口輸出)

實驗三 u-boot-2010.03的移植

【實驗目的】

       瞭解u-boot-2010.03的代碼結構及移植方法。

【實驗環境】

一、  ubuntu 10.10發行版

二、  u-boot-2010.03

三、  FS_S5PC100平臺

四、  交叉編譯器 arm-cortex_a8-linux-gnueabi-gcc

【實驗步驟】

       說明:後面實驗中的命令行提示符是($)則爲主機命令(主機上執行),(#)則爲開發板命令(開發板上執行)

1、創建本身的平臺

一、 下載源碼

咱們能夠在下面這個網站上下載最新的和之前任一版本的uboot

ftp://ftp.denx.de/pub/u-boot/

 

二、 解壓uboot源碼並進入目錄

$ tar  xvf  u-boot-2010.03.tar.gz

$ cd  u-boot-2010.03

三、 添加fsc100平臺信息

咱們關心的板級相關文件或目錄

u-boot-2010.03/Makefile

u-boot- 2010.03/include/configs/smdkc100.h

u-boot- 2010.03 /cpu/arm_cortexa8/start.S

u-boot- 2010.03 /board/samsung/smdkc100

u-boot- 2010.03 /lib_arm

smdkc100是使用s5pc100芯片的參考板,咱們在其基礎之上移植fsc100

$ cd  board/samsung/

$ cp  –a  smdkc100  fsc100

$ cd  fsc100

$ mv  smdkc100.c  fsc100.c

$ vim  Makefile

修改

COBJS-y := smdkc100.o

COBJS-y := fsc100.o

 

$ cd  include/configs

$ cp  smdkc100.h  fsc100.h

 

修改u-boot頂層目錄下的Makefile,指定交叉工具鏈

$ vim  Makefile

ifeq ($(HOSTARCH, $(ARCH))

CROSS_COMPILE ?=

endif

下添加:

ifeq (arm, $(ARCH))

CROSS_COMPILE ?= arm-cortex_a8-linux-gnueabi-

endif

 

在u-boot頂層目錄下的Makefile中添加fsc100配置信息

$ vim  Makefile

smdkc100_config: unconfig

    @$(MKCONFIG)  $(@:_config=)  arm  arm_cortexa8  smdkc100  samsung s5pc1xx

下添加:

fsc100_config: unconfig

   @$(MKCONFIG)  $(@:_config=)  arm  arm_cortexa8  fsc100  samsung  s5pc1xx

四、 編譯u-boot-2010.03

$ make  distclean

$ make  fsc100_config

$ make

編譯完成後生成的u-boot.bin就是可執行的鏡像文件。可是該文件只能在smdkc100平臺上運行,咱們須要對u-boot源代碼進行相應的修改。

2、針對咱們的fsc100平臺進行相應的移植

一、 修改include/configs/fsc100.h

修改內存基址

#define  CONFIG_SYS_SDRAM_BASE   0x30000000

#define  CONFIG_SYS_SDRAM_BASE   0x20000000

 

#undef   CONFIG_CMD_NAND

改爲

#define  CONFIG_CMD_NAND

 

#undef   CONFIG_CMD_NET

改爲

#define  CONFIG_CMD_NET

 

#define   CONFIG_CMD_NAND

後添加

#define  CONFIG_SYS_ICACHE_OFF          1

 

註釋如下內容

#define  CONFIG_CMD_ONENAND

 

註釋如下內容

#define  MTDIDS_DEFAULT  「onenand…」

……

#define  CONFIG_UPDATEB  「updateb=……」

 

註釋如下內容

#define  CONFIG_EXTRA_ENV_SETTINGS          \

……

「ubi=enabled」

 

修改提示符

#define  CONFIG_SYS_PROMPT             「SMDKC100  #  」

#define  CONFIG_SYS_PROMPT          FSC100  #  」

 

修改

#define  CONFIG_SYS_MEMTEST_END      (CONFIG_SYS_SDRAM_BASE+0x5e00000)

#define  CONFIG_SYS_MEMTEST_END      (CONFIG_SYS_SDRAM_BASE+0x10000000)

 

修改內核加載地址

#define  CONFIG_SYS_LOAD_ADDR              CONFIG_SYS_SDRAM_BASE

#define  CONFIG_SYS_LOAD_ADDR        (CONFIG_SYS_SDRAM_BASE+0x8000)

 

修改內存容量

#define  PHYS_SDRAM_1_SIZE        (128 << 20)

#define  PHYS_SDRAM_1_SIZE             (256 << 20)

 

修改環境變量存放位置

#define   CONFIG_ENV_IS_IN_ONENAND           1

#define  CONFIG_ENV_IS_IN_NAND            1

 

註釋如下內容

#define   CONFIG_USE_ONENAND_BOARD_INIT

                    到

#define  CONFIG_SYS_ONENAND_BASE              0xE7100000

 

#define  CONFIG_DOS_PARTITION            1

下面添加以下信息

 

添加NAND信息

#define  CONFIG_SYS_MAX_NAND_DEVICE            1

#define  CONFIG_SYS_NAND_MAX_CHIPS        1

#define  CONFIG_SYS_NAND_BASE            0xE7200000

#define  CONFIG_NAND_S5PC100         1

#define  CONFIG_NAND_BL1_8BIT_ECC            1

#define  CFG_NAND_HWECC         1

 

#define  NAND_ENABLE_CE() (NFCONT_REG &= ~(1<<1))

#define  NAND_DISABLE_CE()       (NFCONT_REG |= (1<<1))

#define  NF_TRANSRnB()    do {while (! (NFSTAT_REG  & (1<<0)) );} while(0)

 

添加網卡信息

#ifdef  CONFIG_CMD_NET

#define  CONFIG_NET_MULTI

#define  CONFIG_CMD_PING         1

#define  CONFIG_DRIVER_DM9000             1

#define  CONFIG_DM9000_BASE           0x88000000

#define  DM9000_IO   CONFIG_DM9000_BASE

#define  DM9000_DATA   (CONFIG_DM9000_BASE  +  4)

#define  CONFIG_DM9000_USE_16BIT

#define  CONFIG_DM9000_NO_SROM         1

#define  CONFIG_ETHADDR   11:22:33:44:55:66

#define  CONFIG_IPADDR          192.168.1.200

#define  CONFIG_SERVERIP          192.168.1.100

#define  CONFIG_GATEWAYIP     192.168.1.1

#define  CONFIG_NETMASK   255.255.255.0

#endif

 

二、 複製lowlevel_init.S  mem_setup.Sboard/samsung/fsc100

上述代碼專門針對fsc100使用的內存進行初始化,可參考相關芯片手冊

 

三、 複製fsc100.cboard/smsung/fsc100 覆蓋原來的fsc100.c

fsc100.c 包含的是板級初始化函數

 

四、 board/samsung/fsc100/目錄下添加nand_cp.c

#include  <common.h>

#ifdef  CONFIG_S5PC1XX

#include  <asm/io.h>

#include  <linux/mtd/nand.h>

 

#define  _REG__(x)          (*(volatile  unsigned  long  *)(x))

#define  _REGb__(x)        (*(volatile  unsigned  char  *)(x))

#define  NFCONT_REG           _REG__(0xE7200004)

#define  NFCMD_REG          _REG__(0xE7200008)

#define  NFADDR_REG        _REG__(0xE720000C)

#define  NFDATA8_REG      _REGb__(0xE7200010)

#define  NFSTAT_REG         _REG__(0xE7200028)

 

#define  NAND_CONTROL_ENABLE()      (NFCONT_REG |= (1 << 0))

 

static  int  nandll_read_page (uchar  *buf,  ulong  addr,  int  large_block)

{

     int  i;

     int  page_size = 512;

    

if  (large_block)   page_size = 2048;

     NAND_ENABLE_CE();

     NFCMD_REG = NAND_CMD_READ0;

     /*  Write  Address  */

     NFADDR_REG = 0;

     if  (large_block)   NFADDR_REG  =  0;

     NFADDR_REG = (addr) & 0xff;

     NFADDR_REG = (addr >> 8) & 0xff;

     NFADDR_REG = (addr >> 16) & 0xff;

 

     if  (large_block)   NFCMD_REG = NAND_CMD_READSTART;

     NF_TRANSRnB();

     for (i=0; i<page_size; i++) {

         *buf++ = NFDATA8_REG;

     }

     NAND_DISABLE_CE();

     return  0;

}

 

static  int  nandll_read_blocks (ulong  dst_addr,  ulong  size,  int  large_block)

{

     uchar  *buf = (uchar *)dst_addr;

     int  i, pages;

     uint  page_shift = 9;

 

     if  (large_block)  page_shift = 11;

     pages  =  size >> page_shift;

     for (i=0;  i<pages; i++)  {

        nandll_read_page(buf,  i,  large_block);

        buf  +=  (1 << page_shift);

}

return  0;

}

 

int  copy_uboot_to_ram (void)

{

     int  i, large_block = 0;

     vu_char  id;

 

     NAND_CONTROL_ENABLE();

     NAND_ENABLE_CE();

     NFCMD_REG = NAND_CMD_READID;

     NFADDR_REG = 0x0;

 

     /*   wait  for a  while  */

     for  (i=0;  i<200;  i++);

     id  =  NFDATA8_REG;

     id  =  NFDATA8_REG;

     if  (id  >  0x80)   large_block  =  1;

 

     return  nandll_read_blocks(0x2ff80000,  0x40000,  large_block);

}

#endif

 

五、 修改board/samsung/fsc100/Makefile

SOBJS     :=  lowlevel_init.o

改爲

SOBJS     :=  lowlevel_init.o  mem_setup.o

 

COBJS-y  :=  fsc100.o

改爲

COBJS-y :=  fsc100.o  nand_cp.o

 

六、 修改board/samsun/fsc100/config.mk

TEXT_BASE  =  0x34800000

改爲

TEXT_BASE  =  0x2FF80000

 

七、 修改cpu/arm_cortexa8/start.S

#ifndef  CONFIG_SKIP_LOWLEVEL_INIT

       bl   cpu_init_crit

#endif

以後添加以下代碼

/*  判斷uboot是否在內存中運行 */

ldr   r0,  =_TEXT_BASE

adr  r1,  _TEXT_BASE

cmp  r0,  r1

beq   stack_setup

 

ldr  sp,  =(0x22000000)

bl  copy_uboot_to_ram

b   stack_setup

 

八、 連接文件的修改

修改cpu/arm_cortexa8/u-boot.lds爲:

       ……

       .text   :

      {

          cpu/arm_cortexa8/start.o       (.text)

          board/samsung/fsc100/lowlevel_init.o

board/samsung/fsc100/mem_setup.o

          board/samsung/fsc100/nand_cp.o

          *(.text)

}

……

 

九、 複製s5pc100.h  s5pc1x0.h  hardware.h   include/asm-arm/arch-s5pc1xx/

 

十、 複製s5p_nand.cdrivers/mtd/nand/

 

十一、 修改drivers/mtd/nand/Makefile

COBJS-$(CONFIG_NAND_S3C64XX)  +=  s3c64xx.o

後面添加

COBJS-$(CONFIG_NAND_S5PC100)  += s5p_nand.o

 

十二、 修改include/linux/mtd/mtd-abi.h

struct  nand_ecclayout  {

……

struct  nand_oobfree  oobfree[MTD_MAX_OOBFREE_ENTRIES];

uint32_t  useecc;

uint32_t  reserved;

};

 

1三、 lib_arm/board.c中添加網卡初始化代碼

eth_initialize(gd->bd);

後面添加

eth_init(gd->bd);

 

1四、 修改網卡驅動drivers/net/dm9xxx.c

在函數dm9000_init中,

DM9000_iow(DM9000_IMR, IMR_PAR);

以後的內容都註釋掉,直到該函數結束(return  0以前)

 

1五、 修改include/net.h

static inline  int  is_multicast_ether_addr(const u8 *addr)

{

         return  (0x01  ==  addr[0]);

}

 

 

1六、 修改net/net.c

在 int  NetArpWaitTry; 後添加以下代碼

ulong  timer_clk;

 

void  ArpTimeoutCheck(void)

{

     ……

     把

     t  =   get_timer(0);

改爲

t  =  get_timer(0)  /  (timer_clk / CONFIG_SYS_HZ);

}

 

extern unsigned  long  (*get_pclk)(void);

int  NetLoop(proto_t  protocol)

{

        bd_t  *bd  =  gd->bd;

        添加以下代碼:

      timer_clk  =  get_pclk()  /  (16 * 2);

      ……

     

      註釋如下代碼

      eth_halt();

eth_set_current();

if  (eth_init(bd)  <  0)  {

       eth_halt();

       return  -1;

}

 

      把 

if  (timeHandler  && ( … > timeDelta) {

      改爲

      ulong  t;

      t  =  get_timer(0) / (timer_clk  /  CONFIG_SYS_HZ);

      if  (timeHandler  && (t  -  timeStart)  > timeDelta)  {

      ……

}

 

void  NetSetTimeout(ulong  iv,  thand_f  *f)

{

      把

      timeStart  =  get_timer(0);

     改爲

      timeStart  =  get_timer(0)  /  (timer_clk  /  CONFIG_SYS_HZ);

}

 

int  NetSendUDPPacket(uchar *ether,  IPaddr_t  dest,  int  dport,  int  sport,  int  len)

{

      ……

     把

      NetArpWaitTimerStart  =  get_timer(0);

     改爲

     NetArpWaitTimerStart  =  get_timer(0)  /  (timer_clk  /  CONFIG_SYS_HZ);

     ……

}

 

int  PingSend(void)

{

      ……

      把

NetArpWaitTimerStart  =  get_timer(0);

      改爲

     NetArpWaitTimerStart  =  get_timer(0)  /  (timer_clk  /  CONFIG_SYS_HZ);

     ……

}

 

註釋該文件中全部的eth_halt()

 

1七、 go命令的優化

修改該common/cmd_boot.c

int do_go (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])

{

ulong   addr, rc;

int    rcode = 0;

      if  (argc < 2) {

return  cmd_usage(cmdtp);

}

/**************** added by farsight 2011-12-18 *****************/

char *cmdline  =  getenv("bootargs");

struct param_struct *kernel_params=(struct param_struct *)0x20000100;

 

printf("setup linux parameters at 0x20000100\n");

memset(kernel_params, 0, sizeof(struct  param_struct));

kernel_params->u1.s.page_size=4096;

kernel_params->u1.s.nr_pages=0x10000000>>12;

memcpy(kernel_params->commandline, cmdline, strlen(cmdline)+1);

printf("linux command line is: \"%s\"\n",cmdline);

/***************************************************************/ 

 addr = simple_strtoul(argv[1], NULL, 16);

 printf ("## Starting application at 0x%08lX ...\n", addr);

 

/******************* added by farsight 2011-12-18 ******************/

__asm__(

"ldr  r1, =1826\n"

"mov        ip, #0\n"

"mcr        p15, 0, ip, c8, c7, 0\n"        

"mcr        p15, 0, ip, c7, c5, 0\n"        

"mcr        p15, 0, ip, c7, c5, 6\n"       

"mcr        p15, 0, ip, c7, c10, 4\n"        

"mcr        p15, 0, ip, c7, c5, 4\n"        

 

"mrc        p15, 0, ip, c1, c0, 0\n"   

"bic        ip, ip, #0x00002000\n"  

"bic        ip, ip, #0x00000007\n"

"orr        ip, ip, #0x00000002\n"

"orr        ip, ip, #0x00000800\n"

"bic        ip, ip, #0x00001000\n"

"mcr        p15, 0, ip, c1, c0, 0\n"   

 

"mov pc, %0\n"

"nop\n"

:

:"r"(addr)

);

/***************************************************************/

 

rc = do_go_exec ((void *)addr, argc - 1, argv + 1);

if (rc != 0) rcode = 1;

 

printf ("## Application terminated, rc = 0x%lX\n", rc);

return rcode;

}

 

3、從新編譯

$ make  distclean

$ make  fsc100_config

$ make

這樣咱們就獲得可以在fsc100平臺上使用的u-boot.bin

 

實驗四  內核的配置和編譯

【實驗目的】

       瞭解內核的編譯過程及配置選項的內容

【實驗環境】

  • 主機:ubuntu 10.10發行版
  • 目標機:FS_S5PC100平臺
  • 交叉編譯工具:arm-cortex_a8-linux-gnueabi-gcc

【實驗步驟】

  • 解壓內核

將linux-2.6.35.tar.bz2拷貝到/home/linux下並解壓

$tar  xvf  linux-2.6.35.tar.bz2

$ cd  linux-2.6.35

  • 修改內核頂層目錄下的Makefile

$ vim Makefile

修改:

ARCH             ?= $(SUBARCH)

CROSS_COMPILE ?=

CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)

爲:

ARCH            ?= arm

CROSS_COMPILE      ?= arm-cortex_a8-linux-gnueabi-

  • 拷貝標準板配置文件

$ cp  arch/arm/configs/s5pc100_defconfig   .config

  • 配置內核

$ make  menuconfig

該命令執行時會彈出一個菜單,咱們能夠對內核進行詳細的配置。這裏咱們先查看一下,內核都提供了那些功能!

  • 編譯內核

$ make  zImage

經過上述操做咱們可以在arch/arm/boot目錄下生成一個zImage文件,這就是通過壓縮的內核鏡像。

實驗五  網卡驅動的移植

【實驗目的】

       經過上面的實驗咱們可以得到一個內核,可是這個內核只是一個最基本的配置,不少的功能並無包含。

       網卡是嵌入式產品最經常使用的設備,這裏咱們須要完成網卡驅動的移植。FS_S5PC100使用的是DM9000網卡,咱們經過這個實驗可以瞭解如何在內核中添加網卡驅動及網絡功能的基本配置。

【實驗環境】

  • 主機:ubuntu 10.10發行版
  • 目標機:FS_S5PC100平臺
  • 交叉編譯工具:arm-cortex_a8-linux-gnueabi-gcc

【實驗步驟】

  • 平臺代碼修改

vim  arch/arm/mach-s5pc100/mach-smdkc100.c

 

  • 添加須要的頭文件(注:因爲linux的頭文件之間也有依賴關係,因此應該講將下面的頭文件加到原來頭問價的最後)

#if defined (CONFIG_DM9000)

#include <linux/dm9000.h>

#include <linux/irq.h>

#endif

 

  • 平臺設備的添加

/* DM9000 Support */

#if  defined(CONFIG_DM9000)

static struct resource dm9000_resources[] = {

[0] = {

.start        = 0x88000000,

.end        = 0x88000000 + 0x3,

.flags        = IORESOURCE_MEM,

},

[1] = {

.start        = 0x88000000 + 0x4,

.end        = 0x88000000 + 0x4 +0x3,

.flags        = IORESOURCE_MEM,

},

[2] = {

      .start = IRQ_EINT(10),

      .end   = IRQ_EINT(10),

.flags        = IORESOURCE_IRQ | IRQ_TYPE_LEVEL_HIGH,

},

};

 

static struct dm9000_plat_data s5pc100_dm9000_platdata = {

.flags        =   DM9000_PLATF_16BITONLY,

.dev_addr[0]  = 0x00,

.dev_addr[1]  = 0x00,

.dev_addr[2]  = 0x3e,

.dev_addr[3]  = 0x26,

.dev_addr[4]  = 0x0a,

.dev_addr[5]  = 0x00,

};

 

static struct platform_device s5pc100_device_dm9000 = {

.name        = "dm9000",

.id        = -1,

.num_resources        = ARRAY_SIZE(dm9000_resources),

.resource        = dm9000_resources,

.dev = {

.platform_data  = & s5pc100_dm9000_platdata,

}

};

#endif

 

  • 平臺設備列表的添加:

在smdkc100_devices[]結構體數組中添加以下內容:

   #if  defined(CONFIG_DM9000)

   &s5pc100_device_dm9000,

   #endif

 

  • 配置內核

$ make menuconfig

 

  • 網絡配置:

[*] Networking support (NEW)  --->

Networking options  --->

<*> Packet socket

<*> Unix domain sockets

[*] TCP/IP networking

[*]   IP: multicasting

[*]   IP: kernel level autoconfiguration

[*]     IP: BOOTP support

 

  • 網卡驅動配置

Device Drivers  ---> 

[*] Network device support  --->

[*]   Ethernet (10 or 100Mbit)  --->

<*>   DM9000 support

 

  • 網絡文件系統的配置

File systems  ---> 

[*] Network File Systems  --->

<*>   NFS client suppor

[*]     NFS client support for NFS version 3 

[*]       NFS client support for the NFSv3 ACL protocol extension

[*]     Root file system on NFS

 

  • 編譯內核,並拷貝到tftpboot目錄下

$ make  zImage

$ cp arch/arm/boot/zImage  /tftpboot

 

  • 啓動開發板,修改內核啓動參數,經過NFS方式掛載根文件系統

 

實驗六  LED驅動的移植

【實驗目的】

  1. 驅動程序的靜態編譯和動態編譯
  2. 應用程序如何打開/操做設備

【實驗環境】

  • 主機:ubuntu 10.10發行版
  • 目標機:FS_S5PC100平臺
  • 交叉編譯工具:arm-cortex_a8-linux-gnueabi-gcc

【實驗步驟】

  • 修改內核配置

$ make menuconfig

Kernel Features  --->

       [*] Use the ARM EABI to compile the kernel

       [*]   Allow old ABI binaries to run with this kernel (EXPERIMENTAL)

 

Ÿ   添加驅動文件

將實驗代碼LED_TEST/fsc100_led_drv.c拷貝到drivers/char下

 

Ÿ   修改drivers/char/Kconfig

在menu "Character devices"下面

添加以下內容:

config  FSC100_LED

     tristate "FSC100  LED  Device Support"

       depends on  ARCH_S5PC100

           help

     support  led  device  on  FS_S5PC100  develop  board

 

Ÿ   修改drivers/char/Makefile

在 obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o 下一行添加:

obj-$(CONFIG_FSC100_LED) += fsc100_led_drv.o

 

Ÿ   交叉編譯測試程序fsc100_led_test.c

arm-cortex_a8-linux-gnueabi-gcc  fsc100_led_test.c  –o  fsc100_led_test 

sudo  cp  fsc100_led_test   /source/rootfs

 

Ÿ   設置u-boot環境變量

# setenv  serverip 192.168.1.100

# setenv  ipaddr 192.168.1.200

# setenv  bootcmd  tftp  20008000  zImage\; go  20008000

# setenv  bootargs  root=nfs  nfsroot=192.168.1.100:/source/rootfs  console=ttySAC0,115200 init=/linuxrc  ip=192.168.1.200

# saveenv

 

一、 靜態編譯LED驅動

  • 配置內核時按「空格」選擇,配置完成後保存退出

$ make menuconfig

       Device Drivers  ---> 

              Character devices  ---> 

                     <*> FSC100  LED  Device Support

 

  • 保存退出,從新編譯後把zImage拷貝到tftpboot下

$ make  zImage

$ cp  arch/arm/boot/zImage  /tftpboot

 

從新啓動開發板,加載內核並運行。在終端下執行下面操做

  • 建立設備節點

# mknod  /dev/led  c  252  0

 

  • 運行測試程序並觀察現象

# ./fsc100_led_test

 

二、 動態編譯LED驅動

  • 配置內核時按「空格」選擇,配置完成後保存退出

$ make menuconfig

       Device Drivers  ---> 

              Character devices  ---> 

                     <M> FSC100  LED  Device  Support

 

  • 保存退出,從新編譯後把zImage拷貝到tftpboot下,把驅動模塊拷貝到/source/rootfs下

$ make  zImage  modules

$ cp  arch/arm/boot/zImage  /tftpboot

$ cp  drivers/char/fsc100_led_drv.ko  /source/rootfs

 

從新啓動開發板,linux運行起來後在終端下操做

  • 建立設備節點

# mknod  /dev/led  c  252  0          //c表示 字符設備,252是主設備號,0是次設備號

 

  • 加載LED驅動模塊

#insmod  fsc100_led_drv.ko

 

  • 運行測試程序並觀察現象

# ./fsc100_led_test

 

 

 

 

實驗七  Nand flash驅動的移植

【實驗目的】

       Nand flash 是嵌入式系統最經常使用的外部存儲設備,這裏介紹Nand flash驅動移植的過程。

       說明:在本系統移植課程實驗中命令行提示符 「$」表示是在主機上執行,「#」表示在目標板執行

【實驗環境】

  • 主機:ubuntu 10.10發行版
  • 目標機:FS_S5PC100平臺
  • 交叉編譯工具:arm-cortex_a8-linux-gnueabi-gcc

【實驗步驟】

Ÿ   添加針對咱們平臺的Nand flash驅動

拷貝s3c_nand.c到drivers/mtd/nand下

拷貝regs-nand.h到arch/arm/mach-s5pc100/include/mach下

Ÿ   針對平臺上的nand flash設備,修改drivers/mtd/nand/nand_base.c第2812行

for  (i = 0; i < 5; i++)

  • 添加內核配置選項

修改drivers/mtd/nand/Kconfig,在if  mtd_nand下面添加以下內容:

 

config  MTD_NAND_S3C

        tristate "NAND Flash support for S3C SoC"

        depends on (ARCH_S3C64XX || ARCH_S5P64XX || ARCH_S5PC1XX || ARCH_S5PC100) && MTD_NAND

        help

          This enables the NAND flash controller on the S3C. 

          No board specfic support is done by this driver, each board

          must advertise a platform_device for the driver to attach.

 

config  MTD_NAND_S3C_DEBUG

        bool "S3C NAND driver debug"

        depends on MTD_NAND_S3C

        help

          Enable debugging of the S3C NAND driver

 

config  MTD_NAND_S3C_HWECC

        bool "S3C NAND Hardware ECC"

        depends on MTD_NAND_S3C

        help

          Enable the use of the S3C's internal ECC generator when

          using NAND. Early versions of the chip have had problems with

          incorrect ECC generation, and if using these, the default of

          software ECC is preferable.

 

          If you lay down a device with the hardware ECC, then you will

          currently not be able to switch to software, as there is no

          implementation for ECC method used by the S3C

 

修改drivers/mtd/nand/Makefile添加以下內容:

obj-$(CONFIG_MTD_NAND_S3C)  +=  s3c_nand.o

 

  • 修改平臺代碼

修改arch/arm/mach-s5pc100/mach-smdkc100.c添加以下內容:

 

  • 添加頭文件

#if defined (CONFIG_MTD_NAND_S3C)

#include <linux/mtd/partitions.h>

#include <linux/mtd/mtd.h>

#include <plat/nand.h>

#endif

 

  • 添加平臺設備

#if defined(CONFIG_MTD_NAND_S3C)

/* Nand Flash Support */

static struct mtd_partition s5pc100_nand_part[] = {

        [0] = {

                .name        = "bootloader",

                .size        = SZ_1M,

                .offset        = 0,

        },

        [1] = {

                .name        = "kernel",

                .offset = MTDPART_OFS_APPEND,

                .size        = SZ_1M*3,

        },

        [2] = {

                .name        = "rootfs",

                .offset               = MTDPART_OFS_APPEND,

                .size        = SZ_4M,

        },

        [3] = {

                .name        = "usrfs",

                .offset        = MTDPART_OFS_APPEND,

                .size        = MTDPART_SIZ_FULL,

        },

};

 

struct s3c_nand_mtd_info s5pc100_nand_mtd_part_info = {

        .chip_nr = 1,

        .mtd_part_nr = ARRAY_SIZE(s5pc100_nand_part),

        .partition = s5pc100_nand_part,

};

 

static struct resource s5pc100_nand_resource[] = {

        [0] = {

                .start = 0xE7200000,

                .end   = 0xE7200000 + SZ_1M,

                .flags = IORESOURCE_MEM,

        }

};

 

struct platform_device s5pc100_device_nand = {

        .name                  = "s5pc100-nand",

        .id                  = -1,

        .num_resources          = ARRAY_SIZE(s5pc100_nand_resource),

        .resource          = s5pc100_nand_resource,

        .dev = {

                .platform_data = &s5pc100_nand_mtd_part_info,

        }

};

#endif

 

  • 添加平臺設備列表

在smdkc100_device[]結構體數組中添加以下內容:

#if defined(CONFIG_MTD_NAND_S3C)

        &s5pc100_device_nand,

#endif

 

  • 修改arch/arm/plat-samsung/include/plat/nand.h添加以下內容:

struct s3c_nand_mtd_info {

        uint chip_nr;

        uint mtd_part_nr;

        struct mtd_partition *partition;

};

 

  • 配置內核

$ make menuconfig

Device Drivers  --->

        <*> Memory Technology Device (MTD) support  --->

               [*]   MTD partitioning support

<*>   Caching block device access to MTD devices

               <*>   NAND Device Support  --->

                      <*>   NAND Flash support for S3C SoC

                      [*]     S3C NAND Hardware ECC

 

File Systems  --->

         Partition  Types  --->

                [*]    Advanced partition selection

                [*]    PC  BIOS  (MSDOS  partition  tables)  support

                [*]         BSD  disklabel  (FreeBSD  partition  tables)  support

 

  • 編譯內核並拷貝到tftpboot下

$ make  zImage

$ cp  arch/arm/boot/zImage  /tftpboot

 

  • 測試

啓動目標板,在目標板上完成以下操做:

# cat  /proc/partitions

dev:        size       erasesize     name

mtd0: 00100000 00020000  "bootloader"

mtd1: 00300000 00020000  "kernel"

mtd2: 00400000 00020000  "rootfs"

mtd3: 0f800000 00020000  "usrfs"

 

 

 

實驗八    LCD驅動移植

【實驗目的】

       瞭解交叉工具鏈的編譯過程及其使用。

       說明:在本系統移植課程實驗中命令行提示符 「$」表示是在主機上執行,「#」表示在目標板執行

【實驗環境】

  • 主機:ubuntu 10.10發行版
  • 目標機:FS_S5PC100平臺
  • 交叉編譯工具:arm-cortex_a8-linux-gnueabi-gcc

【實驗步驟】

  • 修改arch/arm/mach-s5pc100/mach-smdkc100.c

修改smdkc100_fb_win0結構體內容爲:

static struct s3c_fb_pd_win smdkc100_fb_win0 = {

/* this is to ensure we use win0 */

.win_mode        = {

.pixclock = 1000000000000ULL / ((8+43+1+480)*(4+10+12+272)*80),

.left_margin        = 8,

.right_margin        = 43,

.upper_margin        = 4,

.lower_margin        = 12,

.hsync_len        = 1,

.vsync_len        = 10,

.xres                = 480,

.yres                = 272,

},

.max_bpp        = 32,

.default_bpp        = 16,

};

      

  • 修改drivers/video/Kconfig

修改:

depends on (FB && ARCH_S3C64XX)

爲:

depends on (FB && ARCH_S3C64XX) || (FB && ARCH_S5PC100)

      

  • 配置內核

$ make menuconfig

Device Drivers  --->

Graphics support  --->

              <*> Support for frame buffer devices  --->

<*>   Samsung S3C framebuffer support

Console display driver support  --->

                    <*> Framebuffer Console support

[*] Bootup logo  --->

 

  • 編譯內核並拷貝到tftpboot下

$ make  zImage

$ cp  arch/arm/boot/zImage  /tftpboot

 

  • 測試

插上屏,啓動開發板,可以看到屏幕上顯示一個小企鵝就是移植成功了!

 

 

 

 

實驗九    USB驅動的移植

【實驗目的】

       USB接口是如今計算機系統中最通用的一種接口,

       說明:在本系統移植課程實驗中命令行提示符 「$」表示是在主機上執行,「#」表示在目標板執行

【實驗環境】

  • 主機:ubuntu 10.10發行版
  • 目標機:FS_S5PC100平臺
  • 交叉編譯工具:arm-cortex_a8-linux-gnueabi-gcc

【實驗步驟】

  • 添加針對咱們板子的USB驅動及相關頭文件

拷貝ohci-s3c2410.c drivers/usb/host/

 

拷貝regs-clock.h arch/arm/mach-s5pc100/include/mach/

 

  • 修改drivers/usb/Kconfig

在:

default  y  if  ARCH_S3C2410

後添加:

default  y  if  ARCH_S5PC100

 

  • 修改drivers/usb/host/ohci-hcd.c

修改:

#if defined(CONFIG_ARCH_S3C2410) || defined(CONFIG_ARCH_S3C64XX)

爲:

#if defined(CONFIG_ARCH_S3C2410) || defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_ARCH_S5PC100)

 

  • 修改arch/arm/mach-s5pc100/include/mach/map.h

添加以下內容:

#define S3C_PA_USBHOST          (0xED400000)

 

  • 修改arch/arm/plat-samsung/dev-usb.c

修改

[1] = {

.start = IRQ_USBH,

.end   = IRQ_USBH,

.flags = IORESOURCE_IRQ,

}

爲:

[1] = {

.start = IRQ_UHOST,

.end   = IRQ_UHOST,

.flags = IORESOURCE_IRQ,

}

 

  • 添加平臺設備

修改arch/arm/mach-s5pc100/Kconfig

select  S3C_PL330_DMA

後添加

select  S3C_DEV_USB_HOST

 

修改arch/arm/mach-s5pc100/mach-smdkc100.c

 

添加頭文件

#if defined (CONFIG_USB_SUPPORT)

#include <plat/pll.h>

#include <linux/usb/ch9.h>

#include <mach/regs-clock.h>

#endif

 

添加平臺設備

 

#if defined(CONFIG_USB_SUPPORT)

void usb_host_clk_en(void) {

        /* Setting the epll clk to 48 MHz, P=3, M=96, S=3 */

        writel((readl(S5P_EPLL_CON) & ~(S5P_EPLL_MASK)) | (S5P_EPLL_EN \

                                | S5P_EPLLVAL(96,3,3)), S5P_EPLL_CON);

        writel((readl(S5P_CLK_SRC0) | S5P_CLKSRC0_EPLL_MASK), S5P_CLK_SRC0);

        writel((readl(S5P_CLK_SRC1)& ~S5P_CLKSRC1_UHOST_MASK), S5P_CLK_SRC1);

 

        /* USB host clock divider ratio is 1 */

        writel((readl(S5P_CLK_DIV2)& ~S5P_CLKDIV2_UHOST_MASK), S5P_CLK_DIV2);

        writel(readl(S5P_CLKGATE_D10)|S5P_CLKGATE_D10_USBHOST, S5P_CLKGATE_D10);

        writel(readl(S5P_SCLKGATE0)|S5P_CLKGATE_SCLK0_USBHOST, S5P_SCLKGATE0);

}

EXPORT_SYMBOL(usb_host_clk_en);

#endif

 

添加平臺設備列表

在smdkc100_device[]結構體數組中添加以下內容:

#if defined(CONFIG_USB_SUPPORT)

        & s3c_device_ohci,

#endif

 

  • 配置內核

$ make menuconfig

USB控制器支持

Device Drivers  --->

       [*] USB support  --->

              <*>   Support for Host-side USB

              <*>     OHCI HCD support

 

U盤支持

Device Drivers  --->

       SCSI device support  --->

              <*> SCSI device support

              <*> SCSI disk support

              <*> SCSI generic support

              <*> SCSI media changer support

 

Device Drivers  --->

       [*] USB support  --->

<*>   USB Mass Storage support

 

文件系統及語言配置:

File systems  --->

DOS/FAT/NT Filesystems  --->

<*> VFAT (Windows-95) fs support 

-*- Native language support  --->

<*>   Codepage 437 (United States, Canada)

<*>   Simplified Chinese charset (CP936, GB2312)

<*>   NLS ISO 8859-1  (Latin 1; Western European Languages)

<*>   ASCII (United States)

<*>   NLS UTF-8

            

  • 編譯內核並拷貝到tftpboot下

$ make  zImage

$ cp  arch/arm/boot/zImage  /tftpboot

 

  • 測試

啓動目標板並在目標板上完成以下操做:

# mount  -t  vfat  /dev/sda1 /mnt

# ls

能夠查看到U盤內容,即完成實驗。

 

 

 

實驗十    SD卡驅動移植

【實驗目的】

       SD卡是嵌入式系統最經常使用的外部擴展存儲設備,這裏介紹SD驅動移植的過程。

       說明:在系統移植課程實驗中命令行提示符 「$」表示是在主機上執行,「#」表示在目標板執行

【實驗環境】

  • 主機:ubuntu 10.10發行版
  • 目標機:FS_S5PC100平臺
  • 交叉編譯工具:arm-cortex_a8-linux-gnueabi-gcc

【實驗步驟】

  • 修改配置文件

修改drivers/mmc/host/Kconfig

 

修改:

depends on MMC_SDHCI && (PLAT_S3C24XX || PLAT_S3C64XX)

爲:

depends on MMC_SDHCI && (PLAT_S3C24XX || PLAT_S3C64XX || ARCH_S5PC100)

 

修改driver/mmc/host/sdhci.c

 

修改:

mmc->f_min = host->max_clk / 256;

mmc->f_min = host->max_clk / 512;

 

  • 配置內核

$ make  menuconfig

 

SD卡驅動配置:

Device Drivers  --->

       <*> MMC/SD/SDIO card support  --->

              <*>   SDHCI support on Samsung S3C SoC

                     [*]   DMA support on S3C SDHCI

 

 

  • 編譯內核並拷貝到tftpboot下

$ make  zImage

$ cp  arch/arm/boot/zImage  /tftpboot

 

  • 測試

啓動目標板並在目標板上完成以下操做:

# mount  -t  vfat  /dev/mmcblk0p1  /mnt

# ls

能夠查看到SD卡內容,即完成實驗。 

 

 

 

 

 

 

 

 

 

實驗十一  yaffs2文件系統的移植

【實驗目的】

       yaffs2文件系統是嵌入式系統中經常使用到的一種文件系統,而且在主要用在nand flash上,這裏咱們在內核裏添加yaffs2的支持

【實驗環境】

一、  ubuntu 10.10發行版

二、  FS_S5PC100平臺

三、  交叉編譯器 arm-cortex_a8-linux-gnueabi-gcc

【實驗步驟】

一、  源碼下載

       $ wget http://www.aleph1.co.uk/cgi-bin/viewcvs.cgi/yaffs2.tar.gz

二、  解壓到內核源碼linux-2.6.35同級目錄下

       $ tar  xvf  yaffs2.tar.gz

三、  往內核打yaffs2補丁

$ cd  yaffs2

$ ./patch-ker.sh  c  ../linux-2.6.35

四、  配置內核

$ cd  ../linux-2.6.35

       $ make  menuconfig

File systems  --->

           [*] Miscellaneous filesystems  --->

                     <*>   YAFFS2 file system support

                    -*-     512 byte / page devices

                     -*-     2048 byte (or larger) / page devices

                     [*]       Autoselect yaffs2 format

                     [*]      Cache  short  names  in  RAM

五、  從新編譯內核

       $ make  zImage

六、  拷貝內核到開發板上

       $ cp  arch/arm/boot/zImage  /tftpboot

七、  從新啓動開發板

# cat  /proc/filesystems

 nodev    sysfs

 nodev    rootfs

 nodev    bdev

 nodev    proc

 nodev    tmpfs

 nodev    sockfs

 nodev    usbfs

 nodev    pipefs

 nodev    anon_inodefs

 nodev    rpc_pipefs

 nodev    devpts

             ext3

              ext2

              cramfs

 nodev    ramfs

             vfat

              msdos

              iso9660

nodev      nfs

nodev      jffs2

              romfs

              yaffs

              yaffs2

nodev      mtd_inodefs

 

 

 

 

實驗十二  內存調試

【實驗目的】

段錯誤和內存錯誤是C語言編程常常遇到的問題,使用memwatch是由johan lindh編寫,是一個開發源代碼C語言內存錯誤檢測工具。能檢測雙重釋放,錯誤釋放,沒有釋放內存,溢出等等狀況。

【實驗環境】

一、  ubuntu 10.10發行版

二、  FS_S5PC100平臺

三、  交叉編譯器 arm-cortex_a8-linux-gnueabi-gcc

【實驗步驟】

一、  解壓memwatch.-2.7.1.tar.gz,在解開的目錄下添加代碼memtest.c

#include <stdlib.h>

#include <stdio.h>

#include "memwatch.h"

int main(int argc,char **argv)

{

        char *ptr1;

        char *ptr2;

        ptr1 = malloc(512);

        ptr2 = malloc(512);

        ptr1[512]="A";

        ptr2 = ptr1;

        free(ptr2);

        free(ptr1);

        return 0;

}

二、  修改  Makefile

Makefile文件爲:

CC=arm-cortex_a8-linux-gnueabi-gcc

memtest:

        $(CC) -DMEMWATCH -DMW_STDIO  memtest.c  memwatch.c

五、運行make並將編譯生成的可執行程序a.out拷貝到開發板的根目錄下執行,會生成一個記錄文件memwatch.log,內容以下:

============= MEMWATCH 2.71 Copyright (C) 1992-1999 Johan Lindh =========

 

Started at Thu Jan  1 00:08:33 1970

 

Modes: __STDC__ 32-bit mwDWORD==(unsigned long)

mwROUNDALLOC==4 sizeof(mwData)==32 mwDataSize==32

 

  • overflow: <3> memtest.c(12), 512 bytes alloc'd at <1> memtest.c(8)

double-free: <4> memtest.c(13), 0x1a1b4 was freed from memtest.c(12)

 

Stopped at Thu Jan  1 00:08:33 1970

 

unfreed: <2> test.c(9), 512 bytes at 0x1a3e4      {FE FE FE FE FE FE FE FE FE FE FE FE FE FE FE FE ................}

 

Memory usage statistics (global):

 N)umber of allocations made: 2

 L)argest memory usage      : 1024

 T)otal of all alloc() calls: 1024

 U)nfreed bytes totals      : 512

//overflow: <3> memtest.c(12)緩衝區溢出,當程序執行到第15行free(ptr2)才檢測到的;

512 bytes alloc'd at <1> memtest.c(9)

//表示出錯緩衝區的大小爲512字節,是在memtest.c的第9行分配的。很容易發現代碼的ptr1[512]="A"出現錯誤。

double-free: <4> memtest.c(13), 0x1a7f4 was freed from memtest.c(12)

//double-free: <4> memtest.c(16)是一個雙重釋放的錯誤,表示程序執行到16行的時候才檢測到。

0x1a7f4 was freed from memtest.c(12)

//表示首地址爲 0x1a7f4的內存在15行已經被釋放。

Stopped at Wed Dec 31 19:00:38 1969

unfreed: <2> memtest.c(10), 512 bytes at 0x1aa24        {FE FE FE FE FE FE FE FE

//表示一塊內存沒有釋放,表示這塊內存是在memtest.c的第10行分配,大小爲512字節,首地址爲0x1aa24。

Memory usage statistics (global):

 N)umber of allocations made: 2

 L)argest memory usage      : 1024

 //程序結束時可以是使用的最大動態內存

 T)otal of all alloc() calls: 1024 //總共分配的動態內存

 U)nfreed bytes totals      : 512

 //表示未釋放的內存

 

實驗十三  內核調試

【實驗目的】

因爲在驅動開發中常常看到內核崩潰的問題,最多見的就是OOPS錯誤,本實驗要求學員掌握這種調試方法。

【實驗環境】

一、  ubuntu 10.10發行版

二、  FS_S5PC100平臺

三、  交叉編譯器 arm-cortex_a8-linux-gnueabi-gcc

【實驗步驟】

一、經過OOPS信息中PC寄存器的值能夠知道出錯指令的地址,經過棧回朔信息能夠知道出錯時的函數調用的關係,根據這兩點能夠很快定位錯誤。

二、 修改drivers/video/s3c-fb.c,在s3c_fb_probe函數中int  ret=0;下增長下面語句:

int *ptr  =  NULL;

*ptr  = 0xff;

三、編譯內核下載到開發板上,內核啓動會出現如相似下信息:

Unable to handle kernel NULL pointer dereference at virtual address 00000000

pgd = c0004000

[00000000] *pgd=00000000

Internal error: Oops: 805 [#1]

 

Modules linked in:

CPU: 0    Not tainted  (2.6.35 #6)

PC is at s3c_fb_probe+0xc/0x67c

LR is at platform_drv_probe+0x1c/0x24

pc : [<c0290a28>]    lr : [<c01a44e4>]    psr: a0000013

sp : cfc29f0c     ip : cfc457c0    fp : 00000000

r10: 00000000  r9 : 00000000   r8 : c03ad4f8

r7 : c03a93d0   r6 : c03a93d0   r5 : c0395258   r4 : 00000000

r3 : 000000ff    r2 : cfc28000    r1 : 00000000   r0 : c0395250

 

 

四、Unable to handle kernel NULL pointer dereference at virtual address 00000000

能夠看出使用了空指針。找出函數調用關係:PC is at s3c_fb_probe+0xc/0x67c

,表示出錯指令爲 s3c_fb_probe函數中偏移爲0xc的指令。pc : [<c0290a28>] 表示出錯指令的地址爲c0290a28.

 

五、結合內核源代碼和反彙編代碼定位問題。

arm-cortex_a8-linux-gnueabi-objdump -D vmlinux > vmlinux.dis   //  文件vmlinux.dis很是大

出錯地址c001abc4附近的部分彙編代碼以下:

c0290a1c  <s3c_fb_probe>:

c0290a1c:   e92d4ff0       push  {r4, r5, r6, r7, r8, r9, sl, fp, lr}

c0290a20:   e3a030ff       mov  r3, #255

c0290a24:   e3a04000     mov  r4, #0

c0290a28:   e5843000     str  r3, [r4]

c0290a2c:   e590106c     ldr  r1,  [r0, #108]

……

對應C代碼以下:

  struct  device  *dev = &pdev->dev;

  struct  s3c_fb_platdata  *pd;

  struct  s3c_fb  *sfb;

  struct  resource  *res;

  int  win;

  int  ret = 0;

  int *ptr = NULL;

  *ptr = 0xff;

六、對於大多數狀況,從反彙編代碼定位到C代碼並不會如此容易,須要有較強的閱讀彙編代碼的能力。

七、另一種方法是經過addr2line去定位

arm-cortex_a8-linux-gnueabi-addr2line  0xc0290a28  -e  vmlinux  -f

 

重要  該實驗完成後不要忘記恢復被修改的代碼

實驗十四  文件系統的移植

【實驗目的】

       熟悉Linux文件系統目錄結構,建立本身的文件系統,經過NFS方式測試;用文件系統工具生成ramdisk文件系統映象文件。

【實驗環境】

一、  ubuntu 10.10發行版

二、  FS_S5PC100平臺

三、  交叉編譯器 arm-cortex_a8-linux-gnueabi-gcc

【實驗步驟】

       1、根文件系統製做

一、  源碼下載

咱們選擇的版本是busybox-1.17.3.tar.bz2下載路徑爲:

http://busybox.net/downloads/

二、  解壓源碼

$ tar  xvf  busybox-1.17.3.tar.bz2

三、  進入源碼目錄

$ cd  busybox-1.17.3

四、  配置源碼

$ make menuconfig

Busybox Settings --->

       Build Options --->

              [*] Build BusyBox as a static binary (no shared libs)

              [ ] Force NOMMU build

              [ ] Build with Large File Support (for accessing files > 2 GB)

              (arm-cortex_a8-linux-gnueabi-) Cross Compiler prefix

              () Additional CFLAGS

五、  編譯

$ make

六、  安裝

busybox默認安裝路徑爲源碼目錄下的_install

$ make  install

七、  進入安裝目錄下

$ cd  _install

$ ls

bin  linuxrc  sbin  usr

八、  建立其餘須要的目錄

$ mkdir  dev  etc  mnt  proc  var  tmp  sys  root

九、  添加庫

  • 將工具鏈中的庫拷貝到_install目錄下

$ cp  /home/linux/toolchain/arm-cortex_a8-linux-gnueabi/lib   ./  -a

  • 刪除靜態庫和共享庫文件中的符號表

$ rm  lib/*.a

$ arm-cortex_a8-linux-gnueabi-strip  lib/*

  • 刪除不須要的庫,確保全部庫大小不超過4M

$ rm  lib/libstdc++*

$ du  -mh   lib/

十、 添加系統啓動文件

在etc下添加文件inittab,文件內容以下:

#this is run first except when booting in single-user mode.

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

# /bin/sh invocations on selected ttys

# start an "askfirst" shell on the console (whatever that may be)

::askfirst:-/bin/sh

# stuff to do when restarting the init process

::restart:/sbin/init

# stuff to do before rebooting

::ctrlaltdel:/sbin/reboot

 

在etc下添加文件fstab,文件內容以下:

#device     mount-point     type        options         dump     fsck order

proc         /proc             proc           defaults     0                0

tmpfs         /tmp                   tmpfs         defaults         0                 0

sysfs           /sys                    sysfs           defaults           0                 0

tmpfs     /dev                   tmpfs         defaults         0                 0

       這裏咱們掛載的文件系統有三個proc、sysfs和tmpfs。在內核中proc和sysfs默認都支持,而tmpfs是沒有支持的,咱們須要添加tmpfs的支持

修改內核配置:

File systems --->

       Pseudo filesystems --->

              [*] Virtual memory file system support (former shm fs)

              [*] Tmpfs POSIX Access Control Lists

從新編譯內核

      

       在etc下建立init.d目錄,並在init.d下建立rcS文件,rcS文件內容爲:

#!/bin/sh

# This is the first script called by init process

/bin/mount  -a

echo  /sbin/mdev  >  /proc/sys/kernel/hotplug

/sbin/mdev  -s

       爲rcS添加可執行權限:

       $ chmod   +x  init.d/rcS

 

       在etc下添加profile文件,文件內容爲:

#!/bin/sh

export HOSTNAME=farsight

export USER=root

export HOME=root

export PS1="[$USER@$HOSTNAME \W]\# "

PATH=/bin:/sbin:/usr/bin:/usr/sbin

LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH

export PATH  LD_LIBRARY_PATH

十一、 設備文件建立

根文件系統中有一個設備節點是必須的,在dev下建立console節點

$ sudo  mknod   dev/console  c  5  1

重要:新制做的文件系統尺寸若超出8M,刪除不須要的庫文件

       2、NFS測試

    一、刪除原先的/source/rootfs

    $ sudo  rm  -rf  /source/rootfs   

    二、將咱們新建的根文件系統拷貝到/source/rootfs目錄下

    $sudo  mkdir  /source/rootfs

    $ sudo  cp  _install/*   /source/rootfs   –a

    三、設置uboot環境變量

# setenv  bootcmd  tftp  20008000  zImage\; go  20008000

# setenv  bootargs  root=nfs  nfsroot=192.168.1.100:/source/rootfs  init=/linuxrc console=ttySAC0,115200  ip=192.168.1.200

# saveenv

從新啓動開發板,查看是否可以正常掛載,功能是否正常

 

將NANDFLASH的用戶文件系統分區以yaffs2的方式掛載到/mnt目錄下:

在/etc/init.d/rcS添加:

mount  -t yaffs2 /dev/mtdblock3 /mnt

這樣,就能夠以yaffs2文件系統的方式管理nandflash的第四個分區(0~3)了。固然這裏的yaffs2也能夠換成cramfs、jffs2。但前提是linux內核支持該文件系統。

 

3、製做ramdisk文件系統

經過NFS測試之後,就能夠製做ramdisk文件系統了,具體以下:

       一、製做一個大小爲8M的鏡像文件

        $ cd  ~

       $ dd  if=/dev/zero  of=initrd.img  bs=1k  count=8192 (initrd.img爲8M)

       二、格式化這個鏡像文件爲ext2

       $ mkfs.ext2  -F  initrd.img

       三、在mount下面建立initrd目錄做爲掛載點

       $ sudo  mkdir  /mnt/initrd

       四、將這個磁盤鏡像文件掛載到/mnt/initrd下

       注意這裏的initrd.img不要和ubuntu根目錄下的initrd.img弄混了,同時initrd.img不能存放在rootfs目錄中

       $ sudo  mount  -t  ext2   -o  loop  initrd.img  /mnt/initrd

       五、將咱們的文件系統複製到initrd.img中

將測試好的文件系統裏的內容所有拷貝到 /mnt/initrd目錄下面

       $ sudo  cp  /source/rootfs/*   /mnt/initrd  –a

六、卸載initrd

$ sudo  umount  /mnt/initrd

七、壓縮initrd.img爲initrd.img.gz並拷貝到/tftpboot下

$ gzip  --best  -c  initrd.img  >  initrd.img.gz

$ cp  initrd.img.gz  /tftpboot

八、配置內核支持RAMDISK

製做完 initrd.img.gz後,須要配置內核支持RAMDISK做爲啓動文件系統

Device Drivers

       SCSI device support  --->

              <*> SCSI disk support

       Block devices  --->

              <*>RAM  block  device  support  

(1)Default number of RAM disks 

(8192) Default RAM disk size (kbytes)   (修改成8M)

General setup  --->

       [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support

從新編譯內核,複製到/tftpboot

       九、在U-BOOT命令行從新設置啓動參數:

# setenv  bootcmd  tftp  20008000  zImage \; tftp  20800000  initrd.img.gz \; go  20008000

# setenv  bootargs  root=/dev/ram  rw  init=/linuxrc  initrd=0x20800000,8M console=ttySAC0,115200

# saveenv

從新啓動開發板查看可否正常啓動

 

       4、製做cramfs文件系統

一、cramfs文件系統鏡像製做

因爲系統提供製做cramfs文件系統的工具,能夠直接使用。具體操做以下;

$ mkfs.cramfs  /source/rootfs  rootfs.cramfs

二、將rootfs.cramfs拷貝到/tftpboot目錄下

$ sudo  cp  rootfs.cramfs  /tftpboot

三、將rootfs.cramfs燒寫到nand flash的第三個分區上

u-boot下執行以下命令

# tftp  20008000  rootfs.cramfs

# nand  erase  400000  400000

# nand  write  20008000  400000  400000

四、從新設置u-boot啓動參數

# setenv  bootcmd  tftp  20008000  zImage\; go  20008000

# setenv  bootargs  root=/dev/mtdblock2   init=/linuxrc  console=ttySAC0,115200

# saveenv

啓動開發板,測試是否成功。

[root@farsight /root] # ls /

bin       etc      linuxrc     sbin     tmp      var

dev      lib      mnt      proc     test     usr

[root@farsight /root] # mkdir test

mkdir: Cannot create directory `test': Read-only file system

注意:cramfs格式的文件系統是隻讀

 

       5、製做jffs2文件系統

       一、配置內核支持jffs2文件系統

File systems  --->

           [*] Miscellaneous filesystems  --->

            <*>   Journalling  Flash  File  System  v2  (JFFS2)  support

從新編譯內核並拷貝到/tftpboot下

二、zlib的編譯

       解壓zlib-1.2.3.tar.bz2並進入zlib-1.2.3配置編譯安裝

       $ tar  xvf  zlib-1.2.3.tar.bz2

       $ cd  zlib-1.2.3

       $ ./configure

       $ make

       $ sudo  make install

       三、mtd工具編譯

       解壓mtd-snapshot-20050519.tar.bz2 並進入mtd/util編譯安裝

       $ tar  xvf  mtd-snapshot-20050519.tar.bz2

       $ cd  mtd/util

       $ make

       $ sudo  make  install

       這樣咱們的系統裏就有了mkfs.jffs2這個工具了

       四、jffs2文件系統鏡像製做

       $ mkfs.jffs2   -r  /source/rootfs  -o  rootfs.jffs2  -e  0x20000  --pad=0x400000  -n

       $ sudo  cp  rootfs.jffs2  /tftpboot

       五、jffs2文件系統燒寫

# tftp  20008000  rootfs.jffs2

# nand  erase  400000  400000

# nand  write  20008000  400000  400000

       六、設置u-boot啓動參數

# setenv  bootcmd  tftp  20008000  zImage\; go  20008000

# setenv  bootargs  root=/dev/mtdblock2   rootfstype=jffs2  rw  init=/linuxrc

   console=ttySAC0,115200 

# saveenv

       從新啓動開發板,查看是否成功

相關文章
相關標籤/搜索