This source file includes following definitions.
- __bad_pagetable
- __bad_page
- show_mem
- paging_init
- mem_init
- si_meminfo
1
2
3
4
5
6
7 #include <linux/config.h>
8 #include <linux/signal.h>
9 #include <linux/sched.h>
10 #include <linux/head.h>
11 #include <linux/kernel.h>
12 #include <linux/errno.h>
13 #include <linux/string.h>
14 #include <linux/types.h>
15 #include <linux/ptrace.h>
16 #include <linux/mman.h>
17 #include <linux/mm.h>
18 #include <linux/smp.h>
19
20 #include <asm/system.h>
21 #include <asm/segment.h>
22 #include <asm/pgtable.h>
23
24
25
26
27 #ifdef __SMP__
28 #undef USE_PENTIUM_MM
29 #endif
30
31 extern void die_if_kernel(char *,struct pt_regs *,long);
32 extern void show_net_buffers(void);
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 pte_t * __bad_pagetable(void)
48 {
49 extern char empty_bad_page_table[PAGE_SIZE];
50
51 __asm__ __volatile__("cld ; rep ; stosl":
52 :"a" (pte_val(BAD_PAGE)),
53 "D" ((long) empty_bad_page_table),
54 "c" (PAGE_SIZE/4)
55 :"di","cx");
56 return (pte_t *) empty_bad_page_table;
57 }
58
59 pte_t __bad_page(void)
60 {
61 extern char empty_bad_page[PAGE_SIZE];
62
63 __asm__ __volatile__("cld ; rep ; stosl":
64 :"a" (0),
65 "D" ((long) empty_bad_page),
66 "c" (PAGE_SIZE/4)
67 :"di","cx");
68 return pte_mkdirty(mk_pte((unsigned long) empty_bad_page, PAGE_SHARED));
69 }
70
71 void show_mem(void)
72 {
73 int i,free = 0,total = 0,reserved = 0;
74 int shared = 0;
75
76 printk("Mem-info:\n");
77 show_free_areas();
78 printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
79 i = high_memory >> PAGE_SHIFT;
80 while (i-- > 0) {
81 total++;
82 if (mem_map[i].reserved)
83 reserved++;
84 else if (!mem_map[i].count)
85 free++;
86 else
87 shared += mem_map[i].count-1;
88 }
89 printk("%d pages of RAM\n",total);
90 printk("%d free pages\n",free);
91 printk("%d reserved pages\n",reserved);
92 printk("%d pages shared\n",shared);
93 show_buffers();
94 #ifdef CONFIG_NET
95 show_net_buffers();
96 #endif
97 }
98
99 extern unsigned long free_area_init(unsigned long, unsigned long);
100
101
102
103
104
105
106
107
108 unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
109 {
110 pgd_t * pg_dir;
111 pte_t * pg_table;
112 unsigned long tmp;
113 unsigned long address;
114
115
116
117
118
119
120
121
122 #if 0
123 memset((void *) 0, 0, PAGE_SIZE);
124 #endif
125 #ifdef __SMP__
126 smp_scan_config(0x0,0x400);
127
128
129
130
131 smp_scan_config(639*0x400,0x400);
132 smp_scan_config(0xF0000,0x10000);
133
134
135
136
137
138
139
140 #endif
141 #ifdef TEST_VERIFY_AREA
142 wp_works_ok = 0;
143 #endif
144 start_mem = PAGE_ALIGN(start_mem);
145 address = 0;
146 pg_dir = swapper_pg_dir;
147 while (address < end_mem) {
148 #ifdef USE_PENTIUM_MM
149 if (address <= end_mem + 4*1024*1024 &&
150 (x86_capability & 8)) {
151 #ifdef GAS_KNOWS_CR4
152 __asm__("movl %%cr4,%%eax\n\t"
153 "orl $16,%%eax\n\t"
154 "movl %%eax,%%cr4"
155 : : :"ax");
156 #else
157 __asm__(".byte 0x0f,0x20,0xe0\n\t"
158 "orl $16,%%eax\n\t"
159 ".byte 0x0f,0x22,0xe0"
160 : : :"ax");
161 #endif
162 wp_works_ok = 1;
163 pgd_val(pg_dir[0]) = _PAGE_TABLE | _PAGE_4M | address;
164 pgd_val(pg_dir[768]) = _PAGE_TABLE | _PAGE_4M | address;
165 pg_dir++;
166 address += 4*1024*1024;
167 continue;
168 }
169 #endif
170
171 pg_table = (pte_t *) (PAGE_MASK & pgd_val(pg_dir[768]));
172 if (!pg_table) {
173 pg_table = (pte_t *) start_mem;
174 start_mem += PAGE_SIZE;
175 }
176
177
178 pgd_val(pg_dir[0]) = _PAGE_TABLE | (unsigned long) pg_table;
179 pgd_val(pg_dir[768]) = _PAGE_TABLE | (unsigned long) pg_table;
180 pg_dir++;
181 for (tmp = 0 ; tmp < PTRS_PER_PTE ; tmp++,pg_table++) {
182 if (address < end_mem)
183 set_pte(pg_table, mk_pte(address, PAGE_SHARED));
184 else
185 pte_clear(pg_table);
186 address += PAGE_SIZE;
187 }
188 }
189 invalidate();
190 return free_area_init(start_mem, end_mem);
191 }
192
193 void mem_init(unsigned long start_mem, unsigned long end_mem)
194 {
195 unsigned long start_low_mem = PAGE_SIZE;
196 int codepages = 0;
197 int reservedpages = 0;
198 int datapages = 0;
199 unsigned long tmp;
200 extern int _etext;
201
202 end_mem &= PAGE_MASK;
203 high_memory = end_mem;
204
205
206 memset(empty_zero_page, 0, PAGE_SIZE);
207
208
209 start_low_mem = PAGE_ALIGN(start_low_mem);
210
211 #ifdef __SMP__
212
213
214
215 start_low_mem += PAGE_SIZE;
216 start_low_mem = smp_alloc_memory(start_low_mem);
217 #endif
218 start_mem = PAGE_ALIGN(start_mem);
219
220
221
222
223
224
225 while (start_low_mem < 0x9f000) {
226 mem_map[MAP_NR(start_low_mem)].reserved = 0;
227 start_low_mem += PAGE_SIZE;
228 }
229
230 while (start_mem < high_memory) {
231 mem_map[MAP_NR(start_mem)].reserved = 0;
232 start_mem += PAGE_SIZE;
233 }
234 for (tmp = 0 ; tmp < high_memory ; tmp += PAGE_SIZE) {
235 if (mem_map[MAP_NR(tmp)].reserved) {
236 if (tmp >= 0xA0000 && tmp < 0x100000)
237 reservedpages++;
238 else if (tmp < (unsigned long) &_etext)
239 codepages++;
240 else
241 datapages++;
242 continue;
243 }
244 mem_map[MAP_NR(tmp)].count = 1;
245 free_page(tmp);
246 }
247 tmp = nr_free_pages << PAGE_SHIFT;
248 printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data)\n",
249 tmp >> 10,
250 high_memory >> 10,
251 codepages << (PAGE_SHIFT-10),
252 reservedpages << (PAGE_SHIFT-10),
253 datapages << (PAGE_SHIFT-10));
254
255 if (wp_works_ok < 0) {
256 pg0[0] = pte_val(mk_pte(0, PAGE_READONLY));
257 invalidate();
258 __asm__ __volatile__("movb 0,%%al ; movb %%al,0": : :"ax", "memory");
259 pg0[0] = 0;
260 invalidate();
261 if (wp_works_ok < 0)
262 wp_works_ok = 0;
263 }
264 return;
265 }
266
267 void si_meminfo(struct sysinfo *val)
268 {
269 int i;
270
271 i = high_memory >> PAGE_SHIFT;
272 val->totalram = 0;
273 val->sharedram = 0;
274 val->freeram = nr_free_pages << PAGE_SHIFT;
275 val->bufferram = buffermem;
276 while (i-- > 0) {
277 if (mem_map[i].reserved)
278 continue;
279 val->totalram++;
280 if (!mem_map[i].count)
281 continue;
282 val->sharedram += mem_map[i].count-1;
283 }
284 val->totalram <<= PAGE_SHIFT;
285 val->sharedram <<= PAGE_SHIFT;
286 return;
287 }