分页模式任务切换测试代码

分页模式任务切换测试

该代码,在分页模式下,有两个ring3级的任务,分别输出WYLS两个字串。

程序为两个任务建立了3级的代码段和数据堆栈段,建立了IDT段,只设置了一个页表,只映射了4M内存空间。

内核代码被复制到0x2000h处,0x0——0x1FFF被用来存放pdt和第一个pet,进入内核代码前,已经为内核代码建立过临时代码段和数据堆栈段,大小都是4G的大段。

内核代码首先初始化内核代码的TSS描述符,然后设置时钟中断TSS和其TSS描述符,;设置任务1和任务2的任务状态段、任务描述符、LDT段描述符和任务状态表。然后设置任务状态表,任务状态表包含任务是否可用和任务的时间片,其中内核任务不作为调度对象,所以在时钟中断中始终将内核任务的可用标志位置位不可用。接着去设置IDT表,将所有的中段都指向其中一个中断函数,再设置8h时钟中断,这个是bios设置的,其实我们需要将这个修改,因为在保护模式下这应该为一个异常处理中断,但只要保证这个程序里不犯这样的错误就行了。

最后设置pdtpet,并将pdt的第一个表项u/s位设为1这样,其下的pet的表项才可能被ring3的代码访问,将第三个pet表项u/s射为1,映射到ring3的任务代码页,并将0xb8xxx线性地址映射到0xf0xxx,将0xf0xxx映射到0xb8xxx并将f0项的u/s位设为1,这样任务代码就可以访问显存,显示信息。

在时钟中断代码中,主要是搜索可用的任务,然后修改时钟TSSlink字段,修改相对应的任务状态表,最后转移到可用任务代码里。

目前没有实验的是每一个任务独立4G的空间。

下面是内核代码。

setup.asm

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;Setup.ASM
  3. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  4. ;本代码进行初始化工作和加载些中断
  5. ;中断设为22h
  6. ;输出字符串      输入:ah = 0 DS:SI字符串,0为结束
  7. ;读取文件到指定内存区域 输入:ah = 1 DS:SI文件名,ES:DI目录表内存区域,
  8. ;           输出:DX:BX读入到内存区域
  9. ;                 al: 0eh 文件未找到 0fh找到文件                                         
  10. ;中断设为21h
  11. ;输出各寄存器的值   输出:AX,CX,DX,BX,SP,BP,SI,DI,FLAG
  12. ;50h:0000h-------------------------------
  13. ;              根目录表
  14. ;50h:1c00h-------------------------------
  15. ;          FAT表
  16. ;50h:3300h-------------------------------
  17. ;          Kernel代码区域
  18. bits    16
  19. org 0
  20. jmp main
  21. GDT_DESC
  22.     dw  0x18
  23. gdtaddr dd  0x0
  24. GDT:
  25. NULL:
  26.     dw  0x0,0x0,0x0,0x0
  27. TempCode:
  28.     dw  0xFFFF
  29.     dw  0x0
  30.     dw  0x9A00
  31.     dw  0x00CF
  32. TempDate:
  33.     dw  0xFFFF
  34.     dw  0x0
  35.     dw  0x9200
  36.     dw  0x00CF

  37. main:
  38.     mov ax,cs   ;初始化
  39.     mov ss,ax
  40.     mov sp,07bffh
  41.     xor ax,ax
  42.     mov ds,ax
  43.     mov es,ax
  44. ;-----------------------加载实模式中断
  45.     ;开始加载中断,为了避免段间错误,以后所有代码都有段超越前缀
  46.     ;写入22h中断
  47.     cli
  48.     mov di,22h*4
  49.     mov ax,cs
  50.     mov [ds:di+2],ax    ;向中断向量表写入段值
  51.     mov ax,WYOS_int22h_proc
  52.     mov [ds:di],ax  ;向中断向量表写入偏移
  53.     ;写入21h中断
  54.     mov di,21h*4
  55.     mov ax,cs
  56.     mov [ds:di+2],ax
  57.     mov ax,WYOS_int21h_proc
  58.     mov [ds:di],ax
  59.     sti
  60.     mov ax,cs
  61.     mov ds,ax
  62.     mov si,WYOSMSG
  63.     mov ah,0
  64.     int 22h

  65. ;------------------------读取kernel.bin的代码
  66.     ;读取32位kernel代码到1000h:0000
  67.     mov si,WYOSKNL
  68.     mov ax,50h
  69.     mov es,ax
  70.     mov di,0
  71.     mov ah,1
  72.     mov dx,1000h
  73.     mov bx,0
  74.     int 22h
  75. ;------------------------移动kernel代码到2000h处
  76.     cli 
  77.     cld
  78.     mov ax,0x1000
  79.     mov ds,ax
  80.     mov si,0
  81.     mov     ax,0x200
  82.     mov es,ax
  83.     mov di,0
  84.     mov cx,0x600
  85.     rep movsd


  86. ;------------------------设置GDT伪描述符
  87.     mov ax,cs
  88.     mov ds,ax
  89.     mov bx,16
  90.     mul bx
  91.     add ax,GDT
  92.     adc dx,0
  93.     mov word [gdtaddr],ax
  94.     mov word [gdtaddr+2],dx
  95. ;---------------------------加载GDTR
  96.     mov ax,cs
  97.     mov ds,ax
  98.     lgdt    [GDT_DESC]
  99. ;---------------------------打开A20地址线
  100.     call    Empty_8042
  101.     mov al,0xd1
  102.     out 0x64,al
  103.     call    Empty_8042
  104.     mov al,0xdf
  105.     out 0x64,al
  106.     call    Empty_8042
  107. ;---------------------------设置cr0,进入保护模式
  108.     mov eax,cr0
  109.     or  eax,1
  110.     mov cr0,eax
  111. ;---------------------------设置段选择子,跳转到内核代码中
  112.     mov ax,0x10
  113.     mov ds,ax
  114.     mov es,ax
  115.     mov fs,ax
  116.     mov gs,ax
  117.     mov ss,ax
  118.     mov sp,0xffff

  119.     jmp 0x8:2000h
  120. ;   ;读取setup代码到2000h:0000
  121. ;   mov si,WYOSSTP
  122. ;   mov ax,50h
  123. ;   mov es,ax
  124. ;   mov di,0
  125. ;   mov ah,1
  126. ;   mov dx,2000h
  127. ;   mov bx,0
  128. ;   int 22h
  129. ;   jmp 2000h:0000
  130.     ;加载完成,剩下的就是完成中断函数
  131.     jmp $   ;程序结束
  132. ;----------------------------------21h中断代码区------------------------------   
  133. ;21h中断代码
  134. WYOS_int21h_proc:
  135.     pusha
  136.     push    bx
  137.     push    ax
  138.     mov bx,7
  139.     mov ah,0eh
  140.     mov al,0dh
  141.     int 10h
  142.     mov al,0ah
  143.     int 10h     ;重新换一行
  144.     ;输出ax
  145.     mov al,'A'
  146.     int 10h
  147.     mov al,'X'
  148.     int 10h
  149.     mov al,'='
  150.     int 10h
  151.     pop ax      ;取得ax,先输出ah,再输出al
  152.     push    ax      ;保存ax
  153.     mov al,ah
  154.     call    SHOWALASCII
  155.     pop ax
  156.     call    SHOWALASCII
  157.     mov ah,0eh
  158.     mov al,'h'
  159.     int 10h
  160.     mov al,20h
  161.     int 10h
  162.     ;输出cx
  163.     mov al,'C'
  164.     int 10h
  165.     mov al,'X'
  166.     int 10h
  167.     mov al,'='
  168.     int 10h
  169.     mov al,ch
  170.     call    SHOWALASCII
  171.     mov al,cl
  172.     call    SHOWALASCII
  173.     mov ah,0eh
  174.     mov al,'h'
  175.     int 10h
  176.     mov al,20h
  177.     int 10h
  178.     ;输出DX
  179.     mov al,'D'
  180.     int 10h
  181.     mov al,'X'
  182.     int 10h
  183.     mov al,'='
  184.     int 10h
  185.     mov al,dh
  186.     call    SHOWALASCII
  187.     mov al,dl
  188.     call    SHOWALASCII
  189.     mov ah,0eh
  190.     mov al,'h'
  191.     int 10h
  192.     mov al,20h
  193.     int 10h
  194.     ;输出BX
  195.     mov al,'B'
  196.     int 10h
  197.     mov al,'X'
  198.     int 10h
  199.     mov al,'='
  200.     int 10h
  201.     pop bx  ;取得bx
  202.     mov cx,bx
  203.     mov bx,7
  204.     mov al,ch
  205.     call    SHOWALASCII
  206.     mov al,cl
  207.     call    SHOWALASCII
  208.     mov ah,0eh
  209.     mov al,'h'
  210.     int 10h
  211.     mov al,20h
  212.     int 10h
  213.     ;输出SP
  214.     mov al,'S'
  215.     int 10h
  216.     mov al,'P'
  217.     int 10h
  218.     mov al,'='
  219.     int 10h
  220.     mov cx,sp
  221.     mov al,ch
  222.     call    SHOWALASCII
  223.     mov al,cl
  224.     call    SHOWALASCII
  225.     mov ah,0eh
  226.     mov al,'h'
  227.     int 10h
  228.     mov al,20h
  229.     int 10h
  230.     ;输出BP
  231.     mov al,'B'
  232.     int 10h
  233.     mov al,'P'
  234.     int 10h
  235.     mov al,'='
  236.     int 10h
  237.     mov cx,bp
  238.     mov al,ch
  239.     call    SHOWALASCII
  240.     mov al,cl
  241.     call    SHOWALASCII
  242.     mov ah,0eh
  243.     mov al,'h'
  244.     int 10h
  245.     mov al,20h
  246.     int 10h
  247.     ;输出SI
  248.     mov al,'S'
  249.     int 10h
  250.     mov al,'I'
  251.     int 10h
  252.     mov al,'='
  253.     int 10h
  254.     mov cx,si
  255.     mov al,ch
  256.     call    SHOWALASCII
  257.     mov al,cl
  258.     call    SHOWALASCII
  259.     mov ah,0eh
  260.     mov al,'h'
  261.     int 10h
  262.     mov al,20h
  263.     int 10h
  264.     ;输出DI
  265.     mov al,'D'
  266.     int 10h
  267.     mov al,'I'
  268.     int 10h
  269.     mov al,'='
  270.     int 10h
  271.     mov cx,di
  272.     mov al,ch
  273.     call    SHOWALASCII
  274.     mov al,cl
  275.     call    SHOWALASCII
  276.     mov ah,0eh
  277.     mov al,'h'
  278.     int 10h
  279.     mov al,20h
  280.     int 10h
  281.     ;输出FLAG寄存器
  282.     mov al,0dh
  283.     int 10h
  284.     mov al,0ah
  285.     int 10h     ;重新换一行
  286.     mov al,'F'
  287.     int 10h
  288.     mov al,'L'
  289.     int 10h
  290.     mov al,'A'
  291.     int 10h
  292.     mov al,'G'
  293.     int 10h
  294.     mov al,':'
  295.     int 10h
  296.     call    SHOWFLAG
  297.     mov al,0dh
  298.     int 10h
  299.     mov al,0ah
  300.     int 10h
  301.     ;输出gdtr寄存器
  302.     mov al,'G'
  303.     int 10h
  304.     mov al,'D'
  305.     int 10h
  306.     mov al,'T'
  307.     int 10h
  308.     mov al,'R'
  309.     int 10h
  310.     mov al,':'
  311.     int 10h
  312.     sgdt    [GDT_DESC]
  313.     mov al,byte [gdtaddr+3]
  314.     call    SHOWALASCII
  315.     mov al,byte [gdtaddr+2]
  316.     call    SHOWALASCII
  317.     mov al,byte [gdtaddr+1]
  318.     call    SHOWALASCII
  319.     mov al,byte [gdtaddr]
  320.     call    SHOWALASCII
  321.     mov al,byte [GDT_DESC+1]
  322.     call    SHOWALASCII
  323.     mov al,byte [GDT_DESC]
  324.     call    SHOWALASCII
  325.     
  326.     mov ah,0eh
  327.     mov al,'h'
  328.     int 10h
  329.     mov al,20h
  330.     int 10h
  331.     popa
  332.     iret
  333.     
  334. ;----------------------------------22h中断代码区------------------------------       
  335. WYOS_int22h_proc:
  336.     push    ds
  337. printstr:
  338.     cmp ah,0
  339.     jnz readfile
  340.     call    showmsg
  341.     pop ds
  342.     iret
  343. readfile:
  344.     cmp ah,1
  345.     jz  start
  346.     jmp other
  347.     start:  
  348.     push    cx
  349.     push    bx          
  350.     push    di          ;保存di的基址
  351.     
  352.     pop bx  ;取得di的基址
  353.     push    bx  ;保存di的基址
  354.     add bx,1c00h;计算根目录表的结尾地址

  355.     searchfile:
  356.         cmp BYTE [es:di],0  ;比较目录项第一个字节,如果为0则是到达目录表项尾
  357.         jnz cmpstr      ;不为0,比较文件名
  358.         mov al,0eh      ;未找到文件
  359.         pop di
  360.         pop bx
  361.         pop cx
  362.         iret
  363.     cmpstr:
  364.         push    ax          ;保护环境
  365.         push    si
  366.         push    di
  367.         
  368.         mov cx,11       
  369.         loopnext:
  370.             mov al,[ds:si]  ;比较文件名
  371.             mov ah,[es:di]
  372.             cmp al,ah
  373.             jnz next
  374.             inc di
  375.             inc si
  376.             loop    loopnext
  377.             pop di
  378.             pop si
  379.             pop ax
  380.             jmp loadfile
  381.         next:   
  382.             pop di
  383.             pop si  ;恢复环境
  384.             pop ax
  385.             
  386.             add di,32
  387.             cmp di,bx   ;如果大于等于则没发现文件
  388.             jb  searchfile
  389.             mov al,0eh  ;未发现文件
  390.             pop di
  391.             pop bx
  392.             pop cx
  393.             pop ds
  394.             iret
  395.     loadfile:
  396.         mov ax,[es:di+1ah]  ;获得文件第一个簇号
  397.         pop di
  398.         pop bx
  399.         pop cx
  400.         
  401.         push    ds      ;保存ds
  402.         push    es
  403.         pop ds      ;将簇表内存段传给DS
  404.         push    si      
  405.         push    es
  406.         mov es,dx       ;获得目标段基址
  407.         mov si,bx       ;或的目标段偏移
  408.         push    ax      ;保存簇号
  409.         loadfiletomem:
  410.             call    ReadCluster
  411.             pop ax      ;获得簇号
  412.             add si,200h     ;增加缓存空间
  413.             push    si      ;保存si
  414.             mov si,ax       ;获得簇号在fat表中的位置
  415.             shr si,01h      ;判断是奇簇还是偶簇
  416.             pushf
  417.             add si,ax
  418.             mov ax,[ds:si+1c00h]    
  419.             popf
  420.             jc  gethigh
  421.             and ax,0fffh
  422.             jmp iseof
  423.         gethigh:
  424.             push    cx
  425.             mov cl,4
  426.             shr ax,cl
  427.             pop cx
  428.         iseof:
  429.             cmp ax,0ff8h
  430.             pop si
  431.             jae loadOK
  432.             push    ax
  433.             jmp loadfiletomem
  434.     loadOK:
  435.         pop es
  436.         pop si
  437.         pop ds
  438.         pop ds
  439.         iret
  440. other:  
  441.     pop ds
  442.     iret
  443.     
  444. ;========================================================================== 
  445. ;SHOWAL
  446. ;
  447. ;
  448. ;
  449. ;========================================================================== 
  450. SHOWALASCII:
  451.     push    ax
  452.     push    ax
  453. al_showhigh:
  454.     shr al,4
  455.     add al,30h
  456.     cmp al,39h
  457.     jbe al_showlow
  458.     add al,7
  459.     mov ah,0eh
  460.     int 10h
  461.     jmp al_low
  462. al_showlow:
  463.     mov ah,0eh
  464.     int 10h
  465. al_low: pop ax
  466.     and al,0fh
  467.     add al,30h
  468.     cmp al,39h
  469.     jbe al_endshow
  470.     add al,7
  471.     mov ah,0eh
  472.     int 10h
  473.     jmp al_back
  474. al_endshow:
  475.     mov ah,0eh
  476.     int 10h
  477. al_back:    pop ax
  478.     ret
  479. ;========================================================================== 
  480. ;SHOWFLAG
  481. ;
  482. ;
  483. ;
  484. ;========================================================================== 
  485. SHOWFLAG:
  486.     PUSH    BX
  487.     PUSHF
  488.     POP BX
  489.     PUSHF   
  490.     PUSH    AX
  491.     push    cx
  492.     MOV CX,16
  493. LAST1:
  494.     MOV AL,'0'
  495.     RCL BX,1
  496.     JNC NEXT1
  497.     MOV AL,'1'
  498. NEXT1:  MOV AH,0EH
  499.     INT 10H
  500.     LOOP    LAST1
  501.     MOV AL,'B'
  502.     INT 10H
  503.     POP CX
  504.     POP AX
  505.     POPF
  506.     POP BX
  507.     RET
  508. ;=============================================================================
  509. ;SHOWMSG
  510. ;输出一些字符串
  511. ;入口: DS:SI指向目标字符
  512. ;返回: 空
  513. ;=============================================================================
  514. showmsg:
  515.     push    si
  516.     push    ax
  517.     push    bx
  518.     cld
  519.     mov ah,0eh          
  520.     mov bx,7            ;选用0页面和字符前景色7
  521. nextchar:
  522.     mov al,[si]
  523.     inc si
  524.     or  al,al
  525.     jz  ok
  526.     int 10h
  527.     jmp nextchar
  528. ok:
  529.     pop bx
  530.     pop ax
  531.     pop si
  532.     ret
  533. ;=============================================================================
  534. ;ReadCluster
  535. ;读取指定簇号
  536. ;入口: AX为簇号,ES:SI为缓冲区起始地址
  537. ;返回: 无
  538. ;=============================================================================
  539. ReadCluster:
  540.     dec ax      ;修正簇号,前两个簇号表示的不是数据区域
  541.     dec ax
  542.     add ax,33
  543.     xor dx,dx
  544.     mov cx,1
  545. ;=============================================================================
  546. ;ReadSectors
  547. ;读取指定扇区号,指定数目的连续扇区
  548. ;入口: AX为逻辑扇区号,从零开始。CX为读取的扇区数。ES:SI为缓冲区起始地址
  549. ;返回: 无
  550. ;=============================================================================
  551. ReadSectors:
  552.     pusha
  553.     push    cx
  554.     mov bx,18       ;每磁道的扇区数目,ax % 18 + 1就是物理扇区号,而其商就是含磁头的
  555.                 ;磁道号,
  556.                 ;因为 扇区号 = 磁道数1*磁头数*扇区数+磁头数1*扇区数+扇区数1-1
  557.                 ;那么ax/18的商就是磁道数1*磁头数+磁头数1
  558.                 ;其商再除以磁头数商就是磁道数,而余数就是磁头数
  559.     div bx
  560.     inc dx      ;得到真实的扇区数
  561.     mov cx,dx       ;保存到cx
  562.     xor dx,dx       ;将得到商,再次除以磁头数目得到
  563.     push    cx
  564.     mov cx,2        
  565.     div cx
  566.     pop cx
  567.                 ;AX就是磁道数,dx就是磁头数
  568.     mov ch,al       ;磁道的低8位
  569.     ror ah,2        ;将ah的低二位放到高二位
  570.     or  cl,ah       ;高二位放到cl的高二位
  571.     mov dh,dl       ;将磁头号送入dh
  572.     mov dl,0        ;驱动器号
  573.     pop ax      ;获得读取扇区数目
  574.     mov ah,2
  575.     mov bx,si
  576.     int 13h
  577.     popa
  578.     ret
  579. ;=============================================================================
  580. ;Empty_8042
  581. ;等待键盘控制器闲
  582. ;入口: 无
  583. ;返回: 无
  584. ;=============================================================================
  585. Empty_8042:
  586.     in  al,0x64
  587.     test    al,0x2
  588.     jnz Empty_8042
  589.     ret
  590. ;------------------------数据区域---------------------------------------------
  591. WYOSMSG     db  'Kernel Run',0dh,0ah,0
  592. WYOSERR     db  'File not found',0dh,0ah,0
  593. WYOSKNL     db  'KERNEL  BIN',0
  594. ;WYOSKNL        db  'MAIN    BIN',0

  595. times   2048-($-$$) db 0

kernel.asm

  1. ;定义一些段和描述符中字段的偏移

  2. ;任务状态段各字段偏移

  3. tss_link    equ  0H

  4. tss_esp0    equ  4H

  5. tss_ss0     equ  8H

  6. tss_esp1    equ  0CH

  7. tss_ss1     equ  10H

  8. tss_esp2    equ  14H

  9. tss_ss2     equ  18H

  10. tss_cr3     equ  1CH

  11. tss_eip     equ  20H

  12. tss_eflags  equ  24H

  13. tss_eax     equ  28H

  14. tss_ecx     equ  2CH

  15. tss_edx     equ  30H

  16. tss_ebx     equ  34H

  17. tss_esp     equ  38H

  18. tss_ebp     equ  3CH

  19. tss_esi     equ  40H

  20. tss_edi     equ  44H

  21. tss_es      equ  48H

  22. tss_cs      equ  4CH

  23. tss_ss      equ  50H

  24. tss_ds      equ  54H

  25. tss_fs      equ  58H

  26. tss_gs      equ  5CH

  27. tss_ld      equ  60H

  28. tss_IO      equ  66H





  29. bits    32

  30. org     2000h

  31. jmp  main

  32. gdt_desc:

  33. dw       0x820

  34. gdtaddr       dd    gdt

  35. ;=========================

  36. gdt:

  37. NULL:

  38. dw       0x0,0x0,0x0,0x0

  39. SystemCode:

  40. dw       0xFFFF

  41. dw       0x0

  42. dw       0x9A00

  43. dw       0x00CF

  44. SystemData:

  45. dw       0xFFFF

  46. dw       0x0

  47. dw       0x9200

  48. dw       0x00CF

  49. CLKTaskDesc:                ;时钟任务描述符表

  50.                             dw       0x69

  51.                             dw       0x0

  52.                             dw       0x8900

  53.                             dw       0x0080

  54. UserSpace:

  55. user times       0x800 db 0       ;留给用户进程的全局描述符,模式采用类似于linux的设置,

  56. ;ldt0,tss0,ldt1,tss1如此类推,总共可以支持128个用户任务

  57. ;=========================    ;中断描述符表伪描述符

  58. idt_desc:

  59. dw       0x800

  60. idtaddr       dd    idt

  61. ;=========================    ;中断描述符表

  62. idt:

  63. times       0x800 db 0

  64. ;=========================

  65. CLKTask:                     ;时钟任务状态段

  66.                              times      102 db 0

  67.                              dw         $+2         ;I/O许可位图偏移

  68.                              db         0xFF              ;I/O许可位图结束字节









  69. KernelTask:                     ;内核任务状态段

  70.                                 times   102 db 0

  71.                                 dw      $+2

  72.                                 db      0xFF              ;I/O许可位图结束字节





  73. TestTask1:                     ;Task1的任务状态段

  74.                                times    102 db 0

  75.                                dw       $+2

  76.                                db       0xFF





  77. TestTask2:                     ;Task2的任务状态段。

  78.                                times    102 db 0

  79.                                dw       $+2

  80.                                db       0xFF





  81. LDT1:                          ;Task1的局部描述符表

  82. Task1KnlStack:

  83. dw       0xFFFF

  84. dw       0x0

  85. dw       0x9200

  86. dw       0x00CF

  87. Task1CodeSeg:

  88. dw       0xFFFF

  89. dw       0x0

  90. dw       0xFA00

  91. dw       0x00CF

  92. Task1DataSeg:

  93. dw       0xFFFF

  94. dw       0x0

  95. dw       0xF200

  96. dw       0x00CF





  97. LDT2:                          ;Task2的局部描述符表

  98. Task2KnlStack:

  99. dw       0xFFFF

  100. dw       0x0

  101. dw       0x9200

  102. dw       0x00CF

  103. Task2CodeSeg:

  104. dw       0xFFFF

  105. dw       0x0

  106. dw       0xFA00

  107. dw       0x00CF

  108. Task2DataSeg:

  109. dw       0xFFFF

  110. dw       0x0

  111. dw       0xF200

  112. dw       0x00CF





  113. ;===========任务状态表

  114. task_status     equ  0h

  115. task_cpu_time   equ  1h

  116. task_link       equ  2h

  117. TaskStatusTable:

  118. Task0:

  119. db  1

  120. db  0

  121. dw  0

  122. Task1:

  123. db  1

  124. db  0

  125. dw  0

  126. Task2:

  127. db  0

  128. db  0

  129. dw  0

  130. ;===============代码开始处

  131. main:

  132. mov       ax,0x10          ;虽然setup程序已经设置过段寄存器,为了程序的正常运行,还是重新设置下

  133. mov       ds,ax





  134. xor       esi,esi

  135. xor       edi,edi

  136. mov       esp,0xA0000

  137. xor       ebp,ebp





  138. ;设置内核TSS描述符

  139. mov       esi,UserSpace+8         ;获得内核TSSDESC的地址

  140. mov       eax,KernelTask          ;内核TSS的地址->eax

  141. mov       word [esi+2],ax         ;设置base addr的低16位

  142. shr       eax,16                  ;将高16位送入到ax

  143. mov       byte [esi+4],al         ;设置base addr中间8位

  144. mov       byte [esi+7],ah         ;设置base addr高8位

  145. mov       word [esi],0x69         ;设置TSS的大小        

  146. mov       byte [esi+5],0x89       ;设置描述符的类型和访问权限        

  147. mov       byte [esi+6],0x80       ;设置段粒度和其他属性

  148. ;设置时钟TSS

  149. mov       esi,CLKTask

  150. mov       dword [esi+tss_cr3],0

  151. mov       dword [esi+tss_eip],WYOS_clock_task

  152. mov       dword [esi+tss_eflags],0x202

  153. mov       word [esi+tss_es],0x10

  154. mov       word [esi+tss_cs],0x8

  155. mov       word [esi+tss_ds],0x10

  156. mov       word [esi+tss_fs],0x10

  157. mov       word [esi+tss_gs],0x10

  158. mov       word [esi+tss_ss],0x10

  159. mov       dword [esi+tss_esp],0xa0000









  160. ;设置时钟任务状态段描述符

  161. mov       eax,CLKTask

  162. mov       word [CLKTaskDesc+2],ax

  163. shr       eax,16

  164. mov       byte [CLKTaskDesc+4],al

  165. mov       byte [CLKTaskDesc+7],ah



  166. ;设置任务1和任务2的任务状态段、任务描述符、LDT段描述符和任务状态表

  167. ;Task1 TSS

  168. mov       esi,TestTask1

  169. mov       word [esi+tss_ss0],0x4

  170. mov       dword [esi+tss_esp0],0x80000

  171. mov       dword [esi+tss_cr3],0

  172. mov       word [esi+tss_ldt],0x30

  173. mov       dword [esi+tss_eip],Task1Code

  174. mov       dword [esi+tss_eflags],0x202

  175. mov       word [esi+tss_es],0x17

  176. mov       word [esi+tss_cs],0xf

  177. mov       word [esi+tss_ds],0x17

  178. mov       word [esi+tss_fs],0x17

  179. mov       word [esi+tss_gs],0x17

  180. mov       word [esi+tss_ss],0x17

  181. mov       dword [esi+tss_esp],0x90000



  182. ;TSS DESC

  183. mov       esi,UserSpace+3*8

  184. mov       eax,TestTask1

  185. mov       word [esi+2],ax

  186. shr       eax,16

  187. mov       byte [esi+4],al

  188. mov       byte [esi+7],ah

  189. mov       word [esi],0x69

  190. mov       byte [esi+5],0x89

  191. mov       byte [esi+6],0x0



  192. ;LDT DESC

  193. mov       esi,UserSpace+2*8

  194. mov       eax,0x18

  195. mov       word [esi],ax

  196. mov       eax,LDT1

  197. mov       word [esi+2],ax

  198. shr       eax,16

  199. mov       byte [esi+4],al

  200. mov       byte [esi+7],ah

  201. mov       byte [esi+5],0x82

  202. mov       byte [esi+6],0x0



  203. ;Task2

  204. ;Task2 TSS

  205. mov       esi,TestTask2

  206. mov       word [esi+tss_ss0],0x4

  207. mov       dword [esi+tss_esp0],0x80000

  208. mov       dword [esi+tss_cr3],0

  209. mov       word [esi+tss_ldt],0x40

  210. mov       dword [esi+tss_eip],Task2Code

  211. mov       dword [esi+tss_eflags],0x202

  212. mov       word [esi+tss_es],0x17

  213. mov       word [esi+tss_cs],0xf

  214. mov       word [esi+tss_ds],0x17

  215. mov       word [esi+tss_fs],0x17

  216. mov       word [esi+tss_gs],0x17

  217. mov       word [esi+tss_ss],0x17

  218. mov       dword [esi+tss_esp],0x90000



  219. ;TSS DESC

  220. mov       esi,UserSpace+5*8

  221. mov       eax,TestTask2

  222. mov       word [esi+2],ax

  223. shr       eax,16

  224. mov       byte [esi+4],al

  225. mov       byte [esi+7],ah

  226. mov       word [esi],0x69

  227. mov       byte [esi+5],0x89

  228. mov       byte [esi+6],0x0





  229. ;LDT DESC

  230. mov       esi,UserSpace+4*8

  231. mov       eax,0x18

  232. mov       word [esi],ax

  233. mov       eax,LDT2

  234. mov       word [esi+2],ax

  235. shr       eax,16

  236. mov       byte [esi+4],al

  237. mov       byte [esi+7],ah

  238. mov       byte [esi+5],0x82

  239. mov        byte [esi+6],0x0

  240. ;TaskStatus

  241. mov       esi,TaskStatusTable

  242. mov       byte [esi+task_status],1

  243. mov       byte [esi+task_cpu_time],0

  244. mov       word [esi+task_link],0x28

  245. add       esi,4

  246. mov       byte [esi+task_status],0

  247. mov       byte [esi+task_cpu_time],5

  248. mov       word [esi+task_link],0x38

  249. add       esi,4

  250. mov       byte [esi+task_status],0

  251. mov       byte [esi+task_cpu_time],5

  252. mov       word [esi+task_link],0x48





  253. ;设置IDT中的时钟中断任务们描述符,暂定为8H,

  254. mov       esi,idt

  255. mov       ecx,256                        

  256. SetIdtItem:              

  257. mov       eax,WYOS_default_interrupt

  258. mov       word [esi],ax

  259. mov       word [esi+2],0x8

  260. mov       byte [esi+5],0x8E

  261. shr       ax,16

  262. mov       word [esi+6],ax

  263. add       esi,8

  264. loop      SetIdtItem





  265. mov       esi,idt 

  266. mov       word [esi+(8H*8+2)],0x18       ;填写8H中断

  267. mov       byte [esi+(8H*8+5)],0x85



  268. lgdt      [gdt_desc]

  269. lidt      [idt_desc]

  270. mov       ax,0x28

  271. ltr       ax





  272. jmp       clear

  273. clear:       ;跳转一下清除高速缓冲寄存器

  274.              ;       sti 



  275.              ;setpage:        ;设置页目录表和第一个页表,先映射4M内存

  276. setpdt:

  277. mov     ax,0x10

  278. mov     es,ax

  279. xor     edi,edi

  280. mov     eax,0

  281. mov     ecx,0x400

  282. rep     stosd

  283. ;设置第一个页目录表项

  284. xor     edi,edi

  285. mov     eax,0x1007

  286. stosd

  287. setpet:

  288. mov     edi,0x1000

  289. mov     ecx,0x400

  290. mov     eax,3

  291. setpetvalue:

  292. stosd

  293. add     eax,0x1000

  294. loop    setpetvalue

  295. ;设置显示寄存器的虚拟地址为0xf0xxx而0xb8000则指向物理0xf0xxx这一块区间

  296. mov     edi,0x1000

  297. mov     dword [edi+0x3*4],0x3007

  298. mov     dword [edi+0xb8*4],0xf0003

  299. mov     dword [edi+0xf0*4],0xb8007

  300. ;设置完成进入保护模式

  301. mov     eax,0

  302. mov     cr3,eax

  303. mov     eax,cr0

  304. or      eax,0x80000000

  305. mov     cr0,eax

  306. jmp     clear_pregetinstruction

  307. clear_pregetinstruction:

  308. mov     byte [0xf0004],'P'

  309. mov     byte [0xf0006],'A'

  310. mov     byte [0xf0008],'G'

  311. mov     byte [0xf000a],'I'

  312. mov     byte [0xf000c],'N'

  313. mov     byte [0xf000e],'G'

  314. sti                                

  315. die:  jmp  $

  316.       jmp       die

  317. WYOS_default_interrupt:

  318. push       eax

  319. pushf

  320. mov       al,[WYOS_interrupt_string]

  321. mov       byte [0xf0002],al

  322. cmp       al,0xFF

  323. jb       save

  324. reset:

  325. mov      al,0

  326. save:

  327. inc      al

  328. mov      byte [WYOS_interrupt_string],al

  329. mov      al , 0x20

  330. out      0x20 , al

  331. out      0xa0 , al

  332. popf

  333. pop      eax

  334. iret



  335. WYOS_clock_task:

  336. push       eax

  337. push       edx

  338. push       esi

  339. push       edi

  340. ;获得正在运行的任务的任务门选择子

  341. mov       esi,CLKTask

  342. mov       ax,word [esi+tss_link]

  343. ;通过任务门选择子获得正在运行的任务TID

  344. shr       ax,3

  345. sub       ax,5

  346. shr       ax,1

  347. or        ax,ax

  348. jnz       CheckCpuTime         ;如果不是0号任务则检查当前任务的剩余时间片

  349. ;             ;设置返回任务的TID

  350. mov eax,0              

  351. CheckCpuTime:       ;eax包含指向当前的任务的TID

  352.                     mov     edx,eax   ;将TID保存到edx中

  353.                     shl     eax,2

  354.                     mov     esi,TaskStatusTable

  355.                     add     esi,eax

  356.                     mov al,byte [esi+task_cpu_time]

  357. or       al,al

  358. jnz      SetCpuTime      ;如果剩余时间片不为0,则继续运行该任务

  359. ;剩余时间片为0,则寻找一个可用的任务,并将当前任务设为可用

  360. mov      ecx,2

  361. push     esi          ;保存当前任务的状态表的指针

  362. mov      esi,TaskStatusTable

  363. search:

  364. mov      al,byte [esi+task_status]

  365. or       al,al

  366. jz       find

  367. add      esi,4

  368. loop     search

  369. find:

  370. mov      eax,esi     ;先将找到的任务的状态表的指针保存到eax,因为要修改以前的任务为可用

  371. pop      esi

  372. or       edx,edx   ;如果是0号任务,则不置为可用

  373. jz       SetTaskStatus

  374. mov      byte [esi+task_status],0

  375. SetTaskStatus:

  376. mov      esi,eax

  377. mov      byte [esi+task_status],1    ;设找到的可用任务为不可用

  378. mov      byte [esi+task_cpu_time],6      ;设为6这是因为下面的SetCpuTime会自动将任务的时间片去1

  379. SetReturnTSSSel:     ;设置返回的任务门选择子

  380.                      mov       edi,CLKTask

  381.                      mov       ax,word [esi+task_link]

  382. mov      word [edi+tss_link],ax

  383. ;将目标任务设为忙

  384. mov      edx,2

  385. sub      edx,ecx

  386. shl      edx,1

  387. add      edx,5

  388. shl      edx,3

  389. mov      edi,gdt

  390. add      edi,edx

  391. mov      edx,[edi+5]

  392. or       edx,0x2

  393. mov      [edi+5],edx

  394. SetCpuTime:     ;esi中包含可用的任务的状态表指针

  395.                 mov al,byte [esi+task_cpu_time]

  396. dec      al

  397. mov      byte [esi+task_cpu_time],al

  398. CLKTaskEnd:

  399. pop     edi

  400. pop     esi

  401. pop     edx

  402. pop     eax

  403. mov     al , 0x20

  404. out     0x20 , al

  405. out     0xa0 , al

  406. iret

  407. jmp     WYOS_clock_task





  408. WYOS_clock_task_delay:

  409. ret

  410. ;============Task1 Code============

  411. Task1Code:

  412. mov      esi,dword [WYOS_cursor_position]

  413. cmp      esi,0xf0fff

  414. jc       Task1Show

  415. mov      esi,0xf0000





  416. Task1Show:

  417. mov      ecx,0xFFFF

  418. Task1_delay:

  419. loop     Task1_delay

  420. mov byte [esi],'W'

  421. inc      esi

  422. inc      esi

  423. mov      dword [WYOS_cursor_position],esi

  424. mov      byte [esi],'Y'

  425. inc      esi

  426. inc      esi

  427. mov dword [WYOS_cursor_position],esi





  428. jmp       Task1Code

  429. ;============Task2 Code============

  430. Task2Code:

  431. mov      esi,dword [WYOS_cursor_position]

  432. cmp      esi,0xf0fff

  433. jc       Task2Show

  434. mov      esi,0xf0000







  435. Task2Show:

  436. mov      ecx,0xFFFF

  437. Task2_delay:

  438. loop     Task2_delay     

  439. mov      byte [esi],'L'

  440. inc      esi

  441. inc      esi

  442. mov      dword [WYOS_cursor_position],esi

  443. mov      byte [esi],'S'

  444. inc      esi

  445. inc      esi

  446. mov      dword [WYOS_cursor_position],esi





  447. jmp      Task2Code

  448. ;==================

  449. ;其它数据

  450. WYOS_font_character     db    'Y'

  451. WYOS_interrupt_string   db    0

  452. WYOS_cursor_position    dd       0xf0000

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值