Файл: Организация эвм и систем.docx

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 29.04.2024

Просмотров: 18

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Федеральное государственное бюджетное образовательное учреждение высшего образования

Министерство связи и массовых коммуникаций Российской Федерации

Федеральное государственное образовательное бюджетное учреждение высшего образования «Сибирский государственный университет телекоммуникаций и информатики» (ФГОБУ ВО «СибГУТИ»)
Практическое задание №7 Дисциплина: Архитектура ЭВМ

Выполнил студент 2 курса: Горбань Д.В

Группа: ИП-017 Проверил преподаватель: Трусов К.

Новосибирск, 2022

Цельработы

Изучить устройство накопителей на жестких магнитных дисках. Разработать библиотеку функций по преобразованию геометрий и адресов секторов накопителей на жестких магнитных дис- ках. Создать программу, рассчитывающую таблицу разделов (MBR).

Заданиеналабораторнуюработу

  1. Прочитайте главу 7 практикума по курсу «Организация ЭВМ и систем».

  2. Разработайте пользовательские типы (typedef), для хранения адресов секторов и геометрий жестких дисков в форматах:

  • CHS (20 бит). Имя пользовательского типа - tCHS;

  • ECHS или Large (24 бита). Имя пользовательского типа - tLARGE;

  • CHS из стандарта IDE (28 бит). Имя пользовательского типа tIDECHS;

  • LBA (32 бит). Имя пользовательского типа - tLBA.

  • Создайте библиотеку функций по преобразованию геометрий и адресов секторов накопителей на жестких магнитных дисках в разные стандарты:

    • int g_lba2chs (tLBA, tCHS *).

    • int g_lba2large (tLBA, tLARGE *).

    • int g_lba2idechs (tLBA, tIDECHS *).

    • int g_chs2large (tCHS, tLARGE *).

    • int g_chs2lba (tCHS, tLBA *).

    • int g_chs2idechs (tIDECHS, tLBA *).

    • int g_large2chs (tLARGE, tCHS *).

    • int g_large2idechs (tLARGE, tIDECHS *).

    • int g_large2lba (tLARGE, tLBA *).

    • int g_idechs2chs (tIDECHS. tCHS *).

    • int g_idechs2lagre (tIDECHS. tLARGE *).

    • int g_idechs2lba (tIDECHS. tLBA *).

    • int a_lba2chs (tCHS geometry, tLBA, tCHS *).

    • int a_lba2large (tLARGE geometry, tLBA, tLARGE *).

    • int a_lba2idechs (tIDECHS geometry, tLBA, tIDECHS *).

    • int a_chs2lba (tCHS geometry, tCHS, tLBA *).

    • int a_large2lba (tLARGE geometry, tLARGE, tLBA *).

    • int a_idechs2lba (tIDECHS geometry, tIDECHS, tLBA *).

    • int a_large2chs (tLARGE geometry1, tCHS geometry2, tLARGE, tCHS *).

    • int a_large2idechs (tLARGE geometry1, tIDECHS geometry2, tLARGE, tIDECHS *).

    • int a_chs2large (tCHS geometry1, tLARGE geometry2, tCHS, tLARGE *).

    • int a_idechs2large (tIDECHS geometry1, tLARGE geometry2, tIDECHS, tLARGE *).

    • int a_chs2idechs (tCHS geometry1, tIDECHS geometry2, tCHS, tIDECHS


    *).

    • int a_idechs2chs (tIDECHS geometry1, tCHS geometry2, tIDECHS, tCHS

    *).

    Защиталабораторнойработы

    С использованием библиотеки функций необходимо разработать программу, выполняющую следующие действия:

    • Предлагает пользователю ввести геометрию диска в формате IDECHS.

    • Рассчитывает размер жесткого диска в ГБайтах и выводит его на экран.

    • Предлагает пользователю ввести: размер требуемого раздела на диске, его тип и будет ли он активный (активным может быть только один раздел на диске !).

    • На основании введѐнных данных рассчитывает строку в таблице разделов. Считается, что первый создаваемый пользователем раздел располагается, начиная с сектора 1 (LBA), второй – следом за ним, третий следом за вторым и т.д.

    • Формирование таблицы разделов прекращается, если пользователь ввѐл 0 (ноль) как

    размер раздела или на диске больше не осталось свободного места.

    После ввода всей требуемой информации формируются таблицы разделов (основная и все расширенные) и выводятся на экран с указанием номера сектора, в котором будет записана каждая таблица.

    2. Пользовательские типы (typedef), для хранения адресов секторов и геометрий жестких дисков в форматах:
    CHS (20 бит). Имя пользовательского типа - tCHS;

    ECHS или Large (24 бита). Имя пользовательского типа - tLARGE;

    CHS из стандарта IDE (28 бит). Имя пользовательского типа tIDECHS; LBA (32 бит). Имя пользовательского типа - tLBA.
    C – кол-во цилиндров H кол-во головок


    typedef struct

    {

    unsigned long int C:10, H:4, S:6;

    } tCHS;
    S – кол-во секторов на дорожку Структура CHS(в сумме занимает 20 бит):


    typedef struct

    {

    unsigned long int C:10, H:8, S:6;

    } tLARGE;

    Структура LARGE(в сумме занимает 24 бита):

    typedef struct

    {

    unsigned long int C:16, H:4, S:8;

    } tIDECHS;

    Структура IDE(в сумме занимает 28 бит):
    Структура LBA(32 бита или 4 байта):

    typedef unsigned long int tLBA;

    typedef struct

    {

    unsigned char active; tLARGE startCHS; unsigned char type; tLARGE endCHS;

    tLBA startLBA; unsigned int size;

    } tPartition;

    Структура раздела:

     Все преобразования из разных типов производятся путем изменения структуры SHC по специальным формулам, приведенным в лекционном материале. Разберем некоторые функции.

    int g_chs2lba (tCHS g1, tLBA *g2){

    *g2=g1.C*g1.H*g1.S; return 1;

    }

    Преобразование из CHS в LBA производится простым умножением цилиндров, головок и секторов друг на друга:

    int a_chs2large (tCHS g1, tLARGE g2, tCHS a1, tLARGE *a2){ int c,h,k=1;

    if (g1.C<=g2.C || g1.H>=g2.H) return 0; c=g1.C;

    h=g1.H;

    do{

    c/=2; h*=2; k*=2;

    } while ((c>g2.C)&&(h
    a2->C=a1.C%g2.C;

    a2->H=(g2.H/k)*(a1.C%k)+a1.H; a2->S=a1.S;

    return 1;

    }

    Чтобы перевести из CHS в LARGE достаточно разделить кол-во цилиндров на 2, а сектора и головки умножить на два и округлить в большую сторону:

    Демонстрация работы


    В качестве демонстрации работоспособности программы, предлагается ввести геометрию диска в формате IDECHS, после
    чего будет выведен размера диска в ГБайтах.

    Далее пользователь вводит: размер требуемого раздела на диске, его тип и будет ли он активным (активным может быть только один раздел на диске).

    На основании введенных данных рассчитывает строку в таблице разделов. Считается, что первый создаваемый пользователем раздел располагается, начиная с сектора 1 (LBA), второй – следом за ним, третий следом за вторым и т.д.

    Формирование таблицы разделов прекращается, если пользователь ввѐл 0 (ноль) как размер раздела или на диске больше не осталось свободного места.

    После ввода всей требуемой информации формируются таблицы разделов (основная и все расширенные) и выводятся на экран с указанием номера сектора, в котором будет записана каждая таблица.



    Исходный код



    Main.c

    #include #include "libSC.h" #include "myTerm.h" #include "myBigChars.h" #include "myReadKey.h" #include "signal.h" #include "disk.h"
    struct partition_table

    {

    tPartition table[4];

    struct partition_table *next;

    } * first, *temp, *last; // таблица будет представлять из себя список
    tPartition tm; tIDECHS geomet; tLARGE geom, adr; tLBA disk, adres = 1; int IC = 0;
    void sighandler(int signo)

    {

    if (signo == SIGALRM)

    {

    int flag; sc_regGet(0b0001000, &flag); if (flag == 0)

    {

    IC += 1;

    }

    }

    if (signo == SIGUSR1)

    {

    // registr = 0; sc_memorySave("sc_config"); mt_clrscr();

    }

    }

    int main()


    {

    if (signal(SIGALRM, sighandler) == SIG_ERR) printf("\ncan't catch SIGALRM\n");

    if (signal(SIGUSR1, sighandler) == SIG_ERR) printf("\ncan't catch SIGUSR1\n");
    // memory init sc_memoryInit(MaxMemory);

    // printf("%d - first position check\n", *mem);
    // memory set sc_memorySet(25, 452);
    // memory get

    int val = 0;

    sc_memoryGet(25, &val);

    // printf("%d - 25 element\n", val);
    // memory write sc_memorySave("../bin/memory.txt");
    // memory load sc_memoryLoad("../bin/memory.txt");
    // zero flags init sc_regInit();
    // set flag values

    int temp1 = sc_regSet(0b00010000, 1); int temp2 = sc_regSet(0b00010000, 0);

    // printf("%d - flag set 1(00010000) || %d - flag set 0(00010000)\n", temp1, temp2);
    // encode command

    int tempCheck = -1;

    // sc_commandEncode(0x11, 13, &tempCheck);

    // printf("%d - encode number (command - 0x11, operand - 13)\n", tempCheck);
    // decode command

    int tempCommand = -1;

    int tempOperand = -1;

    // sc_commandDecode(2189, &tempCommand, &tempOperand);

    // printf("%d(0x11) - command || %d - operand\n", tempCommand, tempOperand);
    mt_setbgcolor(CYAN); mt_gotoXY(10, 10);
    int key = -1; rk_readkey(&key);

    // printf("key = 2\n");
    rk_mytermsave();
    // printf("%d - SIGALARM || %d - SIGUSR1\n", SIGALRM, SIGUSR1);
    int t, k = 0, b = 1, free_size, type_oc, bool_oc;

    char c;

    geom.C = 1023; // максимальные значения С, H, S

    geom.H = 255;

    geom.S = 63;

    first = malloc(sizeof(struct partition_table)); // выделяем память под первый элемент
    last = first;
    printf("Введите IDECHS геометрию диска\n");

    metka:


    printf("C:");

    scanf("%d", &t); // считываем значение C

    if (t > geom.C)

    {

    printf("Error\n");

    goto metka;

    }

    geomet.C = t;

    metka1:


    printf("H:");

    scanf("%d", &t); // считываем значение H

    if (t > geom.H)

    {

    printf("Error\n");

    goto metka1;

    }

    geomet.H = t;

    metka2:


    printf("S:");

    scanf("%d", &t); // считываем значение S

    if (t > geom.S)

    {

    printf("Error\n");

    goto metka1;

    }

    geomet.S = t;
    g_idechs2lba(geomet, &disk); //

    расчитываем размер диска по геометрии

    printf("Размер диска %.2f Gb\n", (float)disk / (1024 * 2048)); // выводим размер диска

    free_size = disk / 2; do

    {

    do


    {

    printf("Свободного места: %d Кб\n", free_size); // выводим

    оставшееся место

    printf("Размер раздела (Кб):");

    scanf("%d", &t); // считываем размер раздела

    } while (t > free_size); // пока если свободное место

    if (t == 0)

    break;


    free_size -= t; // вычитаем из свободного места размер раздела

    tm.startLBA = adres; // запоминаем начало LBA адреса tm.size = t; // запоминаем размер раздела adres += tm.size;

    // запоминаем конечный адрес

    if (a_lba2large(geom, tm.startLBA, &adr)) // переводим из LBA в CHS tm.startCHS = adr; // запоминаем CHS адрес

    else


    tm.startCHS = geom;
    if (a_lba2large(geom, adres, &adr)) // переводим конец LBA в CHS tm.endCHS = adr; // запоминаем конечный CHS адрес

    else


    tm.endCHS = geom;
    bool_oc = 1;
    while (bool_oc)

    {

    bool_oc = 0;

    printf("Тип ОС:\n"); // выводим архитектуры ОС

    printf("1 - FAT16\n");

    printf("2 - FAT32\n"); printf("3 - Linux swap\n"); printf("4 - Linux\n");

    printf("5 - HPFS/NTFS\n"); scanf("%d", &type_oc); switch (type_oc)

    { // в зависимости от выбора сохраняем флаги ОС

    case 1:


    tm.type = 0x04; break;

    case 2:


    tm.type = 0x0c; break;

    case 3:


    tm.type = 0x82; break;

    case 4:


    tm.type = 0x83; break;

    case 5:


    tm.type = 0x07; break;

    default:


    bool_oc = 1;

    }

    }
    tm.active = 0;
    if (b)

    {

    printf("Установить раздел активным (y/n)\n");

    do


    {

    scanf("%c", &c); // считываем выбор

    } while ((c != 'n') && (c != 'y'));

    if ((c == 'y'))

    {

    tm.active = 0x80; // если выбор y, то помечаем раздел флагом

    b = 0;

    }

    }
    if (((tm.startCHS.C == geom.C) && (tm.startCHS.H == geom.H) && (tm.startCHS.S == geom.S)) || (k == 3))

    {

    last->table[k] = tm;

    last->table[k].type = 0x05; if (k != 3)

    last->table[k + 1].startLBA = 0;

    temp = malloc(sizeof(struct partition_table)); last->next = temp;

    last = temp;

    last->table[0] = tm;

    last->table[1].startLBA = 0;

    k = 1;

    }

    else


    {

    last->table[k] = tm;

    last->table[++k].startLBA = 0;

    }

    } while (free_size != 0);
    printf("Актив # CHS начало # ОС # CHS конец # LBA начало # Размер\n");
    temp = first;
    while (temp != NULL)

    { // пока не дошли до конца списка

    int i;

    // printf("Адрес сектора где расположена таблица %d\n",temp-

    >table[0].startLBA);

    for (i = 0; i < 4; i++)

    {

    if (temp->table[i].startLBA == 0) break;

    printf("%2x%5d%4d%3d%4x%5d%4d%3d%13ld%13d\n", temp-

    >table[i].active, temp->table[i].startCHS.C, temp->table[i].startCHS.H, temp-

    >table[i].startCHS.S, temp->table[i].type, temp->table[i].endCHS.C, temp-

    >table[i].endCHS.H, temp->table[i].endCHS.S, temp->table[i].startLBA, temp-

    >table[i].size); // выводим все данные о разделе

    }

    temp = temp->next; // переходим к следующему разделу

    }

    return 0;


    }
    Disk.c



    L1=g1/63;

    nlog=L1/1024;

    while (nlog/k>0){ if (k==256) break; k*=2;

    }

    if (k==256)

    k=255;

    if (nlog/k<1024){ g2->C=L1/k;

    g2->H=k; g2->S=63;

    } else return 0; return 1;


    }
    int g_lba2idechs (tLBA g1, tIDECHS *g2){

    int L1,nlog,k=2; L1=g1/255;

    nlog=L1/65535;

    while (nlog/k>0){ if (k==16) break; k*=2;

    }

    if(k==16) k=15;

    if (nlog/k<65536){ g2->C=L1/k;

    g2->H=k; g2->S=25;

    } else return 0; return 1;


    }
    int g_chs2large (tCHS g1, tLARGE *g2){

    int c,h; c=g1.C; h=g1.H;

    do { c/=2; h*=2;

    } while ((c/2>0)&&(h*2<256)); g2->C=c;

    g2->H=h;

    g2->S=g1.S;

    return 1;


    }
    int g_chs2idechs (tCHS g1, tIDECHS *g2){

    int c,h; c=g1.C; h=g1.H;

    do {

    c*=2; h/=2;

    } while ((c*2<65536)&&(h/2>0)); g2->C=c;

    g2->H=h;

    g2->S=g1.S;

    return 1;


    }
    int g_chs2lba (tCHS g1, tLBA *g2){

    *g2=g1.C*g1.H*g1.S;

    return 1;


    }
    int g_large2chs (tLARGE g1, tCHS *g2){

    int c,h; c=g1.C; h=g1.H;

    do { c*=2; h/=2;

    } while ((c*2<1024)&&(h/2>0)); if (c>1023 || h>15) return 0; g2->C=c;

    g2->H=h;

    g2->S=g1.S;

    return 1;


    }
    int g_large2idechs (tLARGE g1, tIDECHS *g2){

    int c,h; c=g1.C; h=g1.H;

    do{

    c*=2; h/=2;

    } while ((c*2<1024)&&(h/2>0)); if (c>65536 || h>15) return 0; g2->C=c;

    g2->H=h;

    g2->S=g1.S;

    return 1;


    }
    int g_large2lba (tLARGE g1, tLBA *g2){

    *g2=g1.C*g1.H*g1.S;

    return 1;


    }
    int g_idechs2chs (tIDECHS g1, tCHS *g2){ tLBA temp; g_idechs2lba(g1,&temp);

    if (g_lba2chs(temp,g2)==0) return 0; return 1;

    }
    int g_idechs2lagre (tIDECHS g1, tLARGE *g2){ tLBA temp;

    g_idechs2lba(g1,&temp);

    if (g_lba2large(temp,g2)==0) return 0; return 1;

    }
    int g_idechs2lba (tIDECHS g1, tLBA *g2){

    *g2=g1.C*g1.H*g1.S;

    return 1;


    }
    int a_lba2chs (tCHS g1, tLBA a1, tCHS *a2){

    int a;

    a2->C=a1/(g1.H*g1.S); a=a1%(g1.H*g1.S);

    a2->H=a/g1.S; a2->S=a%g1.S;

    return 1;


    }
    int a_lba2large (tLARGE g1, tLBA a1, tLARGE *a2){

    int a;

    if ((g1.C*g1.H*g1.S)return 0; a2->C=a1/(g1.H*g1.S); a=a1%(g1.H*g1.S);

    a2->H=a/g1.S; a2->S=a%g1.S;

    return 1;


    }
    int a_lba2idechs (tIDECHS g1, tLBA a1, tIDECHS *a2){

    int a;

    a2->C=a1/(g1.H*g1.S); a=a1%(g1.H*g1.S);

    a2->H=a/g1.S; a2->S=a%g1.S;

    return 1;


    }
    int a_chs2lba (tCHS g1, tCHS a1, tLBA *a2){

    if ((g1.C return 0;

    *a2=a1.C*(g1.H*g1.S)+a1.H*g1.S+a1.S;

    return 1;


    }
    int a_large2lba (tLARGE g1, tLARGE a1, tLBA *a2){

    if ((g1.C return 0;

    *a2=a1.C*(g1.H*g1.S)+a1.H*g1.S+a1.S;

    return 1;


    }
    int a_idechs2lba (tIDECHS g1, tIDECHS a1, tLBA *a2){

    if ((g1.C return 0;

    *a2=a1.C*(g1.H*g1.S)+a1.H*g1.S+a1.S;

    return 1;


    }
    int a_large2chs (tLARGE g1, tCHS g2, tLARGE a1, tCHS *a2){

    int c,h,k=1;

    if (g1.C>=g2.C || g1.H<=g2.H) return 0; c=g1.C;

    h=g1.H;

    do{

    c*=2; h/=2; k*=2;

    } while ((cg2.H)); a2->C=g1.C*(a1.H%k)+a1.C;

    a2->H=a1.H%k; a2->S=a1.S;

    return 1;


    }
    int a_large2idechs (tLARGE g1, tIDECHS g2, tLARGE a1, tIDECHS *a2){

    int c,h,k=1;

    if (g1.C>=g2.C || g1.H<=g2.H) return 0; c=g1.C;

    h=g1.H;

    do{

    c*=2; h/=2; k*=2;

    } while ((cg2.H)); a2->C=g1.C*(a1.H%k)+a1.C;

    a2->H=a1.H%k; a2->S=a1.S;

    return 1;


    }
    int a_chs2large (tCHS g1, tLARGE g2, tCHS a1, tLARGE *a2){

    int c,h,k=1;

    if (g1.C<=g2.C || g1.H>=g2.H) return 0; c=g1.C;

    h=g1.H;

    do{

    c/=2; h*=2; k*=2;

    } while ((c>g2.C)&&(h a2->C=a1.C%g2.C;

    a2->H=(g2.H/k)*(a1.C%k)+a1.H; a2->S=a1.S;

    return 1;


    }
    int a_idechs2large (tIDECHS g1, tLARGE g2, tIDECHS a1, tLARGE *a2){ tLBA temp;

    a_idechs2lba(g1,a1,&temp);

    if (a_lba2large(g2,temp,a2)==0) return 0; return 1;

    }
    int a_chs2idechs (tCHS g1, tIDECHS g2, tCHS a1, tIDECHS *a2){

    int c,h,k=1;

    if (g1.C>=g2.C || g1.H<=g2.H) return 0; c=g1.C;

    h=g1.H;

    do{

    c*=2; h/=2; k*=2;

    } while ((cg2.H)); a2->C=g1.C*(a1.H%k)+a1.C;

    a2->H=a1.H%k; a2->S=a1.S;

    return 1;


    }


    Disk.h #include #include

    // С - цилиндры, H - число головок, S - число секторов на дорожку

    typedef struct


    {

    unsigned long int C:10, H:4, S:6;

    } tCHS;

    typedef struct


    {

    unsigned long int C:10, H:8, S:6;

    } tLARGE;

    typedef struct


    {

    unsigned long int C:16, H:4, S:8;

    } tIDECHS;

    typedef unsigned long int tLBA;



    typedef struct

    {

    unsigned char active; tLARGE startCHS; unsigned char type; tLARGE endCHS;

    tLBA startLBA;

    unsigned int size;

    } tPartition;
    int g_lba2chs (tLBA, tCHS *);

    int g_lba2large (tLBA, tLARGE *); int g_lba2idechs (tLBA, tIDECHS *); int g_chs2large (tCHS, tLARGE *); int g_chs2idechs (tCHS, tIDECHS *); int g_chs2lba (tCHS, tLBA *);

    int g_large2chs (tLARGE, tCHS *);

    int g_large2idechs (tLARGE, tIDECHS *);

    int g_large2lba (tLARGE, tLBA *);

    int g_idechs2chs (tIDECHS, tCHS *);

    int g_idechs2lagre (tIDECHS, tLARGE *);

    int g_idechs2lba (tIDECHS, tLBA *);
    int a_lba2chs (tCHS, tLBA, tCHS *);

    int a_lba2large (tLARGE, tLBA, tLARGE *); int a_lba2idechs (tIDECHS, tLBA, tIDECHS *); int a_chs2lba (tCHS, tCHS, tLBA *);

    int a_large2lba (tLARGE, tLARGE, tLBA *);

    int a_idechs2lba (tIDECHS, tIDECHS, tLBA *);

    int a_large2chs (tLARGE, tCHS, tLARGE, tCHS *);

    int a_large2idechs (tLARGE, tIDECHS, tLARGE, tIDECHS *);

    int a_chs2large (tCHS, tLARGE, tCHS, tLARGE *);

    int a_idechs2large (tIDECHS, tLARGE, tIDECHS, tLARGE *);

    int a_chs2idechs (tCHS, tIDECHS, tCHS, tIDECHS *);


    Makefile