分享
 
 
 

用网络卡从并口上启动Linux

王朝system·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

作者:raoxianhong

代码:

1、到底想干什么

了解Linux的启动过程,制作一个自己的Linux启动程序,可以增加对Linux的了解,还能学习PC机的启动机制,增进对计算机结构的了解,增强对Linux内核学习的信心。

也可以在某些专用产品中使用(比如专用的服务器)。为此,我尝试在原来代码的基础上修改制作了一个用网络卡从并口上启动Linux的程序,以博一笑,其中有许多问题值得研究。

2、Linux对启动程序的要求

Linux(bzImage Kernel)对启动程序的要求比较简单,你只要能够建立一个启动头(setup.S),

给出一些信息,然后将kernel(/usr/src/linux/arch/i386/boot/compressed/bvmlinux.out)调到

绝对地址0x100000(1M地址处),如果有initrd,则将它调到内存高端(离0x100000越远越好,比如如果

initrd小于4M,就可以将它调到地址0xB00000,即12M处,相信现在已经很少有少于16M内存的机器了),

然后执行一些初始化操作,跳到内核处就行了。

当然,说起来容易做起来还有点麻烦,以下分几个问题解释。

3、PC机开机流程--启动程序放在何处

PC机加电后,进入实模式,先进行自检,然后初始化各个总线扩展设备(ISA, EISA,PCI,AGP),

全部初始化做完后,从当前启动设备中读一个块(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、网络、磁带机、并口(软件狗上烧个内核和应用程序?)、串口(外接你的设备)、 USB设备(?)、PCI扩展卡、IC卡等等上面来读;各位还有什么意见,提醒提醒。有位老兄说实在不行可以用键盘启动,每次启动时把内核敲进去,还有int 16h支持呢,做起来也不难,应该是最节省的方案了。

反正一个原则是,在启动程序中能够从该设备上读就行了,这里最简单的就是并口了,简单的端口操作,不需 要任何驱动程序支持,不需要BIOS支持,比磁盘还简单(磁盘一般使用int 13h,主要是计算柱面啊、磁头啊、磁道啊、扇区啊好麻烦,幸好有现成的源代码,可以学习学习)。

好了,我们挑个简单的方案,将启动代码(bootsect.S+setup.S)放到网络卡的boot rom中,内核数据和应用数据放到另外一台计算机上,用并口提供。下面谈谈几个相关的问题。

5、将数据移动到绝对地址处

第一个问题,我们得到数据,因为是在实模式下,所以一般是放在1M地址空间内,怎样将它移动到指定的地方去,

在setup.S 的源代码中,使用了int 15h(87h号功能)。这里将该段代码稍加改动,做了些假设,列到下面:

流程是:

if (%cs:move_es==0)/*由于使用前move_es初始化为0,因此这是第一次调用,此时es:bx是要移动的数据

存放处bx=0,es低四为位为零表示es:bx在64K边界上,fs的低8位指定目的地地址,

也以64K字节为单位,用不着那么精确,以简化操作*/

{

将es右移四位,得到64K单位的8位地址(这样一来,最多只能将数据移动到16M以下了),作为源数据

描述符中24位地址的高8位,低16位为零。

将fs的低8位作为目的地的描述符中24位地址的高8位,同样,它的低16位为零。

将es存放在move_es中,es自然不会是零,因此以后再调用该例程时就进行正常的移动操作了。

ax清零返回。

}

else

{

if (bx==0)/*bx为零,表示数据已经满64K了,应该进行实际的移动*/

{

调用int15h 87h号功能,进行实际的数据移动(64K, 0x8000个16字节块)。

目的地址(24位)高8位增一,往后走64K

ax = 1

return;

}

else

{

ax = 0;

return;

}

}

# we will move %cx bytes from es:bx to %fs(64Kbytes 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 return 0 if no data really moved, and return 1 if there is data

# really to be moved

#

movetohigh:

cmpw $0, %cs:move_es

jnz move_second

# at this point , 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 else 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

int $0x15

jc move_panic # this, if INT15 fails

movw %cs:move_es, %es # we reset %es to always point

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:

.byte 0x00, 0x00, 0x01 # base = 0x010000

.byte 0x93 # typbyte

.word 0 # limit16,base24 =0

move_dst:

.word 0xffff

move_dst_base:

.byte 0x00, 0x00, 0x10 # base = 0x100000

.byte 0x93 # typbyte

.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:

.string "INT15 refuses to access high mem, giving up."

6、用并口传输数据

用并口传输数据,可以从/usr/src/linux/driver/net/plip.c中抄一段,我们采用半字节协议,

并口线连接参考该文件。字节收发过程如下:

#define PORT_BASE 0x378

#define data_write(b) outportb(PORT_BASE, b)

#define data_read() inportb(PORT_BASE+1)

#define OK 0

#define TIMEOUT 1

#define FAIL 2

int sendbyte(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();

if ((c0 & 0x80) == 0)

break;

if (--cx == 0)

return TIMEOUT;

}

data_write(0x10 | (data 4));

data_write((data 4));

cx = 32767l * 1024l;

while (1) {

c0 = data_read();

if (c0 & 0x80)

break;

if (--cx == 0)

return TIMEOUT;

}

return OK;

}

int rcvbyte(unsigned char * pByte)

{

unsigned char c0, c1;

unsigned long cx;

cx = 32767l * 1024l;

while (1) {

c0

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有