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