现在的位置: 首页 > 综合 > 正文

哈工大操作系统试验1 操作系统的引导

2014年02月13日 ⁄ 综合 ⁄ 共 5297字 ⁄ 字号 评论关闭

这次实验涉及一些汇编知识,不过指导书上写的还是比较清楚的,抄一抄上面的代码,基本就ok了。

实验主要需要改3个文件

build.c           只要吧文件末尾稍微改成这样

if ((id=open(argv[3],O_RDONLY,0)) >= 0)                                        //就是打开文件的一个函数,失败的话会返回-1哦~
	{for (i=0 ; (c=read(id,buf,sizeof buf))>0 ; i+=c )
		if (write(1,buf,c)!=c)
			die("Write call failed");
	close(id);
	fprintf(stderr,"System is %d bytes.\n",i);
	if (i > SYS_SIZE*16)
		die("System is too big");}
	return(0);

build.c       原来是这样的

if ((id=open(argv[3],O_RDONLY,0))<0)
		die("Unable to open 'system'");
//	if (read(id,buf,GCC_HEADER) != GCC_HEADER)
//		die("Unable to read header of 'system'");
//	if (((long *) buf)[5] != 0)
//		die("Non-GCC header of 'system'");
	for (i=0 ; (c=read(id,buf,sizeof buf))>0 ; i+=c )
		if (write(1,buf,c)!=c)
			die("Write call failed");
	close(id);
	fprintf(stderr,"System is %d bytes.\n",i);
	if (i > SYS_SIZE*16)
		die("System is too big");
	return(0);

bootsect.s  基本不用过动,如果觉得无聊可以改一改输出的那个字符串。

msg1:
	.byte 13,10                    !这个好像是伪指令   byte和ascii是两种数据的表示方法
	.ascii "fuck..."
	.byte 13,10,13,10

主要需要改动的是setup这个文件。

首先解释一下,输出一条字符串的代码。

!print the message
 
              MOV       AX,#SETUPSEG
              MOV       ES,AX                          !赋值给ES不能直接赋值,需要用AX做中转
              MOV       AH,#0X03                       !下三行为读入光标位置
              XOR       BH,BH                           
              INT       0X10

              MOV       CX,#25                         !字符串长度,设大一点没关系~
              MOV       BX,#0X0007
              MOV       BP,#MSG2
              MOV       AX,#0X1301
              INT       0X10

ES 和 BP 分别是段寄存器和,偏移地址,把ES设#SETUPSEG是内存中存放setup.s开始的地方,BP表示存放#MSG2的偏移地

一般的ES BP 作为附加数据段寄存器,程序中有多个数据段时,经常用到,处理字符串时,也经常会用的哦~

INT 0x10 是BOIS 的视频中断,所有与显示有管的调用都需要通过该中断实现。

AL -- 需要显示的ASCII字符

BH -- 页号(本次实验中一直设为0x00就可以啦)

BL -- 文本属性(设成0x07就好啦)通修改它可以选择不同的字体颜色偶~

把它加在setup的开头,就好啦~就像这样。。。

! NOTE! These had better be the same as in bootsect.s!

    !宏的设置
     INITSEG  =         0X9000	! WE MOVE BOOT HERE - OUT OF THE WAY              
      SYSSEG  =         0X1000	! SYSTEM LOADED AT 0X10000 (65536).
    SETUPSEG  =         0X9020	! THIS IS THE CURRENT SEGMENT
!伪指令globl的意思为后面的标识符都是全局的,即使不使用也会强制引入。
.globl begtext, begdata, begbss, endtext, enddata, endbss
.text       !文本段
    begtext:
.DATA        !数据段
    begdata:
.bss         !未初始化的数据段
     begbss:
.text

entry start
      start:

!print the message
 
              MOV       AX,#SETUPSEG   
              MOV       ES,AX
              MOV       AH,#0X03
              XOR       BH,BH
              INT       0X10

              MOV       CX,#25
              MOV       BX,#0X0007
              MOV       BP,#MSG_HELLOW
              MOV       AX,#0X1301
              INT       0X10

当然不要忘了在最后加上叫做MSG2的数据段,关于为啥要这样写,我也不知道,反正课件就是这样写的,可以去问问老师。。。。。

MSG_HELLOW:
        .byte 13,10
	.ascii "Now we are in SETUP"
	.byte 13,10,13,10

获取系统数据的代码,老师已经写好了,突然觉得老师好牛逼啊~留下获取数据的代码,把下面没用的删掉就好啦~

具体怎么删,请自己斟酌哦~

不删的话系统可能会不断重启噢~

最后需要吧数据输出就好拉~

! print the cursor position
  
	      mov	ah,#0x03		! read cursor pos
	      xor       bh,bh
	      int       0x10
	
              MOV       CX,#25
              mov       bx,#0x0007      ! page 0, attribute 7 (normal)
              MOV       BP,#MSG3
              MOV       AX,#0X1301		! WRITE STRING, MOVE CURSOR
              INT       0X10
			
              MOV       AX,#INITSEG
              MOV       DS,AX   !SET THE DATA SEG ADDRESS, EVEN IT HAS BEEN SET.
     ! get data		 	  
              MOV       CX,#4
              MOV       DX,[0]
     PRINT_DIGIT1:             !print the data
              ROL       DX,#4
              MOV       AX,#0XE0F
              AND       AL,DL
              ADD       AL,#0X30
              CMP       AL,#0X3A
              JL        OUTP1
              ADD       AL, #0X07
       OUTP1:
              INT       0X10
              LOOP      PRINT_DIGIT1
			  
              ! MOV       AX,#SETUPSEG
              ! MOV       DS,AX
              ! MOV       ES,AX

一开始是输出描述性的字符串,PRINT_DIGITL是输出内存中的数据

ROL是左位移,

ROL DX,#4 是把DX的低四位移到高四位上。

CMP 是比较指令 类似于if

jl是一个条件转移指令,jump less 小于转跳,用于有符号转跳

类似还有 jg , jump large

ja  jump above  , jb   jump below  这两个是用于无符号数比较的。

 

其他指导书上有详细注释

不要忘记在末尾加上这个

MSG_CURSOR:
	.byte 13,10
	.ascii "the cursor position is:"
      
MSG_MEMORY:
        .byte 13,10
        .ascii "the size of the extended memory is:"

这样既本就完成啦~

setup的完整代码如下

!
!	setup.s		(C) 1991 Linus Torvalds
!
! setup.s is responsible for getting the system data from the BIOS,
           !  AND       PUTTING THEM INTO THE APPROPRIATE PLACES IN SYSTEM MEMORY.
! both setup.s and system has been loaded by the bootblock.
!
! This code asks the bios for memory/disk/other parameters, and
! puts them in a "safe" place: 0x90000-0x901FF, ie where the
! boot-block used to be. It is then up to the protected mode
! system to read them from there before the area is overwritten
           !  FOR       BUFFER-BLOCKS.
!

! NOTE! These had better be the same as in bootsect.s!

     INITSEG  =         0X9000	! WE MOVE BOOT HERE - OUT OF THE WAY
      SYSSEG  =         0X1000	! SYSTEM LOADED AT 0X10000 (65536).
    SETUPSEG  =         0X9020	! THIS IS THE CURRENT SEGMENT

.globl begtext, begdata, begbss, endtext, enddata, endbss
.text
    begtext:
.DATA
    begdata:
.bss
     begbss:
.text

entry start
      start:

!print the message which wing edit
 
              MOV       AX,#SETUPSEG
              MOV       ES,AX
              MOV       AH,#0X03
              XOR       BH,BH
              INT       0X10

              MOV       CX,#25
              MOV       BX,#0X0007
              MOV       BP,#MSG_HELLOW
              MOV       AX,#0X1301
              INT       0X10


! ok, the read went well so we get current cursor position and save it for
! posterity.

              MOV       AX,#INITSEG	! THIS IS DONE IN BOOTSECT ALREADY, BUT...
              MOV       DS,AX
              MOV       AH,#0X03	! READ CURSOR POS
              XOR       BH,BH
              INT       0X10		! SAVE IT IN KNOWN PLACE, CON_INIT FETCHES
              MOV       [0],DX		! IT FROM 0X90000.

! Get memory size (extended mem, kB)

              MOV       AH,#0X88
              INT       0X15
              MOV       [2],AX

! Get video-card data:

              MOV       AH,#0X0F
              INT       0X10
              MOV       [4],BX		! BH = DISPLAY PAGE
              MOV       [6],AX		! AL = VIDEO MODE, AH = WINDOW WIDTH
	      
! check for EGA/VGA and some config parameters

              MOV       AH,#0X12
              MOV       BL,#0X10
              INT       0X10
              MOV       [8],AX
              MOV       [10],BX
              MOV       [12],CX

 		
! Get hd0 data

              MOV       AX,#0X0000
              MOV       DS,AX
              LDS       SI,[4*0X41]
              MOV       AX,#INITSEG
              MOV       ES,AX
              MOV       DI,#0X0080
              MOV       CX,#0X10
              REP
              MOVSB

! Get hd1 data

              MOV       AX,#0X0000
              MOV       DS,AX
              LDS       SI,[4*0X46]
              MOV       AX,#INITSEG
              MOV       ES,AX
              MOV       DI,#0X0090
              MOV       CX,#0X10
              REP
              MOVSB

              MOV       AX,#SETUPSEG
              MOV       DS,AX
              MOV       ES,AX

! print some datas about the hardware:
! print the cursor position
  
	      mov	ah,#0x03		! read cursor pos
	      xor       bh,bh
	      int       0x10
	
              MOV       CX,#25
              mov       bx,#0x0007      ! page 0, attribute 7 (normal)
              MOV       BP,#MSG_CURSOR
              MOV       AX,#0X1301		! WRITE STRING, MOVE CURSOR
              INT       0X10
			
              MOV       AX,#INITSEG
              MOV       DS,AX   !SET THE DATA SEG ADDRESS, EVEN IT HAS BEEN SET.
			 	  
              MOV       CX,#4
              MOV       DX,[0]
     PRINT_DIGIT1:             !print the data
              ROL       DX,#4
              MOV       AX,#0XE0F
              AND       AL,DL
              ADD       AL,#0X30
              CMP       AL,#0X3A
              JL        OUTP1
              ADD       AL, #0X07
       OUTP1:
              INT       0X10
              LOOP      PRINT_DIGIT1
			  
              ! MOV       AX,#SETUPSEG
              ! MOV       DS,AX
              ! MOV       ES,AX
			  
!print size of the extended memory:

              mov	ah,#0x03		! read cursor pos
	      xor       bh,bh
	      int       0x10
		   
              MOV       CX,#37
              mov	bx,#0x0007      ! page 0, attribute 7 (normal)
              MOV       BP,#MSG_MEMORY
              MOV       AX,#0X1301		! WRITE STRING, MOVE CURSOR
			  
              INT       0X10
	      MOV       AX,#INITSEG
              MOV       DS,AX   !SET THE DATA SEG ADDRESS, EVEN IT HAS BEEN SET.
			 	  
              MOV       CX,#4
              MOV       DX,[2]
            PRINT_DIGIT2:
              ROL       DX,#4
              MOV       AX,#0XE0F
              AND       AL,DL
              ADD       AL,#0X30
              CMP       AL,#0X3A
              JL        OUTP2
              ADD       AL, #0X07
       OUTP2:
              INT       0X10
              LOOP      PRINT_DIGIT2	
			  
! change the line:
  
print_nl:    
			  mov       ax,#0xe0d
			  int       0x10
			  mov       al,#0xa
			  int       0x10
 

MSG_HELLOW:
        .byte 13,10
	.ascii "We are in setup ou Qin~"
	.byte 13,10,13,10
   
MSG_CURSOR:
	.byte 13,10
	.ascii "the cursor position is:"
      
MSG_MEMORY:
        .byte 13,10
        .ascii "the size of the extended memory is:"
	
.text
    endtext:
.DATA
   enddata:
.bss
     endbss:

抱歉!评论已关闭.