天天看點

kernel驅動移植過程

  1. 擴充CS8900驅動移植方法1(在配置好的本地CS8900驅動基礎上修改, 見"挂載最小系統過程.txt": line161~line275)

    /linux-2.6.22.6/drivers/net/cs89x0.c:

    注釋line201:

    // #define RM9200_PA_CS8900 0x80000000 //local cs8900

    // static unsigned int cs8900_irq_map[] = {57, 0, 0, 0}; //irq: 57

    添加:

    define RM9200_PA_CS8900 0x40000000 //extend cs8900

    static unsigned int cs8900_irq_map[] = {93, 0, 0, 0}; //extend cs8900:pin124 PB29 IRQ0/93

    修改menuconfig, 關閉nand flash功能(因為nandflash 和 cs8900公用一個base )

    Device Drivers —>

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

    < > NAND Device Support —>

    Device Drivers  --->
     	Network device support  --->
     		Ethernet (10 or 100Mbit)  --->
     			<*> CS89x0 support
               

    配置u-boot支援擴充cs8900: (需要關閉本地網卡, 配置成擴充網卡, 否則能挂載uImage, 但是不能挂載系統)

    /u-boot-1.3.4/include/configs/at91rm9200dk.h:

    注釋line264: // #define CS8900_BASE 0x80000300

    注釋line173: // #define CONFIG_CMD_NAND

    /u-boot-1.3.4/drivers/net/cs8900.c: 
     	注釋: 
     		/*Net1(local) init  (another config CS8900_BASE: 0x80000300)
     		//Reset Net1  **is very important
     		AT91C_BASE_PIOB->PIO_OER = 1<<27;
     		AT91C_BASE_PIOB->PIO_CODR = 1<<27;		//low
    
     		//Configure PC13 controllers to periph A mode
     		AT91C_BASE_PIOC->PIO_ASR = 1<<13;
     		AT91C_BASE_PIOC->PIO_BSR = 0x00000000;
     		AT91C_BASE_PIOC->PIO_PDR = 1<<13;
    
     		//Configure CS7
     		AT91C_BASE_SMC2->SMC2_CSR[7] = 0x1100318A;
     		*/
     	打開: 
     		//Net2(extend) init	 (another config CS8900_BASE: 0x40000300)
     		//Reset Net2  **is very important
     		AT91C_BASE_PIOC->PIO_OER = 1<<14;	
     		AT91C_BASE_PIOC->PIO_CODR = 1<<14;		//low
    
     		//Configure CS3
     		AT91C_BASE_SMC2->SMC2_CSR[3] = 0x1100318A;
     		//
               

    儲存後重新編譯:

    $ make

    $ cp arch/arm/boot/uImage /work/nfs_root/

    修改環境變量:

    U-Boot> setenv bootcmd nfs 20007FC0 10.124.0.45:/work/nfs_root/uImage ;bootm 20007FC0

    U-Boot> setenv bootargs noinitrd root=/dev/nfs nfsroot=10.124.0.45:/work/nfs_root/new_fs_mini ip=10.124.0.33:10.124.0.45:10.124.0.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC0,115200

    U-Boot> saveenv

    測試, 上電觀察序列槽列印輸出:

    cs89x0:cs89x0_probe(0x0)

    cs89x0.c: v2.4.3-pre1 Russell Nelson [email protected], Andrew Morton [email protected]

    eth0: cs8900 rev K found at 0xc2a00300

    cs89x0: Extended EEPROM checksum bad and no Cirrus EEPROM, relying on command line

    cs89x0 media IRQ 93, programmed I/O, MAC 00:00:3e:26:0a:00

    cs89x0_probe1() successful

    init started: BusyBox v1.7.0 (2020-07-27 18:45:41 CST)

    starting pid 687, tty ‘’: ‘/etc/init.d/rcS’

    usb 1-2: device not accepting address 5, error -62

    Please press Enter to activate this console.
     starting pid 693, tty '/dev/ttyS0': '/bin/sh'
     #
               
  2. 擴充CS8900驅動移植方法2

    /linux-2.6.22.6/drivers/net/arm/:

    添加cs8900.c cs8900.h

    /linux-2.6.22.6/drivers/net/arm/Kconfig:

    添加:

    config ARM_CS8900

    tristate “ARM_CS8900 support”

    depends on NET_ETHERNET && ARM && ARCH_AT91RM9200

    help

    if you have ARM_CS8900 card of this type then you should

    always answer Y to this.

    /linux-2.6.22.6/drivers/net/arm/Makefile:

    添加: obj-$(CONFIG_ARM_CS8900) += cs8900.o

    /linux-2.6.22.6/arch/arm/mach-at91/at91rm9200.c:

    添加:

    static struct map_desc at91rm9200_cs8900_desc[] __initdata = {

    {

    .virtual = 0xc2a00000,

    .pfn = __phys_to_pfn(0x40000000),

    .length = SZ_1M,

    .type = MT_DEVICE,

    },

    };

    配置menuconfig:

    Device Drivers —>

    Network device support —>

    Ethernet (10 or 100Mbit) —>

    <*> ARM_CS8900 support

    配置u-boot支援擴充cs8900:(同上)

    儲存後重新編譯:

    $ make

    $ cp arch/arm/boot/uImage /work/nfs_root/

    修改環境變量:

    U-Boot> setenv bootcmd nfs 20007FC0 10.124.0.45:/work/nfs_root/uImage ;bootm 20007FC0

    U-Boot> setenv bootargs noinitrd root=/dev/nfs nfsroot=10.124.0.45:/work/nfs_root/new_fs_mini ip=10.124.0.33:10.124.0.45:10.124.0.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC0,115200

    U-Boot> saveenv

    測試, 上電觀察序列槽列印輸出:

    allocate cs8900 device ok.

    Cirrus Logic CS8900A driver for Linux (Modified for AT91RM9200)

    debug:[cs8900_probe-504]

    debug:[cs8900_probe-513]

    debug:[cs8900_probe-519]

    eth0: CS8900A rev E at 0xc2a00300 irq=25, addr: 00: 0:3E:26:0A: 0

    starting pid 687, tty ‘’: ‘/etc/init.d/rcS’

    Please press Enter to activate this console.

    starting pid 693, tty ‘/dev/ttyS0’: ‘/bin/sh’

    #

  3. 擴充dm9000驅動移植方法1

    /linux-2.6.22.6arch/arm/mach-at91/board-dk.c

    添加line47:

    #if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)

    #include <linux/dm9000.h>

    #endif

    #define rm9200_CS3 		0x40000000
     	#define dm9000_irq 		25
    
     	/* --------------------------------------------------------------------
     	 *  NET: DM900
     	 * -------------------------------------------------------------------- */ 
     	#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
     	static struct resource rm9200_dm9k_resource[] = {
     		[0] = {
     			.start = rm9200_CS3,       /* ADDR7=0,發送位址時使用這個位址 */
     			.end   = rm9200_CS3 + 3,
     			.flags = IORESOURCE_MEM,
     		},
     		[1] = {
     			.start = rm9200_CS3 + 0x80,   /* ADDR7=1,傳輸資料時使用這個位址 */
     			.end   = rm9200_CS3 + 0x80 + 3,
     			.flags = IORESOURCE_MEM,
     		},
     		[2] = {
     			.start = dm9000_irq,         /* 中斷号 */
     			.end   = dm9000_irq,
     			.flags = IORESOURCE_IRQ,
     		}
    
     	};
    
     	/* for the moment we limit ourselves to 16bit IO until some
     	 * better IO routines can be written and tested
     	*/
    
     	static struct dm9000_plat_data rm9200_dm9k_platdata = {
     		.flags      = DM9000_PLATF_16BITONLY,
     	};
    
     	static struct platform_device rm9200_device_dm9k = {
     		.name       = "dm9000",
     		.id     = 0,
     		.num_resources  = ARRAY_SIZE(rm9200_dm9k_resource),
     		.resource   = rm9200_dm9k_resource,
     		.dev        = {
     			.platform_data = &rm9200_dm9k_platdata,
     		}
     	};
     	#endif /* CONFIG_DM9000 */
    
     添加line446:
     	#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
     		/* dm9000 */
     		platform_device_register(&rm9200_device_dm9k);
     	#endif
               

    /linux-2.6.22.6/drivers/net/dm9000.c:

    添加line412:

    #if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)

    volatile unsigned long *AT91C_BASE_SMC2_CS3; //0xFFFFFF7C

    AT91C_BASE_SMC2_CS3 = (unsigned long*)ioremap(0xFFFFFF7C, 4);
     		
     		*AT91C_BASE_SMC2_CS3 = 0x1100318A;
    
     		iounmap(AT91C_BASE_SMC2_CS3);
    
     	#endif
     
     添加line595: 
     	#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
     		printk("Now use the default MAC address: 00:00:3e:0a:26:00\n");
     		ndev->dev_addr[0] = 0x00;
     		ndev->dev_addr[1] = 0x00;
     		ndev->dev_addr[2] = 0x3e;
     		ndev->dev_addr[3] = 0x26;
     		ndev->dev_addr[4] = 0x0a;
     		ndev->dev_addr[5] = 0x00;
     	#endif
               

    配置u-boot支援擴充dm9000網卡:

    注釋line236: // #define CONFIG_DRIVER_CS8900 1

    打開line270: #define CONFIG_DRIVER_DM9000 1

    配置menuconfig:

    Device Drivers —>

    Network device support —>

    Ethernet (10 or 100Mbit) —>

    <*> DM9000 support

    修改環境變量:

    U-Boot> setenv bootcmd nfs 20007FC0 10.124.0.45:/work/nfs_root/uImage ;bootm 20007FC0

    U-Boot> setenv bootargs noinitrd root=/dev/nfs nfsroot=10.124.0.45:/work/nfs_root/new_fs_mini ip=10.124.0.33:10.124.0.45:10.124.0.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC0,115200

    U-Boot> saveenv

    測試, 上電觀察序列槽列印輸出:

    dm9000 Ethernet Driver

    Now use the default MAC address: 00:00:3e:0a:26:00

    eth0: dm9000 at c285c000,c285e080 IRQ 25 MAC: 00:00:3e:26:0a:00

    VFS: Mounted root (nfs filesystem).

    Freeing init memory: 108K

    init started: BusyBox v1.7.0 (2020-07-27 18:45:41 CST)

    starting pid 690, tty ‘’: ‘/etc/init.d/rcS’

    Please press Enter to activate this console.
     starting pid 696, tty '/dev/ttyS0': '/bin/sh'
     #
               
  4. 擴充dm9000驅動移植方法2(使用dm9dev9000c.c)

    修改dm9dev9000c.c:

    注釋line411: //if((db->chip_revision!=0x1A) || ((chip_info&(1<<5))!=0) || ((chip_info&(1<<2))!=1)) return -ENODEV;

    添加line1609: #fefine MODULE
     			
     修改line1631: int __init init_module(void)	
     	為: int __init dm9000a_init(void)
     	
     修改line1653: void __exit cleanup_module(void)
     	為: void __exit dm9000a_exit(void)
     	
     添加最後一行#endif上面: module_init(dm9000a_init);
     			module_exit(dm9000a_exit);
     
     修改line478: if (request_irq(dev->irq,&dmfe_interrupt,0,dev->name,dev)) 
     	為: if (request_irq(dev->irq,&dmfe_interrupt,IRQF_TRIGGER_RISING,dev->name,dev)) //IRQF_TRIGGER_RISING=1
     	
     修改line382: outb(DM9KS_VID_L, iobase);
     			id_val = inb(iobase + 4);
     			outb(DM9KS_VID_H, iobase);
     			id_val |= inb(iobase + 4) << 8;
     			outb(DM9KS_PID_L, iobase);
     			id_val |= inb(iobase + 4) << 16;
     			outb(DM9KS_PID_H, iobase);
     			id_val |= inb(iobase + 4) << 24;
     		為: 
     			outb(DM9KS_VID_L, iobase);
     			id_val = inb(iobase + 0x80);
     			outb(DM9KS_VID_H, iobase);
     			id_val |= inb(iobase + 0x80) << 8;
     			outb(DM9KS_PID_L, iobase);
     			id_val |= inb(iobase + 0x80) << 16;
     			outb(DM9KS_PID_H, iobase);
     			id_val |= inb(iobase + 0x80) << 24;
     	
     修改line417: db->io_data = iobase + 4; 
     	為: db->io_data = iobase + 0x80; 
     	
     添加line35: 
     	volatile unsigned long *AT91C_BASE_SMC2_CS3; //0xFFFFFF7C
     	AT91C_BASE_SMC2_CS3 = (unsigned long*)ioremap(0xFFFFFF7C, 4);		
     	*AT91C_BASE_SMC2_CS3 = 0x1100318A;
     	iounmap(AT91C_BASE_SMC2_CS3);
     	
     	iobase = (unsigned int)ioremap(0x40000000, SZ_1M);
     	irq = 93; 							// irq0: 25 or 93
     
     添加line1685: 
     	iounmap((void *)iobase);
     
     時間參數配置過程:
     	參考: at91rm9200晶片手冊(Page167): Figure 66. 不含 tDF 的标準讀協定
     		  dm9000aep(Page49): 10.3 AC Electrical Characteristics & Timing Waveforms
     	a. dm9000不發出等待信号,是以 等待狀态使能WSEN = 1; 
     	b. 片選啟動位址 ACSS=0;
     	c. 讀、寫信号啟動時間 NRD = 0, NWD = 0, RWSETUP = 0;
     	d. 讀、寫信号保持時間: >=10ns RWHOLD = 1;
     	AT91C_BASE_SMC2->SMC2_CSR[3] = 0x10003183;
               

    配置/linux-2.6.22.6/drivers/net/Kconfig:

    添加line878:

    config DM9DEV9000C

    tristate “DM9DEV9000C support”

    depends on (ARM || MIPS) && NET_ETHERNET

    select CRC32

    select MII

    —help—

    Support for DM9000 chipset.

    To compile this driver as a module, choose M here and read
     		  <file:Documentation/networking/net-modules.txt>.  The module will be
     		  called DM9DEV9000C.
               

    配置/linux-2.6.22.6/drivers/net/Makefile:

    添加line199:

    obj-$(CONFIG_DM9DEV9000C) += dm9dev9000c.o

    配置menuconfig:

    Device Drivers —>

    Network device support —>

    Ethernet (10 or 100Mbit) —>

    <*> DM9DEV9000C support

    配置u-boot支援擴充dm9000網卡:

    注釋line236: // #define CONFIG_DRIVER_CS8900 1

    打開line270: #define CONFIG_DRIVER_DM9000 1

    修改環境變量:

    U-Boot> setenv bootcmd nfs 20007FC0 10.124.0.45:/work/nfs_root/uImage ;bootm 20007FC0

    U-Boot> setenv bootargs noinitrd root=/dev/nfs nfsroot=10.124.0.45:/work/nfs_root/new_fs_mini ip=10.124.0.33:10.124.0.45:10.124.0.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC0,115200

    U-Boot> saveenv

    測試, 上電觀察序列槽列印輸出:

    I/O: c2a00000, VID: 90000a46

    id_val=0

    Freeing init memory: 108K

    init started: BusyBox v1.7.0 (2020-07-27 18:45:41 CST)

    starting pid 688, tty ‘’: ‘/etc/init.d/rcS’

    Please press Enter to activate this console.
     starting pid 694, tty '/dev/ttyS0': '/bin/sh'
     #
               

繼續閱讀