메뉴 건너뛰기

NEOS White Paper

주의 : 본 기능은 NEOS V4에만 적용됩니다.

 

NEOS 에서는 AHCI를 사용하여 SATA Device를 지원하고 있다. 

1. SATA Device Driver 구조

sata device driver는 아래와 같은 구조를 가진다. Virtual filesystem으로부터 block device driver로 command를 받아 AHCI 드라이버에서 FIS(Frame information structure)를 구성하여 DMA를 통하여 sata device에 command와 data를 전달한다.

wd: block device driver

ata: ata bus driver

ahci: ahci driver

 

neossata.png

 

2. block device driver

SATA Device Driver는 block device driver이다. 따라서 별도의 함수 인터페이스를 사용하지 않고, DIOCSTRATEGY라는 버퍼를 사용한 디스크 접근 제어 명령을 제공하며,  ioctl() 함수의 DIOSTRATEGY를 통하여 sata device 의 임의의 영역에 읽고 쓰기를 한다. block device driver에서 사용하는 함수들은 아래의 Device Driver Operator를 통하여 제공되므로, SATA Device Driver에서 사용할 device 제어 함수들은 이 구조체에 등록한다

static DeviceOperator wd_ops = {

    wdopen,        /* device open */

    wdread,        /* device read */

    wdwrite,       /* device write */

    wdioctl,       /* device ioctl */

    wdclose,       /* device close */

    wdinit         /* device initialize */

   // ...

 

 

int wdioctl(Device *dev, Value cmd, Address addr)

{

     // ....

    case DIOCSTRATEGY:

        wdstrategy((struct buf *)addr);

        return (0);

     //   ....

}

 

 

3. Sata Device Driver Configuration

Sata device driver등록은 BspConfig.c의 함수 BspPostInitialize()에서 한다. BspPostInitialize()는 sussystem configuration 하는 main thread인 UserMain()에서 호출된다.

void

BspPostInitialize(void)

{

            SataConfig();

}

 

AHCI driver는 PCI bus에 연결되어 있다.  따라서 pci bus에서 AHCI driver를 찾고, interrupt 를 등록하여야한다. 이 interrupt에는 ahci의 interrupt handler가 등록되게 된다. 이 과정은 SataConfig.c의 Sataconfig()함수내의 sataInit()에서 이루어진다. ahci driver의 initialization 및 configuration이 이루어진 후 sata device driver를 vfs에 attach, mount 한다.

void SataConfig(void)

{

            fatconf_t   fatopt;

 

    memset(&fatopt, 0x00, sizeof(fatconf_t));

            sataInit(INT_PIN_NUMBER, INT_LINE, PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_7SER_MO_SATA_AHCI);

 

    /* Mount FAT file system to SATA AHCI SSD hard disk */

    printk("Mounting start.\n\r");

 

    if(mount(MOUNT_MSDOS, "/dev/wd0", "/wddisk", MNT_SYNC, NULL) != SUCCESS)

    {

        printk("mount failed. err = %d\n\r", errno);

        fatopt.spc = 32;

 

        printk("format start.\n\r");

        if(msdosfs_newfs("/dev/wd0", NULL, &fatopt) != SUCCESS)

        {

            printk("FORMAT FAILED\n\r");

        }

        printk("format done\n\r");

 

        return;

    }

    if(vfs_setcwd("/wddisk/") != SUCCESS)

    {

        printk("Fail to set root directory..( error %d )\n",errno);

        return;

    }

    printk("Mount done.\n");

 

 

위로