рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рдореЗрдВ, рд╣рдордиреЗ IA-32 рд╕рдВрд░рдХреНрд╖рд┐рдд рдореЛрдб рдореЗрдВ рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдореВрд▓ рдмрд╛рддреЛрдВ рдХреА рдЬрд╛рдВрдЪ рдХреАред рдЖрдЬ рдпрд╣ рдЬрд╛рдирдиреЗ рдХрд╛ рд╕рдордп рд╣реИ рдХрд┐ рд╡рд░реНрдЪреБрдЕрд▓ рдПрдбреНрд░реЗрд╕ рд╕реНрдкреЗрд╕ рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рдХрд╛рдо рдХрд┐рдпрд╛ рдЬрд╛рдПред
рд╕рд╛рдордЧреНрд░реА рдХреА рддрд╛рд▓рд┐рдХрд╛
рдмрд┐рд▓реНрдб рд╕рд┐рд╕реНрдЯрдо (рдореЗрдХ, рдЬреАрд╕реАрд╕реА, рдЧреИрд╕)ред рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдмреВрдЯ (рдорд▓реНрдЯреАрдмреВрдЯ)ред рд▓реЙрдиреНрдЪ (qemu)ред рд╕реА рд▓рд╛рдЗрдмреНрд░реЗрд░реА (strcpy, memcpy, strext)ред
рд╕реА рд▓рд╛рдЗрдмреНрд░реЗрд░реА (рд╕реНрдкреНрд░рд┐рдВрдЯрдл, рд╕реНрдЯреНрд░реИрдЪреА, рд╕реНрдЯреНрд░реИрдореНрдк, рд╕реНрдЯреНрд░реЗрдЯреЛрдХ, рд╡рд╛_рд▓рд┐рд╕реНрдЯ ...)ред рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рдХрд░реНрдиреЗрд▓ рдореЛрдб рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЛрдб рдореЗрдВ рдмрдирд╛рдирд╛ред
рдХрд░реНрдиреЗрд▓ рд╕рд┐рд╕реНрдЯрдо рд▓реЙрдЧред рд╡реАрдбрд┐рдпреЛ рдореЗрдореЛрд░реА рдЯрд░реНрдорд┐рдирд▓ рдХрд╛ рдЖрдЙрдЯрдкреБрдЯ (kprintf, kpanic, kassert)ред
рдбрд╛рдпрдиреЗрдорд┐рдХ рдореЗрдореЛрд░реА, рд╣реАрдк (kmalloc, kfree)ред
рдореЗрдореЛрд░реА рдФрд░ рдЗрдВрдЯрд░рдкреНрдЯ рд╣реИрдВрдбрд▓рд┐рдВрдЧ (GDT, IDT, PIC, syscall) рдХрд╛ рд╕рдВрдЧрдардиред рдЕрдкрд╡рд╛рджред
рд╡рд░реНрдЪреБрдЕрд▓ рдореЗрдореЛрд░реА (рдкреЗрдЬ рдбрд╛рдпрд░реЗрдХреНрдЯрд░реА рдФрд░ рдкреЗрдЬ рдЯреЗрдмрд▓)редрдкреНрд░рдХреНрд░рд┐рдпрд╛ред рд╕рдордпрдмрджреНрдзрдХред рдорд▓реНрдЯреАрдЯрд╛рд╕реНрдХрд┐рдВрдЧред рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ (рдорд╛рд░, рдирд┐рдХрд╛рд╕, рдкреАрдПрд╕)ред
рдХрд░реНрдиреЗрд▓ рдХреА рдлрд╝рд╛рдЗрд▓ рдкреНрд░рдгрд╛рд▓реА (initrd), рдпреЛрдЧрд┐рдиреА, рдФрд░ рдЗрд╕рдХреЗ рдЖрдВрддрд░рд┐рдХред рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ (рдирд┐рд╖реНрдкрд╛рджрди)ред
рдЪрд░рд┐рддреНрд░ рдбрд┐рд╡рд╛рдЗрд╕ рдбреНрд░рд╛рдЗрд╡рд░ред рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ (ioctl, fopen, fread, fwrite)ред рд╕реА рд▓рд╛рдЗрдмреНрд░реЗрд░реА (fopen, fclose, fprintf, fscanf)ред
рдХрд░реНрдиреЗрд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреВрд░реНрдг рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рд░реВрдк рдореЗрдВ рд╢реЗрд▓ред
рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реБрд░рдХреНрд╖рд╛ рдореЛрдб (рд░рд┐рдВрдЧ 3)ред рдЯрд╛рд╕реНрдХ рд╕реНрдЯреЗрдЯрд╕ рд╕реЗрдЧрдореЗрдВрдЯ (tss)ред
рдЖрднрд╛рд╕реА рд╕реНрдореГрддрд┐
рд╡рд░реНрдЪреБрдЕрд▓ рдореЗрдореЛрд░реА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рджреВрд╕рд░реЗ рд╕реЗ рдЕрд▓рдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗ, рдЕрд░реНрдерд╛рддреНред рдЙрд╕реЗ рд░реЛрдХ рдирд╣реАрдВ рд╕рдХреЗред рдЕрдЧрд░ рдХреЛрдИ рд╡рд░реНрдЪреБрдЕрд▓ рдореЗрдореЛрд░реА рдирд╣реАрдВ рд╣реЛрддреА, рддреЛ рд╣рдореЗрдВ рд╣рд░ рдмрд╛рд░ рдореЗрдореЛрд░реА рдореЗрдВ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкрддреЗ рдкрд░ рдПрд▓реНрдл рдлрд╛рдЗрд▓ рд▓реЛрдб рдХрд░рдиреА рдкрдбрд╝рддреАред рд▓реЗрдХрд┐рди рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ, рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдлрд╝рд╛рдЗрд▓реЛрдВ рдореЗрдВ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкрддреЛрдВ (рдкреВрд░реНрдг) рдХреЗ рд▓рд┐рдВрдХ рд╢рд╛рдорд┐рд▓ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рдпреЛрдЧрд┐рдиреА рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рддреЗ рд╕рдордп, рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЬреНрдЮрд╛рдд рд╣реИ рдХрд┐ рдореЗрдореЛрд░реА рдореЗрдВ рдХрд┐рд╕ рдкрддреЗ рдкрд░ рд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ (рд▓рд┐рдВрдХрд░ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рджреЗрдЦреЗрдВ)ред рдЗрд╕рд▓рд┐рдП, рд╣рдо рд╡рд░реНрдЪреБрдЕрд▓ рдореЗрдореЛрд░реА рдХреЗ рдмрд┐рдирд╛ рджреЛ рдпреЛрдЧрд┐рдиреА рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рд▓реЛрдб рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред рд▓реЗрдХрд┐рди рд╡рд░реНрдЪреБрдЕрд▓ рдореЗрдореЛрд░реА рдЪрд╛рд▓реВ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдбрд╛рдпрдиреЗрдорд┐рдХ рд▓рд╛рдЗрдмреНрд░реЗрд░реА (рдЬреИрд╕реЗ рдХрд┐ .so) рд╣реИрдВ рдЬреЛ рдХрд┐рд╕реА рднреА рдкрддреЗ рдкрд░ рд▓реЛрдб рд╣реЛ рд╕рдХрддреА рд╣реИрдВред рдЙрдиреНрд╣реЗрдВ рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рдХрд┐рд╕реА рднреА рдкрддреЗ рдкрд░ рдбрд╛рдЙрдирд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЙрдирдХреЗ рдкрд╛рд╕ рдПрдХ рд░рд┐рд▓реЛрдХ рд╕реЗрдХреНрд╢рди рд╣реИред рдЗрд╕ рдЦрдВрдб рдореЗрдВ, рдЙрди рд╕рднреА рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рдЬрд╣рд╛рдВ рдкреВрд░реНрдг рдкрддреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдкрдВрдЬреАрдХреГрдд рд╣реИрдВ, рдФрд░ рдХрд░реНрдиреЗрд▓, рдЬрдм рдЗрд╕ рддрд░рд╣ рдХреА рдпреЛрдЧрд┐рдиреА рдлрд╝рд╛рдЗрд▓ рд▓реЛрдб рд╣реЛ рд░рд╣реА рд╣реЛ, рддреЛ рдЗрди рдкрддреЗ рдХреЛ рдкреЗрди рд╕реЗ рдареАрдХ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдЕрд░реНрдерд╛рддред рдЙрдиреНрд╣реЗрдВ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдФрд░ рд╡рд╛рдВрдЫрд┐рдд рдбрд╛рдЙрдирд▓реЛрдб рдкрддреЗ рдХреЗ рдмреАрдЪ рдХрд╛ рдЕрдВрддрд░ рдЬреЛрдбрд╝реЗрдВред
рд╣рдо 4 рдХрд┐рд▓реЛрдмрд╛рдЗрдЯ рдкреГрд╖реНрдареЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рд╣рдо рдЕрдзрд┐рдХрддрдо 4 рдореЗрдЧрд╛рдмрд╛рдЗрдЯ рд░реИрдо рдХреЛ рд╕рдВрдмреЛрдзрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЗрддрдирд╛ рд╣реА рдХрд╛рдлреА рд╣реИред рдкрддрд╛ рдорд╛рдирдЪрд┐рддреНрд░ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:
0-1 рдПрдордмреА : рд╕реНрдкрд░реНрд╢ рди рдХрд░реЗрдВред
1-2 mb : рдХреЛрдб рдФрд░ рдХрд░реНрдиреЗрд▓ рдбреЗрдЯрд╛ред
2-3 рдПрдордмреА : рдЧреБрдард▓реА рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛ред
3-4 рдПрдордмреА : рдПрд▓реНрдл рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рдХрд╕реНрдЯрдо рдкреЗрдЬ рдЕрдкрд▓реЛрдб рдХрд┐рдП рдЧрдПред
рдкреЗрдЬ рдкреЗрдЬрд┐рдВрдЧ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдкрд░ рд░реИрдЦрд┐рдХ рдкрддрд╛ (рдлреНрд▓реИрдЯ рдореЙрдбрд▓ рд╕реЗ рдкреНрд░рд╛рдкреНрдд) рднреМрддрд┐рдХ рдПрдХ рдХреЗ рдмрд░рд╛рдмрд░ рдирд╣реАрдВ рд╣реИред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рдкрддрд╛ рдСрдлрд╕реЗрдЯ (рдХрдо-рдСрд░реНрдбрд░ рдмрд┐рдЯреНрд╕), рдкреЗрдЬ рдЯреЗрдмрд▓ рдореЗрдВ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХреЗ рд╕реВрдЪрдХрд╛рдВрдХ рдФрд░ рдкреЗрдЬ рдбрд╛рдпрд░реЗрдХреНрдЯрд░реА (рд╣рд╛рдИ-рдСрд░реНрдбрд░ рдмрд┐рдЯреНрд╕) рдХреЗ рд╕реВрдЪрдХрд╛рдВрдХ рд╕реЗ рд╡рд┐рднрд╛рдЬрд┐рдд рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдкреГрд╖реНрдареЛрдВ рдХреА рдЕрдкрдиреА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рд╣реЛрдЧреА рдФрд░, рддрджрдиреБрд╕рд╛рд░, рдЯреЗрдмрд▓ рдЯреЗрдмрд▓ред рдпрд╣ рд╡рд╣ рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рд╡рд░реНрдЪреБрдЕрд▓ рдПрдбреНрд░реЗрд╕ рд╕реНрдкреЗрд╕ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
рдкреГрд╖реНрда рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддреА рд╣реИ:
struct page_directory_entry_t { u8 present : 1; u8 read_write : 1; u8 user_supervisor : 1; u8 write_through : 1; u8 cache_disabled : 1; u8 accessed : 1; u8 zero : 1; u8 page_size : 1; u8 ignored : 1; u8 available : 3; u32 page_table_addr : 20; } attribute(packed);
рдкреГрд╖реНрда рддрд╛рд▓рд┐рдХрд╛ рддрддреНрд╡ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
struct page_table_entry_t { u8 present : 1; u8 read_write : 1; u8 user_supervisor : 1; u8 write_through : 1; u8 cache_disabled : 1; u8 accessed : 1; u8 dirty : 1; u8 zero : 1; u8 global : 1; u8 available : 3; u32 page_phys_addr : 20; } attribute(packed);
рдХрд░реНрдиреЗрд▓ рдХреЗ рд▓рд┐рдП, рд╣рдо рдкреЗрдЬ рдбрд╛рдпрд░реЗрдХреНрдЯрд░реА рдФрд░ рдкреЗрдЬ рдЯреЗрдмрд▓ рдХреЛ рд╕реНрдЯреИрдЯрд┐рдХ рд╡реЗрд░рд┐рдПрдмрд▓реНрд╕ рдХреЗ рд░реВрдк рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдХрд░реЗрдВрдЧреЗред рд╕рдЪ рд╣реИ, рдПрдХ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдЙрдиреНрд╣реЗрдВ рдкреГрд╖реНрда рд╕реАрдорд╛ рдкрд░ рд╕рдВрд░реЗрдЦрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПред
static struct page_directory_entry_t kpage_directory attribute(aligned(4096)); static struct page_table_entry_t kpage_table[MMU_PAGE_TABLE_ENTRIES_COUNT] attribute(aligned(4096));
рд╣рдо рд╕рд░рд▓ рддрд░реАрдХреЗ рд╕реЗ рдЬрд╛рдПрдВрдЧреЗ рдФрд░ рдкреВрд░реЗ рднреМрддрд┐рдХ рдкрддрд╛ рд╕реНрдерд╛рди рдХреЛ рдХрд░реНрдиреЗрд▓ рдХреЗ рд▓рд┐рдП рд╕реБрд▓рдн рдмрдирд╛ рджреЗрдВрдЧреЗред рдХрд░реНрдиреЗрд▓ рдкреГрд╖реНрдареЛрдВ рдХрд╛ рд╡рд┐рд╢реЗрд╖рд╛рдзрд┐рдХрд╛рд░ рд╕реНрддрд░ рдПрдХ рдкрд░реНрдпрд╡реЗрдХреНрд╖рдХ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рддрд╛рдХрд┐ рдХреЛрдИ рдЙрди рдкрд░ рдЪрдврд╝ рди рдЬрд╛рдПред рд▓рд╛рдЗрдЯрд╡реЗрдЯ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдПрдВ рдЬреЛ рдХрд░реНрдиреЗрд▓ рдореЛрдб рдореЗрдВ рдЪрд▓рдиреА рдЪрд╛рд╣рд┐рдП, рд╡рд╣реА рдкрддрд╛ рд╕реНрдерд╛рди рдХреЛ рдХрд░реНрдиреЗрд▓ рдХреЗ рд╕рд╛рде рд╕рд╛рдЭрд╛ рдХрд░реЗрдЧрд╛ред рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд╕рд╛рде, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд▓рдВрдмрд┐рдд рд╡реНрдпрд╡рдзрд╛рдиреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдирд┐рд╖реНрдкрд╛рджрди рдирд┐рд╖реНрдкрд╛рджрди рдХрддрд╛рд░ рд╣реЛрдЧреАред рд▓реЗрдХрд┐рди рдЪрд░рд┐рддреНрд░ рдбрд┐рд╡рд╛рдЗрд╕ рдбреНрд░рд╛рдЗрд╡рд░реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрд╛рда рдореЗрдВ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХред рдЗрд╕ рд╡рд┐рд╖рдп рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╣рдореЗрдВ рдЕрднреА рддрдХ рдорд▓реНрдЯреАрдЯрд╛рд╕реНрдХрд┐рдВрдЧ рдХрд╛ рдПрд╣рд╕рд╛рд╕ рдХрд░рдирд╛ рд╣реИред
рдХрд░реНрдиреЗрд▓ рдкреГрд╖реНрдареЛрдВ рдХреА рдПрдХ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдФрд░ рдПрдХ рд╕рдВрдмрдВрдзрд┐рдд рдкреГрд╖реНрда рддрд╛рд▓рд┐рдХрд╛ рдмрдирд╛рдПрдВред рдЬрдм рдХрд░реНрдиреЗрд▓ рдХреЛ рдкреНрд░рд╛рд░рдВрдн рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рд╕рдХреНрд░рд┐рдп рд╣реЛрдЧрд╛ред
extern void mmu_init() { memset(&kpage_directory, 0, sizeof(struct page_directory_entry_t)); kpage_directory.zero = 1; kpage_directory.accessed = 0; kpage_directory.available = 0; kpage_directory.cache_disabled = 0; kpage_directory.ignored = 0; kpage_directory.page_size = 0; kpage_directory.present = 1; kpage_directory.read_write = 1; kpage_directory.user_supervisor = 1; kpage_directory.write_through = 1; kpage_directory.page_table_addr = (size_t)kpage_table >> 12; for (int i = 0; i < MMU_PAGE_TABLE_ENTRIES_COUNT; ++i) { kpage_table[i].zero = 0; kpage_table[i].accessed = 0; kpage_table[i].available = 0; kpage_table[i].cache_disabled = 0; kpage_table[i].dirty = 0; kpage_table[i].global = 1; kpage_table[i].present = 1; kpage_table[i].read_write = 1; kpage_table[i].user_supervisor = 1; kpage_table[i].write_through = 1; kpage_table[i].page_phys_addr = (i * 4096) >> 12; } }
рдЬрдм рд╣рдо рдпреЛрдЧрд┐рдиреА рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдЕрдкрд▓реЛрдб рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреГрд╖реНрда рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдЖрдк рдЗрд╕реЗ рдирд┐рдореНрди рдХрд╛рд░реНрдп рдХреЗ рд╕рд╛рде рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
extern struct page_directory_entry_t* mmu_create_user_page_directory(struct page_table_entry_t* page_table) { struct page_directory_entry_t* upage_dir; upage_dir = malloc_a(sizeof(struct page_directory_entry_t), 4096); upage_dir->zero = 1; upage_dir->accessed = 0; upage_dir->available = 0; upage_dir->cache_disabled = 0; upage_dir->ignored = 0; upage_dir->page_size = 0; upage_dir->present = 1; upage_dir->read_write = 1; upage_dir->user_supervisor = 0; upage_dir->write_through = 1; upage_dir->page_table_addr = (size_t)page_table >> 12; return upage_dir; }
рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдкреГрд╖реНрда рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдХрд░реНрдиреЗрд▓ рдкреГрд╖реНрда рдФрд░ рднрд╡рд┐рд╖реНрдп рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдкреГрд╖реНрдареЛрдВ рдХреЗ рд▓рд┐рдП рд░рд┐рдХреНрдд рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпрд╛рдБ рд╣реЛрдВрдЧреА, рдЕрд░реНрдерд╛рддреНред рд╡рд░реНрддрдорд╛рди рдзреНрд╡рдЬ рдХреЗ рд╕рд╛рде рд░рд┐рдХреЙрд░реНрдб рд╕рд╛рдлрд╝ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдФрд░ 0 рдкрд░ рднреМрддрд┐рдХ рдкреГрд╖реНрда рдХрд╛ рдкрддрд╛ред
extern struct page_table_entry_t* mmu_create_user_page_table() { struct page_table_entry_t* upage_table; upage_table = malloc_a(sizeof(struct page_table_entry_t) * MMU_PAGE_TABLE_ENTRIES_COUNT, 4096); memcpy(upage_table, kpage_table, sizeof(struct page_table_entry_t) * MMU_KERNEL_PAGES_COUNT); for (int i = MMU_KERNEL_PAGES_COUNT; i < MMU_PAGE_TABLE_ENTRIES_COUNT; ++i) { struct page_table_entry_t* current; current = upage_table + i; current->zero = 0; current->accessed = 0; current->available = 0; current->cache_disabled = 0; current->dirty = 0; current->global = 1; current->present = 0; current->read_write = 1; current->user_supervisor = 0; current->write_through = 1; current->page_phys_addr = 0; } return upage_table; }
рд╣рдореЗрдВ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдкреГрд╖реНрда рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдирдП рднреМрддрд┐рдХ рдкреГрд╖реНрдареЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рд╕реАрдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдХреЛрдИ рднреА рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рдЬрдм рд╣рдо рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╣реЗрдбрд░ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рд╕реЗрдЧрдореЗрдВрдЯ рдХреЛ рд▓реЛрдб рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдореЗрдореЛрд░реА рдореЗрдВ рдПрд▓реНрдл рдлрд╛рдЗрд▓ рд▓реЛрдб рдХрд░рддреЗ рд╕рдордп рд╣рдореЗрдВ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рд╕рдорд╛рд░реЛрд╣ рд╣рдореЗрдВ рдЗрд╕рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛:
extern bool mmu_occupy_user_page(struct page_table_entry_t* upage_table, void* phys_addr) { for (int i = MMU_KERNEL_PAGES_COUNT; i < MMU_PAGE_TABLE_ENTRIES_COUNT; ++i) { struct page_table_entry_t* current; current = upage_table + i; if (current->present) { continue; } current->zero = 0; current->accessed = 0; current->available = 0; current->cache_disabled = 0; current->dirty = 0; current->global = 1; current->present = 1; current->read_write = 1; current->user_supervisor = 0; current->write_through = 1; current->page_phys_addr = (size_t)phys_addr >> 12; return true; } return false; }
рдкреЗрдЬрд┐рдВрдЧ рдореЛрдб рдХреЛ рдкреНрд░реЛрд╕реЗрд╕рд░ рдлреНрд▓реИрдЧ рд░рдЬрд┐рд╕реНрдЯрд░ рдореЗрдВ рдереЛрдбрд╝рд╛ рд╕рд╛ рдСрди рдФрд░ рдСрдл рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
/* * Enable paging * void asm_enable_paging(void *page_directory) */ asm_enable_paging: mov 4(%esp),%eax # page_directory mov %eax,%cr3 mov %cr0,%eax or $0x80000001,%eax # set PE & PG bits mov %eax,%cr0 ret /* * Disable paging * void asm_disable_paging() */ asm_disable_paging: mov %eax,%cr3 mov %cr0,%eax xor $0x80000000,%eax # unset PG bit mov %eax,%cr0 ret
рдЬрдм рд╣рдордиреЗ рд╕реАрдЦрд╛ рдХрд┐ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХрд╛ рдкрддрд╛ рд╕реНрдерд╛рди рдХреИрд╕реЗ рдмрдирд╛рдпрд╛ рдЬрд╛рдП, рддреЛ рд╣рдореЗрдВ рдХрд┐рд╕реА рддрд░рд╣ рднреМрддрд┐рдХ рдкреГрд╖реНрдареЛрдВ рдХреЛ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬреЛ рдПрдХ рд╡реНрдпрд╕реНрдд рд╣реИ рдФрд░ рдЬреЛ рдПрдХ рд╕реНрд╡рддрдВрддреНрд░ рд╣реИред рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд┐рдЯрдореИрдк рддрдВрддреНрд░ рд╣реИ, рдкреНрд░рддрд┐ рдкреГрд╖реНрда рдПрдХ рдмрд┐рдЯред рд╣рдо рддреАрд╕рд░реЗ рдореЗрдЧрд╛рдмрд╛рдЗрдЯ рддрдХ рдХреЗ рдкреГрд╖реНрдареЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдХрд░реНрдиреЗрд▓ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИрдВ рдФрд░ рд╣рдореЗрд╢рд╛ рд╡реНрдпрд╕реНрдд рд░рд╣рддреЗ рд╣реИрдВред рд╣рдо рддреАрд╕рд░реА рд╕реЗ рдЪреМрдереА рдореЗрдЧрд╛рдмрд╛рдЗрдЯ рддрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреГрд╖реНрдареЛрдВ рдХрд╛ рдЪрдпрди рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред
static u32 bitmap[MM_BITMAP_SIZE];
рднреМрддрд┐рдХ рдкреГрд╖реНрдареЛрдВ рдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЖрд╡рдВрдЯрд┐рдд рдФрд░ рдирд┐рдкрдЯрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╣рдо рдкреГрд╖реНрда рдХреЗ рднреМрддрд┐рдХ рдкрддреЗ рдкрд░ рдирдХреНрд╢реЗ рдореЗрдВ рд╡рд╛рдВрдЫрд┐рдд рдмрд┐рдЯ рдкрд╛рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрддред рдЕрд╕реБрд╡рд┐рдзрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╕реАрдорд┐рдд рдореЗрдореЛрд░реА рд╕реЗрд▓ рдЖрдХрд╛рд░ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рджреЛ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛: рдмрд╛рдЗрдЯ рд╕рдВрдЦреНрдпрд╛ рдФрд░ рдмрд┐рдЯ рд╕рдВрдЦреНрдпрд╛ред
extern void* mm_phys_alloc_pages(u_int count) { for (int i = 0; i < MM_DYNAMIC_PAGES_COUNT; ++i) { bool is_found = true; for (int j = 0; j < count; ++j) { is_found = is_found && !mm_get_bit(i + j); } if (is_found) { for (int j = 0; j < count; ++j) { assert(!mm_get_bit(i + j)); mm_set_bit(i + j); } return (void *)mm_get_addr(i); } } return null; } extern bool mm_phys_free_pages(void* ptr, u_int count) { size_t address = (size_t)ptr; assert(address >= MM_AREA_START); assert(address % MM_PAGE_SIZE == 0); for (int i = 0; i < MM_DYNAMIC_PAGES_COUNT; ++i) { size_t addr = mm_get_addr(i); if (addr == address) { for (int j = 0; j < count; ++j) { assert(mm_get_bit(i + j)); mm_clear_bit(i + j); } return true; } } return false; }
рдпрд╣ рдЖрдкрдХреЗ рдХрд░реНрдиреЗрд▓ рдореЗрдВ рд╡рд░реНрдЪреБрдЕрд▓ рдореЗрдореЛрд░реА рдХреЗ рд▓рд┐рдП рдкреВрд░реНрдг рд╕рдорд░реНрдерди рдХреЛ рдкреЗрд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред
рд╕рдВрджрд░реНрдн
рд╡реАрдбрд┐рдпреЛ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдореЗрдВ рд╡рд┐рд╡рд░рдг рдФрд░ рд╕реНрдкрд╖реНрдЯреАрдХрд░рдгред
рдЧрд┐рдЯ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рд╕реНрд░реЛрдд рдХреЛрдб (рдЖрдкрдХреЛ рд╕рдмрдХ 6 рд╢рд╛рдЦрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ)ред
рд╕рдВрджрд░реНрдн
1. рдЬреЗрдореНрд╕ рдореЛрд▓реЙрдпред рдЕрдкрдирд╛ рдЦреБрдж рдХрд╛ рдЦрд┐рд▓реМрдирд╛ рдпреВрдирд┐рдХреНрд╕-рдХреНрд▓реЛрди рдУрдПрд╕ рд░реЛрд▓ рдХрд░реЗрдВред
2. рджрд╛рдБрддред рдбреЙрд╕, рд╡рд┐рдВрдбреЛрдЬ, рдпреВрдирд┐рдХреНрд╕ рдХреЗ рд▓рд┐рдП рдЕрд╕реЗрдВрдмрд▓рд░
3. рдХрд▓рд╛рд╢реНрдирд┐рдХреЛрд╡ред рдЕрд╕реЗрдВрдмрд▓рд░ рдЖрд╕рд╛рди рд╣реИ!
4. рддрд╛рдирдирдмрд╛рдоред рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдоред рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдФрд░ рд╡рд┐рдХрд╛рд╕ред
5. рд░реЙрдмрд░реНрдЯ рд▓рд╡ред рд▓рд┐рдирдХреНрд╕ рдХрд░реНрдиреЗрд▓ рд╡рд┐рдХрд╛рд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рд╡рд┐рд╡рд░рдгред