首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

嵌入式linux论文

2)修改utility.c
当你书写程序的时候,请注意在utility.c中已存在的有用的函数体。使用这些函体而不重复创建它们。
如果你使用了来自utility.c的函数,你需要添加预处理条件句,以确保你需要的例行程序被包括在内。因此,由于你的mu使用了safe_read(),要添加“|| defined BB_MU”到utility.c中safe_read()函数前的#if指令中。
2) 修改usage.c
然后向usage.c添加使用信息。代码如下:
#if defined BB_MU
const char mu_usage[] =
"mu\n"
#ifndef BB_FEATURE_TRIVIAL_HELP
"\nReturns an indeterminate value.\n"
#endif
;
如果你的程序支持标量,标量应该在第一行被声明(mu -[bcRovma]),每个标量的详细描述应该在BB_FEATURE_TRIVIAL_HELP部分,一个标量一行。
3) 修改applets.h
向applets.h添加入口。确定按字母的顺序排列,否则会中断busybox.c中的二进制搜索查找算法。代码如下:
/* all programs above here are alphabetically "less than" 'mu' */
#ifdef BB_MU
APPLET("mu", mu_main, _BB_DIR_USR_BIN, mu_usage)
#endif
/* all programs below here are alphabetically "greater than" 'mu' */4)4)修改Config.h
向Config.h中添加
#define BB_MU
4.6什么是QT
Qt是一个跨平台的C++图形用户界面库,由挪威TrollTech公司出品,目前包括Qt,基于Framebuffer的Qt Embedded,快速开发工具Qt Designer,国际化工具Qt Linguist等部分,Qt支持所有Unix系统,当然也包括Linux,还支持WinNT/Win2k,Win95/98平台。
基本上,Qt同X Window上的Motif,Openwin,GTK等图形界面库和Windows平台上的MFC,OWL,VCL,ATL是同类型的东西,但是Qt具有下列优点:
-优良的跨平台特性:
Qt支持下列操作系统:Microsoft Windows 95/98,Microsoft Windows NT,Linux,Solaaris,SunOS,HP-UX,Digital UNIX(OSF/1,Tru64),Irix,FreeBSD,BSD/OS,SCO,AIX,OS390,QNX等等。
-面向对象:
Qt的良好的封装机制使得Qt的模块化程度非常高,可重用性较好,对于用户开发来说是非常方便的。Qt提供了一种称为signals/slots的安全类型来替代callback,这使得各个元件之间的协同工作变得十分简单了。
-丰富的API:
Qt包含多达250个以上的C++类,还提供基于模板的collections,serialization,file,I/O device,derectory management,data/time类。甚至还包括正则表达式的处理功能。
-支持2D/3D图形渲染,支持OpenGL
-大量的开发文档
-XML支持
大家熟知的KDE就是基于Qt的重量级软件

第四章 构造嵌入式实时Linux
§1构造嵌入式实时Linux的开发环境
以下内容介绍了如何构造自己的嵌入式实时Linux,图形界面采用的Qt Embedded,实时功能采用RTAI,开发环境如下:
-百资Linux7操作系统
-Linux核心2.2.16
-qpe-1.1.0-x86-bin
-RTAI-1.4
-Busybox0.51
-kbd-1.06
很多命令和文件直接从百资Linux7操作系统下拷贝过来,包括ash,glibc2等,下文中涉及的几个概念及操作已经在上文中说明。本文采用用引导软盘引导Linux系统,然后加载定制在硬盘上的linux文件系统的方法。后边还涉及从eprom引导的方法的介绍。由于采用的是图形界面方式,不用在终端下直接打命令,有些操作可以在Gnome或KDE下进行,比如文件的压缩和解压命令,都可在KDE的archiver。
51 c8051f(f020,f040) msp430 arm(2410,2510) fpga(xc3s4000) dsp(5116 dm642) keilc vc++ matlab linux protel Ten_layerPCB mpegx h.26x Rscode Turbocode ofdm VideoBroadcasting ldpc_code(now!)
2 Linux启动过程简介
一个启动盘实际上是一个完整系统的缩影,它能够执行一个完整系统的大部分功能。因此,如果想制做Linux启动盘,你必须了解Linux系统启动的基本过程。接下来我就先简要介绍一下Linux的启动过程。
所有的PC机都是通过执行ROM中的代码加载启动盘的0柱面0扇区中的代码来启动整个系统。在Linux系统中启动盘的0柱面0扇区中含有的是启动装载器L ILO,它定位内核,装载它,最后执行它。一旦内核装载后,它先是进行基本设备初始化,接着试图加载并登陆磁盘中根文件系统,如果内核找不到可装载的根文件系统,启动过程会就此停止。如果根文件系统装载完毕并登陆成功后,你会看到一行信息:
VFS: Mounted root (ext2 filesystem) readonly.
之后,系统发现init程序并执行它,init程序寻找它的配置文件/etc/inittab,并开始执行其中的脚本,这些脚本是一些SHELL命令的组合,用来执行如下命令,如加载所需模块、装载SWAP、初始化网络、装载fstab中列出的所有驱动器等。最后启动一个叫getty的程序,它负责console和ttys之间的通信,它在显示器上打印l ogin提示符并激活login程序,login处理登陆的有效性并建立与用户的对话。至此,启动过程完毕。
§3 配置和编译内核
下面讨论如何根据自己系统的需求重新编译生成新的内核。编译内核是非常简单的工作,一般只要根据“/usr/src/linux/”目录下的README文件中的指示就都可以完成。为了正确的合理地设置内核编译配置选项,从而只编译系统需要的功能的代码,一般主要有下面四个考虑:①自己定制编译的内核运行更快(具有更少的代码);②系统将拥有更多的内存(内核部分将不会被交换到虚拟内存中);③不需要的功能编译进入内核可能会增加被系统攻击者利用的漏洞;④将某种功能编译为模块方式会比编译到内核内的方式速度要慢一些。
(1)解压内核源代码到/usr/src/,注意源码目录名应该为Linux:
[root@deep]# cp linux-version_tar.gz /usr/src/
[root@deep]# cd /usr/src/
[root@deep]# tar xzpf linux-version_tar.gz
(2)修改/usr/src/linux/drivers/block/rd.c文件,使ramdisk支持所有的储存设备,而不是只支持从软盘加载文件系统。
ramdisk.c
/* Code fragment from ramdisk.c */
/* Old code - only load ramdisk if booting from floppy */
if (MAJOR(ROOT_DEV) != FLOPPY_MAJOR
#ifdef CONFIG_BLK_DEV_INITRD
&& MAJOR(real_root_dev) != FLOPPY_MAJOR
#endif
)
return;
... code to load ramdisk from block device
/* New code - always try to load ramdisk */
if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR
#ifdef CONFIG_BLK_DEV_INITRD
&& MAJOR(real_root_dev) == FLOPPY_MAJOR
#endif{

/* Load even from hard disk */
/* or from EPROM disk */
printk(KERN_NOTICE "VFS: Insert ramdisk floppy and press
ENTER\n");
wait_for_keypress();
}
... code to load ramdisk from block device

(3)解压RTAI-1.4源代码到?/,patch核心
解压RTAI源代码文件到任意目录?/下
#cd ?/rtai-1.4
#make patch
(4)配置核心
使用下面的命令来确保系统没有陈旧的“.o”文件及依赖关系:
[root@deep]# cd /usr/src/linux/
[root@deep]# make mrproper
开始配置内核
#cd /usr/src/linux
#make config或
#make menuconfig或
#make xconfig
由于新下载的源代码已经配置了最基本的内容,我们只需添加我们需要的,以下内容必须编译进核心:
51 c8051f(f020,f040) msp430 arm(2410,2510) fpga(xc3s4000) dsp(5116 dm642) keilc vc++ matlab linux protel Ten_layerPCB mpegx h.26x Rscode Turbocode ofdm VideoBroadcasting ldpc_code(now!)
1)RTAI需要编译的内容
Processor type and features ->
...
  • MTRR support
    ...
  • Real-Time Hardware Abstraction Layer (NEW)
    Loadable module support ->
  • Enable loadable module support
    [ ] Set version information on all symbols for modules // FORBIDDEN
    ...
    )
    2)frambuffer需要编译的内容
    Code maturity level opetions
      
  • Prompt for development and/or incomplete codes/drivers
       Console drivers
      
  • Video mode selection support
       ...
      
  • Support for frame buffer devices
       ...
      
  • VESA VGA graphics console
       ...
      
  • Advance low level driver options
    3)使用模块需要编译的内容
    Loadable module support
  • Enable loadable module support
    [ ] Set version information on all symbols for modules
  • Kernel daemon support (e.g.autoload of modules)
    4)其他内容
    检查核心是否支持Ramdisk,ps/2鼠标,kernel hacking,tcp/ip,ext2等
    (5)编译压缩内核
    现在返回到“/usr/src/linux/”目录下,下面开始进行内核编译工作,按照下面的命令进行:

    [root@deep]# make dep; make clean; make bzImage

    这行包含三个命令,第一个命令“make dep”实际上读取上一步配置过程生成的配置文件,来创建对应于配置的依赖关系树,从而决定哪些需要编译而那些不需要;第二命令“make clean”完成删除前面步骤留下的文件,以避免出现一些错误;第三步“make bzImage”实现完全编译内核。

    处理结束以后,生成的被压缩的新内核就可以被安装了。如果你在回答Enable loadable module support (CONFIG_MODULES)选“Yes”,在安装新内核以前,就还需要编译一些模块并且正确的安装。通过下面的命令来实现对模块的编译和安装:

    [root@deep]# make modules;make modules_install
    §4制作启动盘
    接着就是确定是用LILO控制启动还是直接用拷贝到盘上的内核控制启动。用LILO的好处是你能增加支持初始化硬件的参数到内核中,缺点是较复杂且占用珍贵的磁盘空间,不过我还是建议使用LILO控制系统启动。下面我就介绍用LILO的过程,直接用拷贝到盘上的内核控制启动的方法就不作叙述了。
      (1)用LILO控制启动首先就得写一个LILO配置文件,以下是一个最简单的配置文件,但是已经够用了。
      boot =/dev/fd0
      install =/boot/boot.b
      map =/boot/map
      read-write
      backup =/dev/null
      compact
      image = KERNEL(即bzImage)
      label = Bootdisk
      root =/dev/hdax (文件系统所在的硬盘分区位置)
    vga=0x314(framebuffer的配置)
    ramdisk=65536(设置ramdisk的大小)
      参数说明见相关资料。然后把它命名为bdlilo.conf。 
      (2)接下来就是创建一个内核文件系统。把一张干净的软盘插入软驱,在上面创建ext2文件系统。
      mke2fs -i 8192 -m 0 /dev/fd0 50 或用fdformat /dev/fd0格式化软盘
      “-i 8192”表示每8192位创建一个信息节点。接着登陆系统:
      mount /dev/fd0 /mnt
      rm -rf /mnt/lost+found
      mkdir /mnt/{boot,dev}
      删去目录/ lost+found,创建两个目录/boot和/dev,再拷贝现有系统中的到目录/dev中,
      cp -R /dev/{null,fd0} /mnt/dev
    /dev目录下还需要几个设备,fb0(framebuffer设备),文件系统所在的硬盘分区,以及RTAI设备
      接着拷贝启动加载器boot.b到目录/boot中,
      cp /boot/boot.b /mnt/boot
    拷贝“/usr/src/linux/System.map”到启动目录下
    [root@deep]# cp /usr/src/linux/System.map /boot
      拷贝你创建的配置文件bdlilo.conf到内核文件系统的根目录下,
      cp bdlilo.conf /mnt
    拷贝新内核文件“/usr/src/linux/arch/i386/boot/bzImage”根目录
    [root@deep]# cp /usr/src/linux/arch/i386/boot/bzImage /mnt
      现在,根文件系统所需所有文件都准备就绪了,你可以运行它了,运行结果应该没有错误,否则就应该仔细检查一下。
  • 51 c8051f(f020,f040) msp430 arm(2410,2510) fpga(xc3s4000) dsp(5116 dm642) keilc vc++ matlab linux protel Ten_layerPCB mpegx h.26x Rscode Turbocode ofdm VideoBroadcasting ldpc_code(now!)
    (3)接着设置内核镜像文件中的ramdisk的偏移量以指出如何确定定位根文件系统。该指示词可以通过命令rdev来设置,它的内容含义如下所示:
      bits 0-10: ramdisk开始的偏移量, 在1024 byte数据块中
      bits 11-13: 不用
      bit 14: ramdisk加载的提示标记
      bit 15: 加载根文件系统之前提示标记
      如果位15被设置,当系统盘启动时将会提示你准备好另一张软盘,如果你的启动盘是两张的话,这个设置很有用。
      对于使用单张和两张启动盘的用户,ramdisk的偏移量是不同的:

    如果你的启动盘只有一张,那么压缩的根文件系统会被放置在内核之后,因此偏移量将会是第一个空闲的数据块,bit 14 应设置为1,bit 15设置为0。例如,如果你的启动盘根文件系统起始于数据块253(十进制),你的ramdisk偏移量应该是253 + 214 = 253 + 16384 = 16637。

    如果你的启动盘有两张,那么你的根文件系统起始于第二张盘的0数据块,所以偏移量是0,bit 14 应设置为1,bit 15应设置为1,最终值为
    214 + 215 = 49152。
      计算好偏移量后,用命令rdev –r进行设置,记住用十进制:
      rdev -r /mnt/bzImage 偏移量
      4)运行lilo:
    lilo –v –C bdlilo.conf –r /mnt
    设置完后,从/mnt卸下软盘。
    §5定制文件系统
    根文件系统最少应该有如下8个目录:
    /dev – 设备
    /proc -- proc 文件系统所需目录
    /etc – 系统配置文件
    /sbin – 重要的系统程序
    /bin – 基本应用程序
    /lib – 共享函数库
    /mnt – 装载其他磁盘节点
    /usr – 附加应用程序
    其中/proc,/mnt和/usr在此情况下都是空的,只需要用mkdir创建它们既可。其余的目录应根据需要分别创建,下面我一个一个的详细叙述。
    ?/dev:/dev中含有系统不可缺少的设备文件,虽然该目录很普通,可以用 mkdir创建,然而目录中的设备文件必须用mknod创建,当然也有捷径,你可以把现有系统中/dev的文件拷贝过来,然后删除不必要的文件。命令cp -dpR /dev /mnt会拷贝/dev整个目录但不拷贝文件内容,dp开关保证链结文件仍然不变,不会拷贝链结所指原文件,而且属性不变。
    必须注意的是,每一个设备文件占用一个信息节点,而软盘上节点数是有限的,因此有必要删除没用的设备文件。例如,如果你没有SCSI 设备,删除所有的以sd开头的文件。如果你不想使用串口设备,删除所有以cua开头的文件。不过记住一定要保留console, kmem, mem, null, ram, tty1等文件。
    ./etc:这个目录中含有一些必不可少的系统配置文件,那么到底哪些文件是必需的,哪些可有可无呢?告诉你一个小窍门,用命令ls –ltru,该命令会根据最后使用日期反列一下目录/etc中的文件,如果一些文件很长时间没有被进入过,基本上可以从你的启动盘中删去。
    (1)安装Busybox-0.51
    把Busybox-0.51解压到一个目录下,然后编译和安装
    #cd ?/busybox-0.51
    #make
    #make install
    在生成的/busybox-0.51/_install/下,产生了一套命令集,可以书写自己的命令加入Busybox,Busybox-0.51下有一些命令默认的没有被编译,可以选择性的加入,加入方法见上文Busybox介绍
    在源程序的scripts文件夹中,有些好的inttab文件,由于该文件默认的外壳是内建的sh,而我们使用的是ash,需要修改
    ::askfirst:-/bin/sh 改为::askfirst:-/bin/ash
    Busybox-0.51使用的是内建的init命令,他取消了运行级的概念,如果使用运行级,就要安装sysvinit软件,这里不进行叙述。

    (2)安装RTAI
    #cd ?/RTAI-1.4
    #make
    #make install
    #make dev
    make install命令将RTAI需要的模块安装在了/lib/modules下
    make dev命令产生RTAI需要的fifo设备,详细操作见makefile文件
    (3)安装Qt-Embedded
    将qpe-1.1.0-bin-x86.tar解压到文件系统中,这是一个完全独立的版本,只需要最基本的命令和运行库就可以运行
    (4)其他文件系统按照如下定制
    /bin
    ash cat chgrp chmod chown cp date dd df dmesg false grep gunzip gzip kill ln ls mkdir mknod echo more mount mv ps pwd rm rmdir sed sh sleep tar touch true umount uname zcat sync kbd_mode
    /dev
    console core fb0 fd0 full hda hdb kmem loop mem null port psaux ram random rtai_shm rtf smouse tty urandom vcs vcsa zero
    /etc
    fstab inittab ld.so.cache mtab profile
    /etc/init.d
    rcS
    /lib
    ld-2.1.3.so ld-linux.so.1 ld-linux.so.1.9.5 ld-linux.so.2 ld.so ld.so.1.9.5 libc-2.1.3.so libc.so.6 libm-2.1.3.so libm.so.6 libpthread-0.8.so libpthread.so.0 libuClibc.so libuClibc.so.1
    /lib/modules/2.2.16-rthal3/misc
    lxrt.o rtai_fifos.o rtai.o rtai_sched.o rtai_shm.o
    /mnt
    /proc
    /sbin
    getty insmod rmmod halt init klogd lsmod mkswap poweroff reboot swapoff swapon syslogd
    /usr/bin
    basename chvt clear cut dirname du env find free head id killall reset sort tail tty uniq uptime wc which whoami xargs yes logger
    /usr/lib
    libstdc2-libc6.1-1-2.9.0.so libstdclibc6.0-1.so.2
    /qpe
    /rtai
    /usr/sbin/
    chroot
    51 c8051f(f020,f040) msp430 arm(2410,2510) fpga(xc3s4000) dsp(5116 dm642) keilc vc++ matlab linux protel Ten_layerPCB mpegx h.26x Rscode Turbocode ofdm VideoBroadcasting ldpc_code(now!)
    (5)需要书写的几个文件
    rcS文件
    #! /bin/sh
    /bin/mount -a
    fstab文件
    proc /proc proc defaults 0 0
    inittab文件
    ::sysinit:/etc/init.d/rcS
    ::askfirst:-/bin/ash
    tty2::askfirst:-/bin/sh
    tty3::askfirst:-/bin/sh
    tty4::askfirst:-/bin/sh
    tty5::respawn:/sbin/getty 38400 tty5
    tty6::respawn:/sbin/getty 38400 tty6
    ::ctrlaltdel:/bin/umount -a -r
    ::ctrlaltdel:/sbin/swapoff -a
    §6生成文件系统的ramdisk压缩镜像文件
    创建一个启动盘首先必须创建根文件系统,由于存储介质容量有限,因此常采用压缩的根文件系统。下面我就详细的介绍怎样创建压缩格式根文件系统。
    1)选择容纳文件系统的设备
    -用ramdisk(DEVICE=/dev/ram0)
    注意:默认的ramdisk只有4096k,可以更改/etc/lilo.conf中的ramdisk=nnn这个全局选项;如果没有/dev/ram0 /dev/ram /dev/ramdisk,用mknod(major 1 ,minor0)建立/dev/ram0
    -使用足够大的硬盘空间
    -使用loopback device:
    注意:如果没有/dev/loop0 /dev/loop1等,用” mknod /dev/loop0 b 7 0”来建立
    使用dd if=/dev/zero of=/tmp/fsfile bs=1k count=nnn来建立临时文件
    用”-o loop”来挂装一个loopback device,如:mount –o loop –t ext2 /tmp/fsfile /mnt
    选择完设备后用dd if=/dev/zero of=DEVICE bs=1k count=3000来准备设备
    2)建立文件系统用mke2fs –m 0 –I 2000 DEVICE
    3)挂装设备用mount –t ext2 DEVICE /mnt
    4)向设备中定制文件系统包括/dev /proc /etc /sbin /bin /lib /mnt /usr
    -注意:组件的安装,在/lib/modules中应包括insmod rmmod lsmod modprobe depmod swapout 还有/etc/conf.modules
    5)卸载设备,压缩用umount /mnt dd if=DEVICE bs=1k | gzip –v9 > rootfs.gz
    具体到本文的要求,命令如下:
    #dd if=/dev/zero of=/tmp/fsfile bs=1k count=1400
    #mke2fs –m 0 –I 2000 /tmp/fsfile(由于loop不是块设备,系统提示你确认)
    #mount –t ext2 –o loop /tmp/fsfile /mnt
    拷贝定制到的文件系统到/mnt目录下
    # dd if=/tmp/fsfile bs=1k | gzip –v9 > rootfs.gz
    #umount /mnt
    6)将压缩好的文件系统传入硬盘
    # dd if=/root/rootfs.gz of=/dev/hdax bs=1k
    §7运行及测试
    插入启动盘引导Linux
    运行qpe
    #cd /qpe
    #ash run
    测试RTAI
    #cd /rtai-1.4/examples
    #cd fp
    #./run
    FIFO 2: Zappa
    FIFO 1: Frank
    FIFO 2: Zappa
    FIFO 2: Zappa
    FIFO 2: Zappa
    FIFO 1: Frank
    ......
    51 c8051f(f020,f040) msp430 arm(2410,2510) fpga(xc3s4000) dsp(5116 dm642) keilc vc++ matlab linux protel Ten_layerPCB mpegx h.26x Rscode Turbocode ofdm VideoBroadcasting ldpc_code(now!)
    第五章 如何从eprom引导Linux
    基本的问题包括从EPROM的SSD(solid state disk)引导,将root文件系统从EPROM拷贝至一个RAM disk,从客户机加载Operator Interface软件并且执行它。本文主要讨论系统工作机制的细节以及它所使用的开发技巧。
    为了使系统工作,我们需要kernel-hacking。Ramdisk.c代码被改成可以从任意的块设备加载而不仅仅是从软盘。另外,我们写一个从EPROM设备的新的块设备驱动程序。
    实现EPROM设备驱动程序的第一种思想是在EPROM中生成一个磁盘映像。这会为我们提供一个同EPROM相同大小的RAM disk。为了得到一个大的RAM disk,我们使用一个压缩的磁盘映像。压缩的思想很简单,相同的扇区之存贮一次。这样的好处是磁盘映像的空白区域不占用EPROM空间。
    下一阶段的任务是将EPROM的磁盘内容组织在一起。我们使用分区的辅助盘来完成这项任务。
    /dev/had* - 6M EPROM
    然后对eprom编程,进行如下的操作
    #dd if=/dev/zero of=/tmp/fsfile bs=1k count=1400
    #mke2fs –m 0 –I 2000 /tmp/fsfile
    #mount –t ext2 –o loop /tmp/fsfile /mnt
    拷贝定制到的文件系统到/mnt目录下
    #dd if=/tmp/fsfile of=~/eprom.dsk count=14000
    这生成一个eprom.dsk文件,我们使用med.c程序将disk image(eprom.dsk)写入EPROMs(即对EPROMs编程)。
    Med ~/eprom.dsk ~/eprom.img
    然后EPROM程序员将EPROM image刻入EPROM中。
    Epromdsk.c代码如下:
    /*
    * linux/kernel/blk_drv/epromdsk.c
    *
    * from code by Theodore Ts'o, 12/2/91
    * Dave Bennett 11/95
    *
    */

    #include
    #include
    #include
    #include
    #include
    #include
    #include

    #include
    #include
    #include

    #define MAJOR_NR EPROM_MAJOR
    #include "blk.h"

    #define EPROMDISK_MINOR 1
    #define EPROMIMAGE_MINOR 2

    static int ed_length;
    static int sector_map;
    static int sector_offset;

    static int ed_blocksizes[2] = {0, 0};

    int get_edisk(unsigned char *buf, int sect, int num_sect);
    int get_image(unsigned char *buf, int ofs, int len);

    /* CURRENT_VERSION must match value in med.c */

    #define CURRENT_VERSION 3
    #define ntohs( X ) ((( X << 8 ) & 0xFF00 ) | (( X >> 8 ) & 0x00FF ))

    #define EPROM_WINDOW 0x0D0000
    #define EPROM_START 0x080000
    #define EPROM_START2 0x100000
    #define EPROM_SIZE 0x100000
    #define EPAGE_SIZE 0x010000
    #define CONTROL_REG1 0x0274
    #define CONTROL_REG2 0x0674

    static void do_ed_request(void)
    {
    int len,
    ofs;

    repeat:
    INIT_REQUEST;
    ofs = CURRENT->sector << 9;
    len = CURRENT->current_nr_sectors << 9;

    if (!( (MINOR(CURRENT->dev) == EPROMDISK_MINOR) ||
    (MINOR(CURRENT->dev) == EPROMIMAGE_MINOR) ) ||
    (ofs+len > ed_length)) {
    printk("EPROMDISK: minor=%d ofs=%d len=%d ed_length=0x%x\n",MINOR(CURRENT->dev),ofs,len,ed_length);
    end_request(0);
    goto repeat;
    }
    if (CURRENT->cmd == READ) {
    if (MINOR(CURRENT->dev) == EPROMDISK_MINOR) {
    get_edisk(CURRENT->buffer,CURRENT->sector,CURRENT->current_nr_sectors);
    }
    if (MINOR(CURRENT->dev) == EPROMIMAGE_MINOR) {
    get_image(CURRENT->buffer,ofs,len);
    }
    } else {
    panic("EPROMDISK: unknown RAM disk command !\n");
    }
    end_request(1);

    goto repeat;
    }

    static struct file_operations ed_fops = {
    NULL, /* lseek - default */
    block_read, /* read - general block-dev read */
    NULL, /* write - general block-dev write */
    NULL, /* readdir - bad */
    NULL, /* select */
    NULL, /* ioctl */
    NULL, /* mmap */
    NULL, /* no special open code */
    NULL, /* no special release code */
    NULL /* fsync */
    };
    51 c8051f(f020,f040) msp430 arm(2410,2510) fpga(xc3s4000) dsp(5116 dm642) keilc vc++ matlab linux protel Ten_layerPCB mpegx h.26x Rscode Turbocode ofdm VideoBroadcasting ldpc_code(now!)
    /*
    * Returns amount of memory which needs to be reserved.
    */


    long ed_init(long mem_start, int mem_end)
    {
    int i,
    ep;

    short tshort,
    version,
    length,
    s_ofs;

    if (register_blkdev(EPROM_MAJOR,"ed",&ed_fops)) {
    printk("EPROMDISK: Unable to get major %d.\n", EPROM_MAJOR);
    return 0;
    }
    blk_dev[EPROM_MAJOR].request_fn = DEVICE_REQUEST;

    for(i=0;i< 4) {
    printk("EPROMDISK: Length (%d) Too short.\n", length);
    return 0;
    }

    ed_length = length * 512;
    sector_map = ep + 6;
    sector_offset = ep + s_ofs;

    printk("EPROMDISK: Version %d installed, %d bytes\n", (int)version, ed_length);
    return 0;
    }


    int get_edisk(unsigned char *buf, int sect, int num_sect)
    {
    short ss, /* Sector start */
    tshort;
    int s; /* Sector offset */

    for(s=0;s0;) {
    sock = bp / EPROM_SIZE;
    page = (bp % EPROM_SIZE) / EPAGE_SIZE;
    offset = bp % EPAGE_SIZE;

    nb = (len+offset)>EPAGE_SIZE?EPAGE_SIZE-(offset%EPAGE_SIZE):len;

    cr1 = socket[sock] | ((page << 4) & 0x30) | 0x40; /* no board select for now */
    cr2 = (page >> 2) & 0x03;
    outb((char)cr1,CONTROL_REG1);
    outb((char)cr2,CONTROL_REG2);

    memcpy(buf+bofs,(char *)(EPROM_WINDOW + offset),nb);

    len -= nb;
    bp += nb;
    bofs += nb;
    }
    return 0;
    }

    med.c代码如下:
    /* med.c - make eprom disk image from ramdisk image */

    #include
    #include
    #include
    #define DISK_SIZE (6291456)
    #define NUM_SECT (DISK_SIZE/512)

    void write_eprom_image(FILE *fi, FILE *fo);

    int main(int ac, char **av)
    {
    FILE *fi,
    *fo;

    char fin[44],
    fon[44];

    if (ac > 1) {
    strcpy(fin,av[1]);
    } else {
    strcpy(fin,"hda3.ram");
    }

    if (ac > 2) {
    strcpy(fon,av[2]);
    } else {
    strcpy(fon,"hda3.eprom");
    }

    fi = fopen(fin,"r");
    fo = fopen(fon,"w");

    if (fi == 0 || fo == 0) {
    printf("Can't open files\n");
    exit(0);
    }

    write_eprom_image(fi,fo);

    fclose(fi);
    fclose(fo);
    }
    51 c8051f(f020,f040) msp430 arm(2410,2510) fpga(xc3s4000) dsp(5116 dm642) keilc vc++ matlab linux protel Ten_layerPCB mpegx h.26x Rscode Turbocode ofdm VideoBroadcasting ldpc_code(now!)
    void write_eprom_image(FILE *fi, FILE *fo)
    {
    char *ini;
    char *outi; /* In and out images */
    short *smap; /* Sector map */
    char *sp;
    char c = 0;

    struct {
    unsigned short version;
    unsigned short blocks;
    unsigned short sect_ofs;
    } hdr;

    int ns,
    s,
    i,
    fs;

    ini = (char *)malloc(DISK_SIZE); /* Max disk size is currently 6M */
    outi = (char *)malloc(DISK_SIZE); /* Max disk size is currently 6M */
    smap = (short *)malloc(NUM_SECT*sizeof(short));

    if (ini == NULL || outi == NULL || smap == NULL) {
    printf("Can't allocate memory \n");
    exit(0);
    }

    if (DISK_SIZE != fread(ini,1,DISK_SIZE,fi)) {
    printf("Can't read input file \n");
    exit(0);
    }

    memcpy(outi,ini,512); /* Copy in first sector */
    smap[0] = 0;
    ns = 1; /* Number of sectors in outi */

    for(i=1;i
    参考书目:
    [1]《GNU/Linux编程指南》 (美)K.Wall,M.Watson 清华大学出版社 1999
    [2] 《Linux实用指南》 (美)诺顿、格蕾菲斯著 翟大昆等译 机械工业出版社 1999
    [3]《嵌入式系統 -- 使用 C 与 C++》 Michael Barr 美商欧莱礼 1999
    [4] 《LINUX操作指南》 本社 人民邮电出版社 1999
    [5] 《Linux 实用大全》 杨文志编著 北京清华大学出版社 1999
    [6] 《单片机与嵌入式系统应用》 何立民 北京航空航天大学出版社 1999
    [7] 《Linux内核源代码分析》 (美)马克斯韦尔 机械工业出版社 2000
    [8] 《UNIX操作系统设计与实现》 陈华瑛、李建国 电子工业出版社出版 1999

    参考文献:
    [1]《frambuffer howto》 Geert Uytterhoeven www.linuxdoc.org 1998
    [2] 《RTAI Beginner Guide》Emanuele Bianchi www.rtai.org
    [3] 《Booting Linux from EPROM》 Dave Bennett www.linuxjournal.com
    [4]《ramdiskhowto》 Paul Gortmaker www.linuxdoc.org 1995
    [5]《kernelhowto》 Juan-Mariano de Goyeneche www.linuxdoc.org 2000
    [6] 《Embedded Linux Howto》 Sebastien Huet www.linux-embedded.com 2000
    [7]《lilohowto》 m.skoric www.linuxdoc.org 2001
    [8]《linux from scratch howto》 Gerard Beekmans www.linux-embedded.com 2000
    [9]《glibc2howto》 Eric Green www.linux.com 1998
    [10] 《Kernel Jorn》Alessandro Rubini & Georg Zezchwitz 《Linux Journal》1996
    [11]《rtlinux doc》 Michael Barabanov www.rtlinux.com 2001
    [12]《the linux boot disk howto》 Tom Fawcett www.linux-embedded.com 2000
    51 c8051f(f020,f040) msp430 arm(2410,2510) fpga(xc3s4000) dsp(5116 dm642) keilc vc++ matlab linux protel Ten_layerPCB mpegx h.26x Rscode Turbocode ofdm VideoBroadcasting ldpc_code(now!)
    返回列表