ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 29.04.2024
Просмотров: 18
Скачиваний: 0
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
Федеральное государственное бюджетное образовательное учреждение высшего образования
Министерство связи и массовых коммуникаций Российской Федерации
Федеральное государственное образовательное бюджетное учреждение высшего образования «Сибирский государственный университет телекоммуникаций и информатики» (ФГОБУ ВО «СибГУТИ»)
Практическое задание №7 Дисциплина: Архитектура ЭВМ
Выполнил студент 2 курса: Горбань Д.В
Группа: ИП-017 Проверил преподаватель: Трусов К.
Новосибирск, 2022
Цельработы
Изучить устройство накопителей на жестких магнитных дисках. Разработать библиотеку функций по преобразованию геометрий и адресов секторов накопителей на жестких магнитных дис- ках. Создать программу, рассчитывающую таблицу разделов (MBR).
Заданиеналабораторнуюработу
-
Прочитайте главу 7 практикума по курсу «Организация ЭВМ и систем». -
Разработайте пользовательские типы (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->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
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)
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
*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
*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
*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 ((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 ((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->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 ((c
a2->H=a1.H%k; a2->S=a1.S;
return 1;
}
Disk.h #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