У рачунарима, да би процес био извршан, мора бити смештен у меморију. За ово, поље мора бити додељено процесу у меморији. Алокација меморије је важно питање којег треба бити свестан, посебно у архитектури кернела и система.

Хајде да детаљно погледамо расподелу Линук меморије и разумемо шта се дешава иза кулиса.

Како се врши додела меморије?

Већина софтверских инжењера не зна детаље овог процеса. Али ако сте кандидат за системског програмера, требало би да знате више о томе. Када посматрамо процес доделе, потребно је ући у мало детаља о Линуку и глибц библиотека.

Када апликацијама треба меморија, морају да је затраже од оперативног система. Овај захтев кернела ће наравно захтевати системски позив. Не можете сами да доделите меморију у корисничком режиму.

Тхе маллоц() породица функција је одговорна за алокацију меморије у језику Ц. Овде се поставља питање да ли маллоц(), као глибц функција, врши директан системски позив.

У Линук кернелу не постоји системски позив који се зове маллоц. Међутим, постоје два системска позива за апликације које захтевају меморију, а то су брк и ммап.

Пошто ћете захтевати меморију у својој апликацији преко глибц функција, можда се питате који од ових системских позива глибц користи у овом тренутку. Одговор је обоје.

Први системски позив: брк

Сваки процес има непрекидно поље података. Са брк системским позивом се повећава вредност прекида програма, која одређује границу поља података и врши се процес алокације.

Иако је додела меморије овом методом веома брза, није увек могуће вратити неискоришћени простор у систем.

На пример, узмите у обзир да додељујете пет поља, свако величине 16 КБ, са брк системским позивом преко функције маллоц(). Када завршите са бројем два од ових поља, није могуће вратити релевантни ресурс (деаллоцатион) тако да га систем може користити. Јер ако смањите вредност адресе да покажете место где почиње ваше поље број два, са позивом на брк, извршићете делокацију за поља број три, четири и пет.

Да би се спречио губитак меморије у овом сценарију, маллоц имплементација у глибц-у надгледа места додељена у пољу података процеса и затим наводи да га врати у систем са функцијом фрее(), тако да систем може да користи слободан простор за даљу меморију издвајања.

Другим речима, након што се додели пет области од 16КБ, ако се друга област врати са функцијом фрее() и још једна област од 16КБ се поново захтева након неког времена, уместо повећања области података путем брк системског позива, враћа се претходна адреса.

Међутим, ако је новозатражена област већа од 16 КБ, тада ће област података бити увећана додељивањем нове области са брк системским позивом пошто област два не може да се користи. Иако област број два није у употреби, апликација не може да је користи због разлике у величини. Због оваквих сценарија долази до ситуације која се зове интерна фрагментација, и заправо ретко можете да искористите све делове меморије до краја.

Ради бољег разумевања, покушајте да компајлирате и покренете следећи пример апликације:

#инцлуде <стдио.х>
#инцлуде <стдлиб.х>
#инцлуде <унистд.х>
интглавни(инт аргц, цхар* аргв[])
{
цхар *птр[7];
инт н;
принтф("Пид од %с: %д", аргв[0], гетпид());
принтф("Почетна пауза програма: %п", сбрк (0));
за (н=0; н<5; н++) птр[н] = маллоц (16 * 1024);
принтф("После 5 к 16кБ маллоц: %п", сбрк (0));
бесплатно(птр[1]);
принтф("Након ослобађања од других 16 кБ: %п", сбрк (0));
птр[5] = маллоц (16 * 1024);
принтф("Након доделе 6. од 16 кБ: %п", сбрк (0));
бесплатно(птр[5]);
принтф("Након ослобађања последњег блока: %п", сбрк (0));
птр[6] = маллоц (18 * 1024);
принтф("Након доделе нових 18 кБ: %п", сбрк (0));
гетцхар();
повратак0;
}

Када покренете апликацију, добићете резултат сличан следећем излазу:

Пид оф ./а.оут: 31990
Почетни програм пауза: 0к55ебцадф4000
После 5 к 16 кБ маллоц: 0к55ебцадф4000
Након ослобађања од других 16 кБ: 0к55ебцадф4000
Након доделе 6. од 16 кБ: 0к55ебцадф4000
Након ослобађања последњег блока: 0к55ебцадф4000
Након доделе а Нова18кБ: 0к55ебцадф4000

Излаз за брк са страцеом ће бити следећи:

брк(НУЛА) = 0к5608595б6000
брк (0к5608595д7000) = 0к5608595д7000

Као што видите, 0к21000 је додато на крајњу адресу поља података. То можете разумети из вредности 0к5608595д7000. Тако отприлике 0к21000, или је додељено 132 КБ меморије.

Овде треба размотрити две важне тачке. Први је додела више од износа наведеног у узорку кода. Други је који ред кода је изазвао брк позив који је обезбедио алокацију.

Рандомизација распореда адресног простора: АСЛР

Када покренете горњи пример апликације једну за другом, сваки пут ћете видети различите вредности адресе. Насумична промена адресног простора на овај начин значајно отежава рад безбедносне нападе и повећава безбедност софтвера.

Међутим, у 32-битним архитектурама, осам битова се генерално користи за насумично подешавање адресног простора. Повећање броја битова неће бити прикладно јер ће адресабилна област преко преосталих битова бити веома мала. Такође, употреба само 8-битних комбинација не отежава ствари довољно за нападача.

У 64-битним архитектурама, с друге стране, пошто постоји превише битова који се могу доделити за АСЛР рад, обезбеђена је много већа случајност, а степен безбедности се повећава.

Линук кернел такође има моћ Андроид уређаји а АСЛР функција је у потпуности активирана на Андроиду 4.0.3 и новијим верзијама. Чак и само из овог разлога, не би било погрешно рећи да 64-битни паметни телефон пружа значајну безбедносну предност у односу на 32-битне верзије.

Привременим онемогућавањем АСЛР функције следећом командом, испоставиће се да претходна тест апликација враћа исте вредности адресе сваки пут када се покрене:

одјек0 | судо тее /проц/сис/кернел/рандомизе_ва_спаце

Да бисте га вратили у претходно стање, биће довољно да у исту датотеку упишете 2 уместо 0.

Други системски позив: ммап

ммап је други системски позив који се користи за доделу меморије на Линук-у. Са ммап позивом, слободни простор у било којој области меморије се пресликава у адресни простор процеса који позива.

У овако урађеној додели меморије, када желите да вратите другу партицију од 16 КБ са функцијом фрее() у претходном примеру брк, не постоји механизам који би спречио ову операцију. Релевантни меморијски сегмент се уклања из адресног простора процеса. Означава се као да се више не користи и враћа се у систем.

Пошто су алокације меморије са ммап веома споре у поређењу са онима са брк, брк алокација је потребна.

Са ммап, било која слободна област меморије се мапира у адресни простор процеса, тако да се садржај додељеног простора ресетује пре него што се овај процес заврши. Ако ресетовање није обављено на овај начин, подацима који припадају процесу који је претходно користио релевантну меморијску област такође може приступити следећи неповезани процес. Тиме би било немогуће говорити о безбедности у системима.

Важност алокације меморије у Линуку

Алокација меморије је веома важна, посебно у питањима оптимизације и безбедности. Као што се види у горњим примерима, неразумевање овог проблема у потпуности може значити уништавање безбедности вашег система.

Чак и концепти слични пусх и поп који постоје у многим програмским језицима засновани су на операцијама алокације меморије. Бити у стању да се добро користи и овлада системском меморијом од виталног је значаја како за програмирање уграђеног система, тако и за развој безбедне и оптимизоване системске архитектуре.

Ако такође желите да уроните у развој Линук кернела, размислите о томе да прво савладате програмски језик Ц.

Кратак увод у програмски језик Ц

Реад Нект

ОбјавиТвеетОбјавиЕмаил

Повезане теме

  • Линук
  • Меморија рачунара
  • Линук Кернел

О аутору

Фатих Куцуккаракурт (Објављено 7 чланака)

Инжењер и програмер софтвера који је љубитељ математике и технологије. Одувек је волео компјутере, математику и физику. Развио је пројекте мотора за игре, као и машинско учење, вештачке неуронске мреже и библиотеке линеарне алгебре. Штавише, наставља да ради на машинском учењу и линеарним матрицама.

Више од Фатих Куцуккаракурт

Претплатите се на наш билтен

Придружите се нашем билтену за техничке савете, рецензије, бесплатне е-књиге и ексклузивне понуде!

Кликните овде да бисте се претплатили