免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3546 | 回复: 5

[驱动] bootloader在内核启动结束还在运行不 [复制链接]

论坛徽章:
0
发表于 2011-07-23 15:35 |显示全部楼层
如题,在Bootloader的时候,网卡的指示灯被点亮了,可是我按了ESC,进入了下载模式,那个灯还在不停的闪。。 进到了LINux,已经可以输入ls命令了,那个灯还在闪。。不知道。。这个灯是Bootloader控制的。。还是内核控制的..哪位大侠能帮小弟分析下不。。。。

论坛徽章:
0
发表于 2011-07-23 16:12 |显示全部楼层
刚刚用EZP2010清了Flash。。只放了Bootloader。。 把start_kernel函数的所有内容全部注释了,然后把这样的bootloader 烧到Flash中。没想到。。  这个灯还是勇敢的亮了。。 哥。。。哭死了。。

刚刚又在没有Flash的情况下启动了板子,发现,不错。。灯一直在亮。。。  大侠。。快点Help一下啦。。。    急死了。。

论坛徽章:
0
发表于 2011-07-23 16:13 |显示全部楼层
这个灯是网卡的指示灯: 我拨掉网线,灯就灭了,插入网线,灯就亮了。。

论坛徽章:
0
发表于 2011-07-23 17:14 |显示全部楼层
嵌入式开发板上的灯有很多种连接方式,因此也有很多种控制方式,比如:
1.GPIO控制,你需要初始化GPIO为OUTPUT模式,然后拉高拉低GPIO就可以控制灯的亮灭。
2.硬件控制,比如大部分switch,phy在实际应用中,通过硬件控制LED,有包的时候就闪。当然也可以通过软件控制这些灯,因为这些灯其实是连在phy,switch后面的,具体要参考phy,switch的datasheet。实际应用中硬件控制LED降低了软件的负荷,但在生产测试的时候有可能要写一版特殊的程序软件控制LED,用来做测试,没人保证一生产出来这颗灯就是100%工作的,所以出厂之前要进行测试。但测试的时候不会叫操作人员插根网线看灯闪不闪,这样速度太慢,效率太低,并且很大程度上依赖于操作人员是否细心负责。所有现在测试这些灯的时候需要软件控制全部的灯全亮全灭,配合图像识别,把这些复杂琐碎的事情全部推给计算机!
3.如果板子上GPIO不够用,甚至可以通过一个锁存器,把LED连接在某些地址线上或者数据线上。
4.各种可行,奇怪的连接方式都有可能!

你看到的情况可以参考第2条。

论坛徽章:
0
发表于 2011-07-23 17:49 |显示全部楼层
本帖最后由 brauceunix 于 2011-07-23 17:56 编辑
嵌入式开发板上的灯有很多种连接方式,因此也有很多种控制方式,比如:
1.GPIO控制,你需要初始化GPIO为OU ...
郁郁前行 发表于 2011-07-23 17:14

嗯。。 谢谢大侠。。 那请问我在内核里可以用驱动继续控制他们吗?地址是0xb8003500.. 我驱动已经弄好了。。 但是只能读,写进去就不行。。。 网上说。是地址被别的程序战用了,我想会不会就是这段硬件给占了。。。
我把驱动贴出来,是LDD3书上silly那个驱动修改过来的。
我刚学驱动开发,这个是我写的第一个驱动程序,很多地方很生,不熟悉。。写得不好的地方。。还请多多包涵。
我测试的时候,主要就是:
  1. mknod /dev/sillyb c 231 0
复制代码

这样的话,我就得到一个8字节读写的一个设备,试过32位的,都读写不成功,但是读写0x200的那个地址是成功的。。 我把这个程序下到开发板上,还是不行。。。  

:
  1. /*
  2. * silly.c -- Simple Tool for Unloading and Printing ISA Data
  3. *
  4. * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
  5. * Copyright (C) 2001 O'Reilly & Associates
  6. *
  7. * The source code in this file can be freely used, adapted,
  8. * and redistributed in source or binary form, so long as an
  9. * acknowledgment appears in derived source files.  The citation
  10. * should list that the code comes from the book "Linux Device
  11. * Drivers" by Alessandro Rubini and Jonathan Corbet, published
  12. * by O'Reilly & Associates.   No warranty is attached;
  13. * we cannot take responsibility for errors or fitness for use.
  14. *
  15. * $Id: silly.c,v 1.3 2004/09/26 07:02:43 gregkh Exp $
  16. */

  17. /* =========================> BIG FAT WARNING:
  18. * This will only work on architectures with an ISA memory range.
  19. * It won't work on other computers.
  20. */

  21. #include <linux/module.h>
  22. #include <linux/init.h>
  23. #include <linux/moduleparam.h>
  24. #include <linux/version.h>

  25. #include <linux/sched.h>
  26. #include <linux/kernel.h> /* printk() */
  27. #include <linux/fs.h>          /* everything... */
  28. #include <linux/errno.h>  /* error codes */
  29. #include <linux/slab.h>
  30. #include <linux/mm.h>
  31. #include <linux/ioport.h>
  32. #include <linux/poll.h>

  33. #include <asm/io.h>
  34. #include <asm/uaccess.h>

  35. int silly_major = 231;
  36. module_param(silly_major, int, 0);
  37. MODULE_AUTHOR("Alessandro Rubini");
  38. MODULE_LICENSE("Dual BSD/GPL");

  39. /*
  40. * The devices access the 640k-1M memory.
  41. * minor 0 uses ioread8/iowrite8
  42. * minor 1 uses ioread16/iowrite16
  43. * minor 2 uses ioread32/iowrite32
  44. * minor 3 uses memcpy_fromio()/memcpy_toio()
  45. */

  46. /*
  47. * Here's our address range, and a place to store the ioremap'd base.
  48. */
  49. #if 1
  50. #define ISA_BASE        0xb8003500
  51. #define ISA_MAX     0xb80035f0  /* for general memory access */
  52. #endif
  53. #if 0
  54. #define ISA_BASE        0x200
  55. #define ISA_MAX                0x2ff  /* for general memory access */
  56. #endif
  57. #define VIDEO_MAX        0xC0000  /* for vga access */
  58. #define VGA_BASE        0xb8000
  59. static void __iomem *io_base;



  60. int silly_open(struct inode *inode, struct file *filp)
  61. {
  62.         return 0;
  63. }

  64. int silly_release(struct inode *inode, struct file *filp)
  65. {
  66.         return 0;
  67. }

  68. enum silly_modes {M_8=0, M_16, M_32, M_memcpy};

  69. ssize_t silly_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
  70. {
  71.         int retval, i = 0;
  72.         int mode = iminor(filp->f_dentry->d_inode);
  73.         void __iomem *add;
  74.         unsigned long isa_addr = ISA_BASE + *f_pos;
  75.         unsigned char *kbuf, *ptr;

  76.         if (isa_addr + count > ISA_MAX) /* range: 0xA0000-0x100000 */
  77.                 count = ISA_MAX - isa_addr;
  78.         printk("\nf_ops is %x\n", *f_pos);
  79.         /*
  80.          * too big an f_pos (caused by a malicious lseek())
  81.          * would result in a negative count
  82.          */
  83.         if (count < 0)
  84.                 return 0;

  85.         kbuf = kmalloc(count, GFP_KERNEL);
  86.         if (!kbuf)
  87.                 return -ENOMEM;
  88.         ptr = kbuf;
  89.         retval = count;
  90.         /*
  91.          * Convert our address into our remapped area.
  92.          */
  93.         add = (void __iomem *)(io_base + (isa_addr - ISA_BASE));
  94.         printk("add is %x\n", add);
  95.         /*
  96.          * kbuf is aligned, but the reads might not. In order not to
  97.          * drive me mad with unaligned leading and trailing bytes,
  98.          * I downgrade the `mode' if unaligned xfers are requested.
  99.          */

  100.         if (mode == M_32 && ((isa_addr | count) & 3))
  101.                 mode = M_16;
  102.         if (mode == M_16 && ((isa_addr | count) & 1))
  103.                 mode = M_8;

  104.         switch(mode) {
  105.           case M_32:
  106.                 while (count >= 4) {
  107.                         *(u32 *)ptr = ioread32(add);
  108.                         add += 4;
  109.                         count -= 4;
  110.                         ptr += 4;
  111.                 }
  112.                 break;
  113.             
  114.           case M_16:
  115.                 while (count >= 2) {
  116.                         *(u16 *)ptr = ioread16(add);
  117.                         add+=2;
  118.                         count-=2;
  119.                         ptr+=2;
  120.                 }
  121.                 break;
  122.             
  123.           case M_8:
  124.                 printk("begin:\n ");
  125.                 while (count) {
  126.                         *ptr = ioread8(add);
  127.                         add++;
  128.                         count--;
  129.                         ptr++;
  130.                         printk("%x ", *ptr);
  131.                 }
  132.                 printk("end\n");
  133.                 break;

  134.           case M_memcpy:
  135.                 memcpy_fromio(ptr, add, count);
  136.                 break;

  137.             default:
  138.                 return -EINVAL;
  139.         }
  140.         printk("copy:\n");
  141.         for (i = 0; i < retval; i ++) {
  142.                 printk("%x ", kbuf[i]);
  143.         }
  144.         if ((retval > 0) && copy_to_user(buf, kbuf, retval))
  145.                 retval = -EFAULT;
  146.         printk("end copy:\n");
  147.         for (i = 0; i < retval; i ++) {
  148.                 printk("%x ", kbuf[i]);
  149.         }
  150.         kfree(kbuf);
  151.         *f_pos += retval;
  152.         return retval;
  153. }


  154. ssize_t silly_write(struct file *filp, const char __user *buf, size_t count,
  155.                     loff_t *f_pos)
  156. {
  157.         int retval, i =0;
  158.         int mode = iminor(filp->f_dentry->d_inode);
  159.         *f_pos = 0;
  160.         //unsigned long isa_addr = ISA_BASE + *f_pos;
  161.         unsigned long isa_addr = ISA_BASE ;
  162.         unsigned char *kbuf, *ptr;
  163.         void __iomem *add;
  164. #if 0
  165.         unsigned long *light = 0xb8003500;
  166.         printk("light is %u\n", *light);       
  167.         *light = 0xff00;
  168.         printk("light is %u\n", *light);
  169. #endif

  170.         /*
  171.          * Writing is dangerous.
  172.          * Allow root-only, independently of device permissions
  173.          */
  174.         if (!capable(CAP_SYS_RAWIO))
  175.                 return -EPERM;

  176.         if (isa_addr + count > ISA_MAX) /* range: 0xA0000-0x100000 */
  177.                 count = ISA_MAX - isa_addr;
  178.         printk("\nwrite...\n");
  179.         printk("f_pos is %u\n", f_pos);
  180.         printk("count is %u\n", count);
  181.         /*
  182.          * too big an f_pos (caused by a malicious lseek())
  183.          * results in a negative count
  184.          */
  185.         if (count < 0)
  186.                 return 0;

  187.         kbuf = kmalloc(count, GFP_KERNEL);
  188.         if (!kbuf)
  189.                 return -ENOMEM;
  190.         ptr = kbuf;
  191.         retval=count;

  192.         /*
  193.          * kbuf is aligned, but the writes might not. In order not to
  194.          * drive me mad with unaligned leading and trailing bytes,
  195.          * I downgrade the `mode' if unaligned xfers are requested.
  196.          */

  197.         if (mode == M_32 && ((isa_addr | count) & 3))
  198.                 mode = M_16;
  199.         if (mode == M_16 && ((isa_addr | count) & 1))
  200.                 mode = M_8;

  201.         if (copy_from_user(kbuf, buf, count)) {
  202.                 kfree(kbuf);
  203.                 return -EFAULT;
  204.         }
  205.         ptr = kbuf;
  206.         printk("data from user:\n");
  207.         for (i = 0; i < 10; i ++)  {
  208.                 printk(" %x", ptr[i]);
  209.         }
  210.         /*
  211.          * Switch over to our remapped address space.
  212.          */
  213.         kbuf[0] = 'h';
  214.         kbuf[1] = 'h';
  215.         kbuf[2] = 'h';
  216.         add = (void __iomem *)(io_base + (isa_addr - ISA_BASE));
  217.         printk("add is %x\n", add);

  218.         switch(mode) {
  219.           case M_32:
  220.                 while (count >= 4) {
  221.                         iowrite8(*(u32 *)ptr, add);
  222.                         add += 4;
  223.                         count -= 4;
  224.                         ptr += 4;
  225.                 }
  226.                 break;
  227.             
  228.           case M_16:
  229.                 while (count >= 2) {
  230.                         iowrite8(*(u16 *)ptr, add);
  231.                         add += 2;
  232.                         count -= 2;
  233.                         ptr += 2;
  234.                 }
  235.                 break;
  236.             
  237.           case M_8:
  238.        
  239.                 while (count) {
  240.                         iowrite8(*ptr, add);
  241.                         printk("p:%x", *ptr);
  242.                         add++;
  243.                         count--;
  244.                         ptr++;
  245.                 }
  246.                 break;

  247.           case M_memcpy:
  248.                 memcpy_toio(add, ptr, count);
  249.                 break;

  250.           default:
  251.                 return -EINVAL;
  252.         }
  253.         *f_pos += retval;
  254.         kfree(kbuf);
  255.         return retval;
  256. }


  257. unsigned int silly_poll(struct file *filp, poll_table *wait)
  258. {
  259.     return POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM;
  260. }


  261. struct file_operations silly_fops = {
  262.         .read =            silly_read,
  263.         .write =    silly_write,
  264.         .poll =            silly_poll,
  265.         .open =            silly_open,
  266.         .release =  silly_release,
  267.         .owner =    THIS_MODULE
  268. };

  269. int silly_init(void)
  270. {
  271.         struct resource *res;
  272.         int result = register_chrdev(silly_major, "silly", &silly_fops);
  273.         if (result < 0) {
  274.                 printk(KERN_INFO "silly: can't get major number\n");
  275.                 return result;
  276.         }
  277.         if (silly_major == 0)
  278.                 silly_major = result; /* dynamic */
  279.         /*
  280.          * Set up our I/O range.
  281.          */

  282.         /* this line appears in silly_init */
  283.         io_base = ioremap(ISA_BASE, ISA_MAX - ISA_BASE);
  284.         res = request_mem_region(ISA_BASE, ISA_MAX-ISA_BASE, "sillyb");
  285.         if (res == NULL) {
  286.                 printk("res is in use\n");
  287.         }       
  288.         return 0;
  289. }

  290. void silly_cleanup(void)
  291. {
  292.         iounmap(io_base);
  293.         release_mem_region(ISA_BASE, ISA_MAX-ISA_BASE);
  294.         unregister_chrdev(silly_major, "silly");
  295. }


  296. module_init(silly_init);
  297. module_exit(silly_cleanup);
复制代码

论坛徽章:
0
发表于 2011-07-23 22:40 |显示全部楼层
问题找到了。。是没有在read或者write的时候进行关闭irq的操作。
最后这样了:在write那儿每写一次之前,加入local_irq_disable();  写入之后加入:local_irq_enable();
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP