专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »数据库 » linux启动过程:用网络卡从并口上启动Linux »正文

linux启动过程:用网络卡从并口上启动Linux

来源: 发布时间:星期二, 2009年5月5日 浏览:0次 评论:0
="t18">
  作者:raoxianhong
  
  代码:
  
  1、到底想干什么
   了解Linux启动过程制作个自己Linux启动可以增加对Linux了解还能学习PC机启动机制增进对计算机结构了解增强对Linux内核学习信心
  也可以在某些专用产品中使用(比如专用服务器)为此我尝试在原来代码基础上修改制作了个用网络卡从并口上启动Linux以博其中有许多问题值得研究
  2、Linux对启动要求
   Linux(bzImage Kernel)对启动要求比较简单你只要能够建立个启动头(up.S)
  给出些信息然后将kernel(/usr/src/linux/arch/i386/boot/compressed/bvmlinux.out)调到
  绝对地址0x100000(1M地址处)假如有initrd则将它调到内存高端(离0x100000越远越好,比如假如
  initrd小于4M就可以将它调到地址0xB00000即12M处相信现在已经很少有少于16M内存机器了)
  然后执行化操作跳到内核处就行了
   当然说起来轻易做起来还有点麻烦以下分几个问题解释
  3、PC机开机流程--启动放在何处
   PC机加电后进入实模式先进行自检然后化各个总线扩展设备(ISA, EISAPCIAGP)
  全部化做完后从当前启动设备中读个块(512字节)到07C0:0000处将控制转到该处
   了解这个过程我们可以决定将启动放在何处:
   1)放在启动设备MBR(主启动记录中)比如磁盘启动扇区这是启动方式
   2)放在总线扩展设备扩展rom中比如网卡boot rom就行这里制作启动就是放在网卡中,可以支持 16K字节
   3)哪位高手能够修改ROMBIOS让BIOS在做完化后不要马上从启动设备读数据而是段外面 加入(2K字节就够了当然也必须和修改后BIOS起烧在BIOS ROM中)就可以从BIOS启动!
   4)先启动个操作系统再在此操作系统中写启动(比如lodlin16就是从DOS中启动Linux好象中软
   提供了个从Windows下启动Linux启动)
  4、操作系统放在何处
   操作系统(般内核在500K-1M的间加上应用可以控制在2M以内当然都经过压缩了)数据选择余地就大了
  可以从软盘、硬盘、CDROM、网络、磁带机、并口(软件Software狗上烧个内核和应用?)、串口(外接你设备)、 USB设备(?)、PCI扩展卡、IC卡等等上面来读;各位还有什么意见提醒提醒有位老兄说实在不行可以用键盘启动每次启动时把内核敲进去还有 16h支持呢做起来也不难应该是最节省方案了
   反正个原则是在启动中能够从该设备上读就行了这里最简单就是并口了简单端口操作不需 要任何驱动支持不需要BIOS支持比磁盘还简单(磁盘般使用 13h,主要是计算柱面啊、磁头啊、磁道啊、扇区啊好麻烦幸好有现成源代码可以学习学习)
   好了我们挑个简单方案将启动代码(bootsect.S+up.S)放到网络卡boot rom中内核数据和应用数据放到另外台计算机上用并口提供下面谈谈几个相关问题
  5、将数据移动到绝对地址处
   第个问题我们得到数据是在实模式下所以般是放在1M地址空间内怎样将它移动到指定地方去
  在up.S 源代码中使用了 15h(87h号功能)这里将该段代码稍加改动,做了些假设列到下面:
  流程是:
   (%cs:move_es0)/*由于使用前move_es化为0因此这是第此时es:bx是要移动数据
   存放处bx=0,es低 4为位为零表示es:bx在64K边界上fs低8位指定目地地址
   也以64K字节为单位用不着那么精确以简化操作*/
   {
   将es右移 4位得到64K单位8位地址(这样最多只能将数据移动到16M以下了)作为源数据
   描述符中24位地址高8位低16位为零
   将fs低8位作为目描述符中24位地址高8位同样低16位为零
   将es存放在move_es中es自然不会是零因此以后再该例程时就进行正常移动操作了
   ax清零返回

   }
  
   {
   (bx0)/*bx为零表示数据已经满64K了应该进行实际移动*/
   {
   15h 87h号功能进行实际数据移动(64K, 0x8000个16字节块)
   目地址(24位)高8位增往后走64K
   ax = 1
   ;
   }
  
   {
   ax = 0;
   ;
   }
   }
  # we will move %cx s from es:bx to %fs(64Ks per unit)
  # when we first call movetohigh(%cs:move_es is zero),
  # the es:bx and %edx is valid
  # we configure the param first
  # follow calls will move data actually
  # %ax 0 no data really moved, and 1 there is data
  # really to be moved
  #
  movetohigh:
   cmpw $0, %cs:move_es
   jnz move_second
   # at this po , es:bx(bx = 0) is the source address
   # %edx is the destination address
   movb $0x20, %cs:type_of_loader
   movw %es, %ax
   shrw $4, %ax
   movb %ah, %cs:move_src_base+2
   movw %fs, %ax
   movb %al, %cs:move_dst_base+2
   movw %es, %ax
   movw %ax, %cs:move_es
   xorw %ax, %ax
   ret # nothing to do for now
  move_second:
   xorw %ax, %ax
   testw %bx, %bx
   jne move_ex
   pushw %ds
   pushw %cx
   pushw %si
   pushw %bx
   movw $0x8000, %cx # full 64K, INT15 moves Words
   pushw %cs
   popw %es
   leaw %cs:move_gdt, %si
   movw $0x8700, %ax
   $0x15
   jc move_panic # this, INT15 fails
   movw %cs:move_es, %es # we re %es to always po
   incb %cs:move_dst_base+2 # to 0x10000
   popw %bx
   popw %si
   popw %cx
   popw %ds
   movw $1, %ax
  move_ex:
   ret
  move_gdt:
   .word 0, 0, 0, 0
   .word 0, 0, 0, 0
  move_src:
   .word 0xffff
  move_src_base:
   . 0x00, 0x00, 0x01 # base = 0x010000
   . 0x93 # typ
   .word 0 # limit16,base24 =0
  move_dst:
   .word 0xffff
  move_dst_base:
   . 0x00, 0x00, 0x10 # base = 0x100000
   . 0x93 # typ
   .word 0 # limit16,base24 =0
   .word 0, 0, 0, 0 # BIOS CS
   .word 0, 0, 0, 0 # BIOS DS
  move_es:
   .word 0
  move_panic:
   pushw %cs
   popw %ds
   cld
   leaw move_panic_mess, %si
   call prtstr
  move_panic_loop:
   jmp move_panic_loop
  move_panic_mess:
   . "INT15 refuses to Access high mem, giving up."
  6、用并口传输数据
   用并口传输数据可以从/usr/src/linux/driver/net/plip.c中抄我们采用半字节协议
  并口线连接参考该文件
字节收发过程如下:
  # PORT_BASE 0x378
  # data_write(b) outportb(PORT_BASE, b)
  # data_read inportb(PORT_BASE+1)
  # OK 0
  # TIMEOUT 1
  # FAIL 2
  
   send(unsigned char data)
  {
   unsigned char c0;
   unsigned long cx;
   data_write((data & 0x0f));
   data_write((0x10 (data & 0x0f)));
   cx = 32767l * 1024l;
   while (1) {
   c0 = data_read;
   ((c0 & 0x80) 0)
   ;
   (--cx 0)
   TIMEOUT;
   }
   data_write(0x10 (data >> 4));
   data_write((data >> 4));
   cx = 32767l * 1024l;
   while (1) {
   c0 = data_read;
   (c0 & 0x80)
   ;
   (--cx 0)
   TIMEOUT;
   }
   OK;
  }
   rcv(unsigned char * pByte)
  {
   unsigned char c0, c1;
   unsigned long cx;
   cx = 32767l * 1024l;
   while (1) {
   c0
0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: