@@ -68,6 +68,18 @@ int unmap_page(uint32_t virt) {
6868 if ((pt [pt_idx ] & PAGING_PRESENT ) == 0 ) return -1 ;
6969 pt [pt_idx ] = 0 ;
7070 invlpg ((void * )virt );
71+
72+ /* check if the page table became empty -> free it and clear PDE */
73+ int empty = 1 ;
74+ for (int i = 0 ; i < 1024 ; ++ i ) {
75+ if (pt [i ] & PAGING_PRESENT ) { empty = 0 ; break ; }
76+ }
77+ if (empty ) {
78+ uint32_t pt_phys = (uint32_t )pt ; /* current identity mapping */
79+ page_directory [pd_idx ] = 0x00000000 ;
80+ free_frame ((void * )pt_phys );
81+ }
82+
7183 return 0 ;
7284}
7385
@@ -93,6 +105,28 @@ void paging_init_identity(uint32_t map_mb) {
93105 printk ("paging: identity map initialized for %u MB (pages=%u)\n" , (unsigned )map_mb , (unsigned )pages );
94106}
95107
108+ /**
109+ * @fn map_range
110+ * @brief 指定範囲を連続ページとしてマップする
111+ */
112+ int map_range (uint32_t phys_start , uint32_t virt_start , size_t size , uint32_t flags ) {
113+ if (phys_start % 0x1000 || virt_start % 0x1000 ) return -1 ;
114+ uint32_t pages = (size + 0xFFF ) / 0x1000 ;
115+ for (uint32_t i = 0 ; i < pages ; ++ i ) {
116+ if (map_page (phys_start + i * 0x1000 , virt_start + i * 0x1000 , flags ) != 0 ) {
117+ return -1 ;
118+ }
119+ }
120+ return 0 ;
121+ }
122+
123+ void page_fault_handler_ex (uint32_t vec , uint32_t error_code , uint32_t eip ) {
124+ uint32_t fault_addr ;
125+ asm volatile ("mov %%cr2, %0" : "=r" (fault_addr ));
126+ printk ("PAGE FAULT: vec=%u err=0x%x eip=0x%x cr2=0x%x\n" , (unsigned )vec , (unsigned )error_code , (unsigned )eip , (unsigned )fault_addr );
127+ while (1 ) {}
128+ }
129+
96130/**
97131 * @fn paging_enable
98132 * @brief ページングを有効化
0 commit comments