linux系统setup设置端口,Linux内核之setup.s

1.复位硬盘系统:BIOS的int 13中断,分两步完成;

a.获取磁盘机的类型: AH=15H\DL=0x81;

b.重置磁盘机系统(复位): AH= 00H\DL = 80;

2.检查setup.S代码的末尾签名0xAA55和0x5A5A;

0xAA55和0x5A5A是用来确保正确引导setup.s的两个标志!检查setup代码结尾处的标志是否为AA55或5A5A,!假如是,则跳到good_sig1处;否则,跳到bad_sig处,查找setup.s的剩余部分代码,并且将其移动到内存中0x1000处。

3.检查内核是不是大内核,是的话,检查是不是new loader装入,如不是就系统进入死循环。否则,new loader装入;

4.下面是获取系统的扩展内存情况:

BIOS  INT 15中断:AX = E820获取内存映射,存于E820MAP数组中,位于0x90000:0x2d0-0x600;

AX = E801获取扩展内存的大小,存于0x90000:2处;

5.设置键盘的重复速率为最大:(持续按住按键时,若超过设定时间,键盘会自动以一定速率重复该字符)

BIOS  INT  16中断:AX = 0X0305即可;

6.调用video.S设置视频参数,有关显卡编程的,这一块没有怎么看;

7.把rom bios中硬盘0(第一个硬盘,[4 * 0x41]处)硬盘1(第二个硬盘,[4 * 0x46]处)的参数表,分别拷到0x90000:0080H和0x90000:0090H处,大小都是16 bytes。

8.判断第二块硬盘是否存在,不存在第二个表就清0。

9.检测微通道总线MAC,检测鼠标器,检测APM BIOS,只要调用相应的BIOS中断就可以了;

10.下面就要准备进入保护模式了:下面代码执行后地址就编程32位的了

cmpw      $0, %cs:realmode_swtch

jz      rmodeswtch_normal

lcall%cs:realmode_swtch

jmp rmodeswtch_end

rmodeswtch_normal:

pushw      %cs

call  default_switch  //关中断,包括可屏蔽的和不可屏蔽的中断

11.测试下loadflags是否为LOADED_HIGH,也就是判断是否为big-kernel,不是就移到0x1000处,是的话就原地不动,

12.加载IDT,GDT的位置到IDTRY , GDTR:

gdt:

.word       0, 0, 0, 0                         # dummy

.word       0, 0, 0, 0                         # unused

.word       0xFFFF                               # 4Gb - (0x100000*0x1000 = 4Gb)

.word       0                                       # base address = 0

.word       0x9A00                               # code read/exec

.word       0x00CF                               # granularity = 4096, 386

#  (+5th nibble of limit)

.word       0xFFFF                               # 4Gb - (0x100000*0x1000 = 4Gb)

.word       0                                       # base address = 0

.word       0x9200                               # data read/write

.word       0x00CF                               # granularity = 4096, 386

#  (+5th nibble of limit)

idt_48:

.word       0                                   # idt limit = 0

.word       0, 0                              # idt base = 0L

gdt_48:

.word       0x8000                      # gdt limit=2048,

#  256 GDT entries

.word       0, 0                              # gdt base (filled in later)

lidt  idt_48                                  # load idt with 0,0

xorl %eax, %eax                       # Compute gdt_base

movw      %ds, %ax                           # (Convert %ds:gdt to a linear ptr)

shll  $4, %eax

addl          $gdt, %eax

movl         %eax, (gdt_48+2)

lgdt gdt_48

这个GDT和head.S中的GDT区别只是物理位置的不一样,setip.S中的早0x90200之后的一段空间,而head.S中的放在1M之后的地方。

这里的IDT都是空的,因为我们关中断了,它暂时用不到。

13.开启A20地址线:

call  empty_8042  //测试8042键盘键盘控制器状态寄存器,只输入缓冲器为空时才能够向里面写数据

movb  $0xD1, %al    # command write,表示要写数据到8042的P2端口,P2端口就用来选通A20信号,

outb         %al, $0x64

call  empty_8042

movb       $0xDF, %al                        #选通A20地址线

outb         %  al, $0x60

call  empty_8042     //再测试输入缓冲器,若为空,表示已经选通。

由于键盘控制器速度比较慢,还有另一种方法选通A20,直接使用I/O端口0x92,前提是此端口没有被其他设备使用。

inb   $0x92, %al                        #

orb  $02, %al                    # "fast A20" version

outb %al, $0x92                       # some chips have only this

14.初始化8259控制器:这里只是屏蔽主从片所有的中断请求,其余的初始化在init_IRQ()函数中完成的。

15.下面正式进入保护模式:将CR0第一位置1,即PE置位。

16.接下来就跳到head.S中去继续初始化了:

.byte  0x66,  0xea                                  # prefix + jmpi-opcode

code32:    .long         0x1000                               # will be set to 0x100000

# for big kernels

.word       __KERNEL_CS

这里0x66是操作码前缀的意思,使用后可以使得后面的指针变为48位(16位的选择子,32位的偏移)。

0xea是jumpi的操作码,code32就是要跳转的目的地址

本博文转载于:FinL的博客

///////////////////////////////////////////////////////////////////// //功 能:寻卡 //参数说明: req_code[IN]:寻卡方式 // 0x52 = 寻感应区内所有符合14443A标准的卡 // 0x26 = 寻未进入休眠状态的卡 // pTagType[OUT]:卡片类型代码 // 0x4400 = Mifare_UltraLight // 0x0400 = Mifare_One(S50) // 0x0200 = Mifare_One(S70) // 0x0800 = Mifare_Pro(X) // 0x4403 = Mifare_DESFire //返 回: 成功返回MI_OK ///////////////////////////////////////////////////////////////////// signed char PcdRequest(unsigned char req_code,unsigned char *pTagType) { signed char status; unsigned int unLen; unsigned char ucComMF522Buf[MAXRLEN]; ClearBitMask(Status2Reg,0x08); WriteRawRC(BitFramingReg,0x07); SetBitMask(TxControlReg,0x03); ucComMF522Buf[0] = req_code; status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen;); if ((status == MI_OK) && (unLen == 0x10)) { *pTagType = ucComMF522Buf[0]; *(pTagType+1) = ucComMF522Buf[1]; } else { status = MI_ERR; } return status; } ///////////////////////////////////////////////////////////////////// //功 能:防冲撞 //参数说明: pSnr[OUT]:卡片序列号,4字节 //返 回: 成功返回MI_OK ///////////////////////////////////////////////////////////////////// signed char PcdAnticoll(unsigned char *pSnr) { signed char status; unsigned char i,snr_check=0; unsigned int unLen; unsigned char ucComMF522Buf[MAXRLEN]; ClearBitMask(Status2Reg,0x08); WriteRawRC(BitFramingReg,0x00); ClearBitMask(CollReg,0x80); ucComMF522Buf[0] = PICC_ANTICOLL1; ucComMF522Buf[1] = 0x20; status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen;); if (status == MI_OK) { for (i=0; i<4; i++) { *(pSnr+i) = ucComMF522Buf[i]; snr_check ^= ucComMF522Buf[i]; } if (snr_check != ucComMF522Buf[i]) { status = MI_ERR; } } SetBitMask(CollReg,0x80); return status; } ///////////////////////////////////////////////////////////////////// //功 能:选定卡片 //参数说明: pSnr[IN]:卡片序列号,4字节 //返 回: 成功返回MI_OK ///////////////////////////////////////////////////////////////////// signed char PcdSelect(unsigned char *pSnr) { signed char status; unsigned char i; unsigned int unLen; unsigned char ucComMF522Buf[MAXRLEN]; ucComMF522Buf[0] = PICC_ANTICOLL1; ucComMF522Buf[1] = 0x70; ucComMF522Buf[6] = 0; for (i=0; i<4; i++) { ucComMF522Buf[i+2] = *(pSnr+i); ucComMF522Buf[6] ^= *(pSnr+i); } CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf;[7]); ClearBitMask(Status2Reg,0x08); status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen;); if ((status == MI_OK) && (unLen == 0x18)) { status = MI_OK; } else { status = MI_ERR; } return status; } ///////////////////////////////////////////////////////////////////// //功 能:验证卡片密码 //参数说明: auth_mode[IN]: 密码验证模式 // 0x60 = 验证A密钥 // 0x61 = 验证B密钥 // addr[IN]:块地址 // pKey[IN]:密码 // pSnr[IN]:卡片序列号,4字节 //返 回: 成功返回MI_OK ///////////////////////////////////////////////////////////////////// signed char PcdAuthState(unsigned char auth_mode,unsigned char addr,unsigned char *pKey,unsigned char *pSnr) { signed char status; unsigned int unLen; unsigned char i,ucComMF522Buf[MAXRLEN]; ucComMF522Buf[0] = auth_mode; ucComMF522Buf[1] = addr; for (i=0; i<6; i++) { ucComMF522Buf[i+2] = *(pKey+i); } for (i=0; i<6; i++) { ucComMF522Buf[i+8] = *(pSnr+i); } // memcpy(&ucComMF522Buf;[2], pKey, 6); // memcpy(&ucComMF522Buf;[8], pSnr, 4); status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen;); if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08))) { status = MI_ERR; } return status; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值