显示硬盘信息【上】

     流水账如下:

    1,建立各进程的pid的宏,方便阅读。

    proc.h中添加:

Code:
  1. /* 各进程的进程号 */  
  2. #define PROC_A_PID          0   
  3. #define PROC_B_PID          1   
  4. #define PROC_C_PID          2   
  5. #define PROC_TTY_PID        3   
  6. #define PROC_MSG_PID        4   
  7. #define PROC_FS_PID         5   
  8. #define PROC_HD_PID         6  

    2,建立一个用户级的文件系统进程,暂时只干一件事儿,就是向处理硬盘驱动消息的系统进程发一个消息,表示要打印硬盘的有关信息,然后死循环。添加一个进程的步骤这里就不赘述了,以下同略。

     kernel/fs.c

Code:
  1. /*   
  2.     By Marcus Xing  
  3.     kernel/fs.c  
  4.     与文件系统有关的代码  
  5. */  
  6.   
  7. #include "type.h"   
  8. #include "const.h"   
  9. #include "console.h"   
  10. #include "tty.h"   
  11. #include "protect.h"   
  12. #include "proc.h"   
  13. #include "ipc.h"   
  14. #include "proto.h"   
  15.   
  16. /*--------------------------------------------------------------Proc_File_System  
  17.     文件系统进程的执行体  
  18. */  
  19. void Proc_File_System()   
  20. {   
  21.     Message m;   
  22.     m.msg_type = HD_INFO;   
  23.     Send_Receive_Shell(BOTH,PROC_HD_PID,&m);   
  24.     Milli_Delay(3000);   
  25.     Send_Receive_Shell(BOTH,PROC_HD_PID,&m);   
  26.        
  27.     Printf("PROC FS LOOP/n");   
  28.     while(1);   
  29. }   

     其中用到的HD_INFO宏在const.h中定义:

     const.h

Code:
  1. #define HD_INFO                     1           /* 显示硬盘信息的功能号 */  

     3,建立一个系统进程,专门用来接收发送与硬盘有关的消息,在这里接收FS进程发送的消息,显示有关的硬盘信息。细节都写在注释里了。在hd.c中添加:

     hd.c

Code:
  1. /*----------------------------------------------------------------Init_Hard_Disk  
  2.     初始化硬盘驱动  
  3.     显示硬盘个数,打开硬盘中断  
  4. */  
  5. void Init_Hard_Disk()   
  6. {   
  7.     u8 *hd_num = (u8*)0x475;    /* BIOS会在0x475地址处写入硬盘数 */  
  8.     /* 显示之 */  
  9.     Disp_Color_Str("Driver Num is ",Make_Color(RED,BLACK));   
  10.     Disp_Int(*hd_num);   
  11.     Disp_Str("/n");   
  12.        
  13.     /* 设置发生硬盘中断的处理函数 */  
  14.     IRQ_Handler_Table[AT_WINI_IRQ] = Hard_Disk_Handler;   
  15.        
  16.     /* 由于硬盘中断在从片,所以必须先打开级联中断 */  
  17.     Enable_IRQ(CASCADE_IRQ);   
  18.     Enable_IRQ(AT_WINI_IRQ);   
  19. }   
  20.   
  21. /*----------------------------------------------------------------Proc_Hard_Disk  
  22.     硬盘驱动程序进程,以消息为接口  
  23. */  
  24. void Proc_Hard_Disk()   
  25. {   
  26.     Message m;   
  27.     while(1)   
  28.     {   
  29.         Send_Receive_Shell(RECEIVE,ANY,&m);   
  30.         int src = m.src_proc_pid;   
  31.         switch(m.msg_type)   
  32.         {   
  33.             case HD_INFO:   
  34.                 //Printf("HD_INFO MESSAGE RECEIVED!");   
  35.                 Disp_HD_Info();   
  36.                 break;   
  37.                    
  38.             default:   
  39.                 Panic("hd.c:UNKNOWN MESSAGE TYPE");   
  40.                 break;   
  41.         }   
  42.         Send_Receive_Shell(SEND,src,&m);   
  43.     }   
  44. }   
  45.   
  46. /*-------------------------------------------------------------Hard_Disk_Handler  
  47.     硬盘中断处理程序  
  48. */  
  49. static void Hard_Disk_Handler(int int_vec_no)   
  50. {   
  51.     In_Byte(REG_STATUS);    /* 必须从状态寄存器清空状态值 */  
  52.     Printf("HARD_DISK_HANDLER/n");   
  53. }   
  54.   
  55. /*------------------------------------------------------------------Disp_HD_Info    
  56.     显示硬盘信息功能函数  
  57. */  
  58. static void Disp_HD_Info()   
  59. {   
  60.     HD_Command hd_cmd;   
  61.        
  62.     /* 把命令结构的各字段填充为0 */  
  63.     u8 *p = (u8*)&hd_cmd;   
  64.     int i = 0;   
  65.     for(;i < sizeof(HD_Command);i++)   
  66.     {   
  67.         *p = 0;   
  68.     }   
  69.        
  70.     /* 填充相应的命令 */  
  71.     hd_cmd.device = MAKE_DEVICE_REG(0,0,0);   
  72.     hd_cmd.command = CMD_INFO;   
  73.     HD_Cmd_Out(&hd_cmd);    /* 开始填充寄存器 */  
  74.        
  75.     /* 这里先不等待硬盘中断返回,因为我们暂不打印硬盘信息 */  
  76. }   
  77.   
  78. /*--------------------------------------------------------------------HD_Cmd_Out  
  79.     填充硬盘驱动器各个寄存器的功能函数  
  80. */  
  81. static void HD_Cmd_Out(HD_Command *hd_cmd)   
  82. {   
  83.     /* 状态寄存器的最高位为0才可继续进行 */  
  84.     do  
  85.     {   
  86.         u8 cur_status = In_Byte(REG_STATUS);   
  87.         if((cur_status & 0x80) == 0)   
  88.         {   
  89.             break;   
  90.         }   
  91.         Milli_Delay(100);   
  92.     }while(1);   
  93.        
  94.     Out_Byte(REG_DEVICE_CTL,0);     /* 使能中断响应 */  
  95.        
  96.     /* 填充寄存器 */  
  97.     Out_Byte(REG_FEATURES,hd_cmd->features);   
  98.     Out_Byte(REG_SECTOR_COUNT,hd_cmd->sector_count);   
  99.     Out_Byte(REG_LBA_LOW,hd_cmd->lba_low);   
  100.     Out_Byte(REG_LBA_MID,hd_cmd->lba_mid);   
  101.     Out_Byte(REG_LBA_HIGH,hd_cmd->lba_high);   
  102.     Out_Byte(REG_DEVICE,hd_cmd->device);   
  103.        
  104.     /*   
  105.         此句执行之后,硬盘驱动器开始工作   
  106.         工作结束后发出一个硬盘中断  
  107.     */  
  108.     Out_Byte(REG_COMMAND,hd_cmd->command);   
  109. }  

    其中用到的一些宏定义在hd.h中:

    hd.h

Code:
  1. /*  
  2.     By Marcus Xing  
  3.     include/hd.h  
  4.     与硬盘驱动有关的信息  
  5. */  
  6.   
  7. /*  
  8.     forward include:  
  9.     type.h  
  10. */  
  11.   
  12. #ifndef _HD_H_   
  13. #define _HD_H_   
  14.   
  15.     /* 有关硬盘驱动器的端口号,只考虑挂到IDE0的硬盘 */  
  16.     /* 写时 */  
  17.     #define REG_DATA            0x1f0   
  18.     #define REG_FEATURES        0x1f1   
  19.     #define REG_SECTOR_COUNT    0x1f2   
  20.     #define REG_LBA_LOW         0x1f3   
  21.     #define REG_LBA_MID         0x1f4   
  22.     #define REG_LBA_HIGH        0x1f5   
  23.     #define REG_DEVICE          0x1f6   
  24.     #define REG_COMMAND         0x1f7   
  25.     #define REG_DEVICE_CTL      0x3f6   
  26.        
  27.     /* 写时 */  
  28.     #define REG_STATUS          0x1f7   
  29.        
  30.     #define CMD_INFO    0xec    /* 获得硬盘信息的送给硬盘驱动器寄存器的值 */   
  31.   
  32.     /* 获得device寄存器值的宏 */  
  33.     #define MAKE_DEVICE_REG(is_lba,is_master,lba_highest) /   
  34.         ((is_lba << 6) | (is_master << 4) | (lba_highest & 0xff) | 0xa0)   
  35.            
  36.     /* 写到硬盘驱动器的各命令寄存器的值的结构 */  
  37.     typedef struct s_hd_cmd   
  38.     {   
  39.         u8 features;   
  40.         u8 sector_count;   
  41.         u8 lba_low;   
  42.         u8 lba_mid;   
  43.         u8 lba_high;   
  44.         u8 device;   
  45.         u8 command;   
  46.     }HD_Command;   
  47.   
  48. #endif   

    4,要想使硬盘持续响应中断,发生中断程序结束之前不仅要填充EOI到主片,而且还要填充EOI到从片,在kernel/kernel.asm修改:

    kernel/kernel.asm

Code:
  1. MASTER                      equ 0           ;代表8259A主片   
  2. SLAVE                       equ 1           ;代表8259A从片   
  3. ...   
  4. ;--------------------------------------------------------------HARD_INT_HANDLERS       
  5. ;初始化外中断处理程序的宏   
  6. %macro  hw  2   
  7.     ;保存寄存器值到当前进程的PCB等功能   
  8.     ;调用后下一条指令的地址入PCB的save_ret_addr字段   
  9.     call    Save   
  10.        
  11.     ;屏蔽当前向量号中断   
  12.     push    %1   
  13.     call    Disable_IRQ   
  14.     add esp,4   
  15.        
  16.     ;通知8259A此次中断已结束   
  17.     mov al,EOI   
  18.     mov dx,20h   
  19.     out dx,al   
  20.        
  21.     ;判断是否为从主片   
  22.     mov eax,%2   
  23.     cmp eax,MASTER   
  24.     je  .1   
  25.     nop   
  26.     nop   
  27.        
  28.     ;如果为从片还要向级联片发送EOI   
  29.     mov al,EOI   
  30.     mov dx,0a0h   
  31.     out dx,al   
  32.        
  33. .1:   
  34.     sti     ;发生中断时CPU自动关中断,这里人为打开   
  35.        
  36.     ;如果是时钟中断   
  37.     ;进程调度,中断重入不重入都调度,在函数内判断   
  38.     ;跳入相应的处理函数处理   
  39.     mov eax,IRQ_Handler_Table   
  40.     push    %1   
  41.     call    [eax + (%1 * 4)]        ;一个函数指针4字节   
  42.     add esp,4   
  43.        
  44.     cli     ;准备返回进程前关中断   
  45.        
  46.     ;恢复当前向量号中断   
  47.     push    %1   
  48.     call    Enable_IRQ   
  49.     add esp,4   
  50.        
  51.     ret     ;准备返回   
  52. %endmacro   
  53.   
  54. ;以下都是宏的扩展   
  55. hw_00:   
  56.     hw  0,MASTER        ;时钟中断处理程序   
  57. hw_01:   
  58.     hw  1,MASTER   
  59. hw_02:   
  60.     hw  2,MASTER   
  61. hw_03:   
  62.     hw  3,MASTER   
  63. hw_04:   
  64.     hw  4,MASTER   
  65. hw_05:   
  66.     hw  5,MASTER   
  67. hw_06:   
  68.     hw  6,MASTER   
  69. hw_07:   
  70.     hw  7,MASTER   
  71. hw_08:   
  72.     hw  8,SLAVE   
  73. hw_09:   
  74.     hw  9,SLAVE   
  75. hw_10:   
  76.     hw  10,SLAVE   
  77. hw_11:   
  78.     hw  11,SLAVE   
  79. hw_12:   
  80.     hw  12,SLAVE   
  81. hw_13:   
  82.     hw  13,SLAVE   
  83. hw_14:   
  84.     hw  14,SLAVE   
  85. hw_15:   
  86.     hw  15,SLAVE  

    我们看到,我们的硬盘驱动进程在填充了寄存器后就直接返回了,也没等硬盘中断是否已经执行结束,因为我们先不想获取硬盘中的信息。为了能验证硬盘能否重复响应中断,在FS进程中延迟了3秒以后又发条消息给硬盘驱动进程。

    别忘了,我们现在还没硬盘呢,先造一个出来,修改下bochsrc就能用了:

    OK,make,bochs:

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值