zoukankan      html  css  js  c++  java
  • msahci代码调试备份

      

      一、代码路径以及断点

      在winddk的例子里面有msahci代码, 编译成功之后, 替换系统的msahci.sys.重启下断点进行分析.

      简单的看下代码在DriverEntry中调用IDE_CONTROLLER_INTERFACE结构,并且调用AtaPortInitializeEx向PCIIDEX创建controller的FDO, 其中包含了AhciChannelInitRoutine、AhciChannelEnabled、AhciAdapterControl函数。对这几个函数下断点,查看调用来源,并且分析函数的作用.

    ULONG    //REMOVE: 1PCIIDEX to driver entry
    DriverEntry (       //  DriverEntry(
        PVOID Argument1,//    IN PDRIVER_OBJECT  DriverObject, 
        PVOID Argument2 //    IN PUNICODE_STRING  RegistryPath 
        )               //    )
    /*++
    The only goal of DriverEntry is to create an IDE_CONTROLLER_INTERFACE, populate and 
    send it to AtaPortInitializeEx.
    
    It assumes:
        DriverEntry is the first function called in msahci.sys
        The OS-specific port driver allocates a controller extension initializes it and sends it to AtaPortInitializeEx. 
        AtaPortInitializeEx initializes the miniport driver抯 dispatch tables and allocates an extension for the driver object. 
        It stores the pointer to the AtaControllerInitialize entry point and the ControllerExtensionSize in the driver object extension for later use.
    
    Called by:                              
        external
    
    It performs:
        (overview)
        1. Initialization of the Ide Controller Interface
        2. Calling into PCIIDEX through AtaPortInitializeEx.
        (details)
        1.1 Initialize IDE_CONTROLLER_INTERFACE to 0s
        1.2 The miniport driver indicates the support for the channel interface by setting the ChannelExtensionSize and the AtaChannelInitRoutine entry point in the controller interface structure.
        1.3 Add mini driver entry points
        1.4 add pointers to data structures and IO alignment
        2.1 The miniport must call AtaPortInitializeEx from its DriverEntry routine. 
    
    Affected Variables/Registers:
        none
    
    Return Values:
        The miniport driver must return TRUE if the initialization succeeded. If the miniport driver fails to initialize it must return FALSE.
        Initialization success is dependant on AtaPortInitializeEx's Return Value
    
    --*/
    {                                        //used to initialize the IDE Controller Interface
        IDE_CONTROLLER_INTERFACE IdeControllerInterface;
        PUCHAR pIdeControllerInterface  = (PUCHAR) &IdeControllerInterface;
        int i=0;
    
      //1.1 initialize IDE_CONTROLLER_INTERFACE to 0s
        for (i= 0; i<sizeof(IDE_CONTROLLER_INTERFACE); i++) {
            (*(pIdeControllerInterface))=0;
            pIdeControllerInterface++; 
        }
      //1.2 The miniport driver indicates the support
        IdeControllerInterface.ChannelExtensionSize= sizeof(AHCI_CHANNEL_EXTENSION); 
        IdeControllerInterface.AtaChannelInitRoutine= AhciChannelInitRoutine;
      //1.3 Add mini driver entry points 
        IdeControllerInterface.AtaControllerChannelEnabled = AhciChannelEnabled;
        IdeControllerInterface.AtaControllerTransferModeSelect = NULL;
        IdeControllerInterface.AtaAdapterControl= AhciAdapterControl;
      //1.4 add pointers to data structures and IO alignment
        IdeControllerInterface.Version= sizeof(IDE_CONTROLLER_INTERFACE);
        IdeControllerInterface.ControllerExtensionSize= sizeof(AHCI_CONTROLLER_EXTENSION);
        IdeControllerInterface.AlignmentMask = 1; // The PRDT DBA must be word aligned.
    
      //2.1 call into PCIIDEX where it will handle creating the controller's FDO
        return AtaPortInitializeEx( Argument1, //DriverObject,
                                    Argument2, //RegistryPath,
                                    &IdeControllerInterface);
    }

      二、调试分析

      在msahci!AhciAdapterControl断下来之后, 可以看到调用来源是PCIIDEX!CallAdapterControl函数

      

      我们再看下msahci!AhciAdapterControl函数的实现,该函数是一个中转函数, 处理control的Start、Stop、PowerUp、PowerDown事件。

      当前堆栈看到ControlAction为0, 是IdeStart事件, 之后再次中断下来看到的是IdePowerUp事件.

    BOOLEAN  
      AhciAdapterControl(
        PVOID ControllerExtension,
        IN IDE_CONTROL_ACTION ControlAction,
        IN PVOID Parameters //when ControlAction is IdeStart, this is a pointer to a IDE_CONTROLLER_CONFIGURATION
        )
    /*++
    This is a CONTROLLER dispatch routine for for notifications the miniport driver receives about the various PNP and power events in the system. 
    This function is a function dispatcher for the IDE_CONTROL_ACTIONS: Start, Stop, PowerUp, and PowerDown
    
    It assumes:
        The port driver ensures that there is no outstanding I/O on the adapter before invoking this routine. 
    
    Called by:    
        external
    
    It performs:
        Dispatch based on the IDE_CONTROL_ACTIONS for the Controller
    
    Affected Variables/Registers:
        none
    
    Return Values:
        The miniport driver must return TRUE to acknowledge the completion of the requested action. 
        A return value of FALSE indicates that the miniport was not able to complete the action successfully. 
        A return value of FALSE for certain actions might cause the device installation to fail.
    
        FALSE is only valid if the IDE_CONTROLLER_CONFIGURATION structure is not the right version.
        This causes the PCIIDEX driver to return from IRP_MJ_PnP with a STATUS_REVISION_MISMATCH
    --*/
    {                    //Used to perform dispatch
        BOOLEAN retVal;
        PIDE_CONTROLLER_CONFIGURATION controllerConfiguration;
    
        switch (ControlAction) {
        case IdeStart:
    
            controllerConfiguration = Parameters;
            retVal = AhciAdapterControlIdeStart(ControllerExtension, controllerConfiguration);
            break;     
    
        case IdeStop:
    
            retVal = AhciAdapterControlIdeStop(ControllerExtension);
            break;
    
        case IdePowerUp:
    
            retVal = AhciAdapterControlIdePowerUp(ControllerExtension);
            break;
    
        case IdePowerDown:
            retVal = AhciAdapterControlIdePowerDown(ControllerExtension);
            break;
    
        default:        
            retVal = FALSE;
            break;
        }
        return retVal;
    }

      在msahci!AhciChannelEnabled中断下来后, 看到堆栈情况如下:

      

      我们看下这个函数的代码实现,这个函数是给每个通道创建PDO. 一旦PDO创建, 这时就会加载ataport去开启通道并且在每个通道上枚举设备。

    ATA_CHANNEL_STATE  
      AhciChannelEnabled(
        IN PVOID ControllerExtension,
        IN ULONG Channel
        )
    /*++
    AtaControllerChannelEnabled is an optional routine.   This is an optional routine and should not have controller critical steps in it.
    This function is not called in the case of a channel restart, only on QueryDeviceRelations
    If the miniport driver does not implement this routine a default handler will be loaded, and all channels are assumed to be enabled.  
    
    PCIIDEX uses this function to help it build PDOs for each channel.  
    Once the PDOs are created, it is time to load ATAport who will start the channels and do enumeration for the device(s) on the channel(s).
    
    It assumes:
        This function will be called with 'ULONG Channel' valuse from 0 to (ControllerConfiguration->NumberOfChannels - 1) which was given to PCIIDEX in AhciAdapterControl (IdeStart).
    
    Called by:    
        external
    
    It performs:
        (overview)
        1. Verification of channel's existance
    
        (details)
        1.1 Initialize variables
        1.2 Verify the channel's existance
            Ataport doesn't support sparse channels explicitly.  It is possible this channel doesn't exist.
    
    Affected Variables/Registers:
    
    Return Values:
        ChannelStateEnabled = Channel is ready to be used by time this function finishes
        ChannelStateDisabled= If previously enabled, this state causes the port driver to mark the channel dead
        ChannelStateUnKnown = use only if you want the port driver to assert.
    --*/
    {
        ATA_CHANNEL_STATE state;
        PAHCI_CONTROLLER_EXTENSION controllerExtension;
                                 //structures to get information from the Controller
        PAHCI_MEMORY_REGISTERS abar;
        ULONG pi;
      
      //this is an optional routine and should not have controller critical steps in it.
      //this is not called in the case of a channel restart, only on QueryDeviceRelations
    
      //1.1 Initialize variables
        state = ChannelStateUnKnown;
        controllerExtension = (PAHCI_CONTROLLER_EXTENSION) ControllerExtension;
        abar = (PAHCI_MEMORY_REGISTERS) controllerExtension->ABAR_Address;
        pi = AtaPortReadRegisterUlong(&abar->PI);
      //1.2 Verify the channel's existance
        if ( (pi & (1 << Channel) ) == 0){
            return ChannelStateDisabled;
        }
    
        return ChannelStateEnabled;
    }

      以上初始化步骤完成之后,ataport就会调用msahci!AhciChannelInitRoutine对通道上的每个设备进行初始化。

      

      我们来看看这个函数的代码实现,msahci!AhciChannelInitRoutine就将ataport初始化一部分的Channel interface进行初始化.该函数是在ataport的AddDevice创建通道的FDO扩展时调用.

    BOOLEAN     
      AhciChannelInitRoutine(
        IN PVOID ChannelExtension,
        OUT PIDE_CHANNEL_INTERFACE ChannelInterface,
        IN PVOID ControllerExtension
        )
    {
    /*++
    This is the first time that we see the Channel Interface.  Ataport has initialized some of it,  we have to initialize the rest. 
    This is the first time that we see the Channel Extension whose size was specified in IdeControllerInterface.ChannelExtensionSize at DriverEntry. 
    Time to start initializing the Channel Extension.
    
    It assumes:
        The ChannelInitialize routine is called when Ataport's AddDevice is creating the Channel's FDO Extension.
    
    Called by:    
        external
    
    It performs:
        (overview)
        1. Start with some defensive structure checking
        2. Fill in ControllerExtension
        3. Initialization of the Channel Extension
        4. Initialization of the Channel Interface
        (details)
        1.1 Initialize Variables
        1.2 Verify the Channel Interface is the version we are expecting.
        2.1 Fill in ControllerExtension
        3.1 Initialize Channel Extension
        3.2 Check for controller matched accomodations
        3.3 Keep a copy of the Controller's Capabilities
        3.4 Finally, Intialize the Command and Interrupt logging
        4.1 Initialization of the Channel Interface
    
    Affected Variables/Registers:
        ControllerExtension
        ChannelExtension
        ChannelInterface
    
    Return Values:
        FALSE is only valid if the IDE_CONTROLLER_CONFIGURATION structure is not the right version.
        This causes the AtaPort driver to return from IRP_MJ_PnP, IRP_MN_START with a STATUS_REVISION_MISMATCH
        True if the function excecuted entirely.
    */
        PAHCI_CHANNEL_EXTENSION channelExtension;
        PAHCI_CONTROLLER_EXTENSION controllerExtension;
    
    
      //1.1 Initialize Variables
        channelExtension = (PAHCI_CHANNEL_EXTENSION) ChannelExtension;
        controllerExtension = (PAHCI_CONTROLLER_EXTENSION) ControllerExtension;
    
    
    #ifdef ENABLE_HISTORY_LOG
        RecordExecutionHistory(channelExtension, 0x00000001);//AhciChannelInitRoutine
    #endif
    
      //1.2 Verify the Channel Interface
        if (ChannelInterface->Version != sizeof(IDE_CHANNEL_INTERFACE) ){
            RecordExecutionHistory(channelExtension, 0x10ff0001);//AhciChannelInitRoutine failed. Structure version mismatch.
            return FALSE;
        }
    
      //2.1 Fill in ControllerExtension
        controllerExtension->ExtensionOnSlot[ChannelInterface->ChannelNumber] = channelExtension;
        channelExtension->ControllerExtension = (PVOID) controllerExtension;
    
      //3.1    Initialize Channel Extension
        channelExtension->ChannelNumber = ChannelInterface->ChannelNumber;                
        
        channelExtension->StateFlags.StartCapable = FALSE;
        channelExtension->StateFlags.Crashing = FALSE;
        channelExtension->StateFlags.IgnoreHotplugDueToResetInProgress = TRUE;
        channelExtension->StateFlags.QueuePaused = FALSE;
    
        channelExtension->StateFlags.NCQ_Disallowed  = FALSE;
        channelExtension->StateFlags.NCQ_Activated = FALSE;
        channelExtension->StateFlags.NCQ_Succeeded = FALSE;
        channelExtension->StateFlags.NCQ_NeverNonQueuedErrorRecovery = FALSE;
            
        channelExtension->StateFlags.CallAhciReset = FALSE;
        channelExtension->StateFlags.CallAhciNonQueuedErrorRecovery = FALSE;
        channelExtension->StateFlags.CallAhciReportBusChange = FALSE;
        channelExtension->StateFlags.IgnoreHotPlug = FALSE;
    
        channelExtension->StateFlags.SingleIo = FALSE;
        channelExtension->StateFlags.ResetInInit = FALSE;
        channelExtension->StateFlags.CallAhciAutoPartialToSlumber = FALSE;
    
        channelExtension->StateFlags.AN_Enabled = FALSE;
        channelExtension->SendGesnToDevice = FALSE;
    
        channelExtension->StateFlags.CLOReset_Enable = FALSE;
    
      //3.2 Check for controller matched accomodations
    
        channelExtension->SlotManager.CommandsIssued = 0;
        channelExtension->SlotManager.CommandsToComplete = 0;
        channelExtension->SlotManager.HighPriorityAttribute = 0;
        channelExtension->SlotManager.NCQueueSlice = 0;
        channelExtension->SlotManager.NormalQueueSlice = 0;
        channelExtension->SlotManager.SingleIoSlice = 0;
        channelExtension->CCS = 1;
      //3.3 Keep a copy of the Controller's Capabilities
        channelExtension->CAP = controllerExtension->CAP;
        channelExtension->CAP2 = controllerExtension->CAP2;
    
      //3.4 Finally, Intialize the Command and Interrupt logging
        channelExtension->CommandHistoryNextAvailableIndex = 0;
        channelExtension->ExecutionHistoryNextAvailableIndex = 0;
        
      //4.1 Initialization of the Channel Interface
        ChannelInterface->IdeHwInitialize = AhciHwInitialize;
        ChannelInterface->IdeHwBuildIo = AhciHwBuildIo;
        ChannelInterface->IdeHwStartIo = AhciHwStartIo;
        ChannelInterface->IdeHwInterrupt = AhciHwInterrupt;
        ChannelInterface->IdeHwReset = AhciHwReset;
        ChannelInterface->IdeHwControl = AhciHwControl;
    
        RecordExecutionHistory(channelExtension, 0x10000001);//Exit AhciChannelInitRoutine
    
        return TRUE;
    }

      

  • 相关阅读:
    2.2.7将任意对象作为对象监视器
    2.2.6验证同步代码块时锁定当前对象的
    2.2.5synchronized代码间的同步性
    2.2.4一半异步,一半同步
    2.2.3用同步代码块解决同步方法的弊端
    FL2440 ubifs文件系统烧录遇到的问题——内核分区的重要性
    FL2440 rt3070模块ap模式移植
    FL2440 rt3070模块station模式动态获取IP地址
    FL2440 rt3070模块station模式移植
    fl2440 platform总线button字符设备驱动
  • 原文地址:https://www.cnblogs.com/aliflycoris/p/10021066.html
Copyright © 2011-2022 走看看