Revision 6dbad63e linux-user/main.c
b/linux-user/main.c | ||
---|---|---|
1 | 1 |
/* |
2 |
* emu main |
|
2 |
* gemu main
|
|
3 | 3 |
* |
4 | 4 |
* Copyright (c) 2003 Fabrice Bellard |
5 | 5 |
* |
... | ... | |
80 | 80 |
return 0; |
81 | 81 |
} |
82 | 82 |
|
83 |
/* default linux values for the selectors */ |
|
84 |
#define __USER_CS (0x23) |
|
85 |
#define __USER_DS (0x2B) |
|
83 | 86 |
|
84 |
/* XXX: currently we use LDT entries */ |
|
85 |
#define __USER_CS (0x23|4) |
|
86 |
#define __USER_DS (0x2B|4) |
|
87 |
void write_dt(void *ptr, unsigned long addr, unsigned long limit, |
|
88 |
int seg32_bit) |
|
89 |
{ |
|
90 |
unsigned int e1, e2, limit_in_pages; |
|
91 |
limit_in_pages = 0; |
|
92 |
if (limit > 0xffff) { |
|
93 |
limit = limit >> 12; |
|
94 |
limit_in_pages = 1; |
|
95 |
} |
|
96 |
e1 = (addr << 16) | (limit & 0xffff); |
|
97 |
e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000); |
|
98 |
e2 |= limit_in_pages << 23; /* byte granularity */ |
|
99 |
e2 |= seg32_bit << 22; /* 32 bit segment */ |
|
100 |
stl((uint8_t *)ptr, e1); |
|
101 |
stl((uint8_t *)ptr + 4, e2); |
|
102 |
} |
|
103 |
|
|
104 |
uint64_t gdt_table[6]; |
|
87 | 105 |
|
88 | 106 |
void usage(void) |
89 | 107 |
{ |
... | ... | |
94 | 112 |
exit(1); |
95 | 113 |
} |
96 | 114 |
|
115 |
|
|
116 |
|
|
97 | 117 |
int main(int argc, char **argv) |
98 | 118 |
{ |
99 | 119 |
const char *filename; |
... | ... | |
149 | 169 |
|
150 | 170 |
env = cpu_x86_init(); |
151 | 171 |
|
172 |
/* linux register setup */ |
|
152 | 173 |
env->regs[R_EAX] = regs->eax; |
153 | 174 |
env->regs[R_EBX] = regs->ebx; |
154 | 175 |
env->regs[R_ECX] = regs->ecx; |
... | ... | |
157 | 178 |
env->regs[R_EDI] = regs->edi; |
158 | 179 |
env->regs[R_EBP] = regs->ebp; |
159 | 180 |
env->regs[R_ESP] = regs->esp; |
160 |
env->segs[R_CS] = __USER_CS; |
|
161 |
env->segs[R_DS] = __USER_DS; |
|
162 |
env->segs[R_ES] = __USER_DS; |
|
163 |
env->segs[R_SS] = __USER_DS; |
|
164 |
env->segs[R_FS] = __USER_DS; |
|
165 |
env->segs[R_GS] = __USER_DS; |
|
166 | 181 |
env->pc = regs->eip; |
167 | 182 |
|
168 |
#if 0 |
|
169 |
LDT[__USER_CS >> 3].w86Flags = DF_PRESENT | DF_PAGES | DF_32; |
|
170 |
LDT[__USER_CS >> 3].dwSelLimit = 0xfffff; |
|
171 |
LDT[__USER_CS >> 3].lpSelBase = NULL; |
|
172 |
|
|
173 |
LDT[__USER_DS >> 3].w86Flags = DF_PRESENT | DF_PAGES | DF_32; |
|
174 |
LDT[__USER_DS >> 3].dwSelLimit = 0xfffff; |
|
175 |
LDT[__USER_DS >> 3].lpSelBase = NULL; |
|
176 |
#endif |
|
183 |
/* linux segment setup */ |
|
184 |
env->gdt.base = (void *)gdt_table; |
|
185 |
env->gdt.limit = sizeof(gdt_table) - 1; |
|
186 |
write_dt(&gdt_table[__USER_CS >> 3], 0, 0xffffffff, 1); |
|
187 |
write_dt(&gdt_table[__USER_DS >> 3], 0, 0xffffffff, 1); |
|
188 |
cpu_x86_load_seg(env, R_CS, __USER_CS); |
|
189 |
cpu_x86_load_seg(env, R_DS, __USER_DS); |
|
190 |
cpu_x86_load_seg(env, R_ES, __USER_DS); |
|
191 |
cpu_x86_load_seg(env, R_SS, __USER_DS); |
|
192 |
cpu_x86_load_seg(env, R_FS, __USER_DS); |
|
193 |
cpu_x86_load_seg(env, R_GS, __USER_DS); |
|
177 | 194 |
|
178 | 195 |
for(;;) { |
179 | 196 |
int err; |
... | ... | |
186 | 203 |
if (pc[0] == 0xcd && pc[1] == 0x80) { |
187 | 204 |
/* syscall */ |
188 | 205 |
env->pc += 2; |
189 |
env->regs[R_EAX] = do_syscall(env->regs[R_EAX], |
|
206 |
env->regs[R_EAX] = do_syscall(env, |
|
207 |
env->regs[R_EAX], |
|
190 | 208 |
env->regs[R_EBX], |
191 | 209 |
env->regs[R_ECX], |
192 | 210 |
env->regs[R_EDX], |
Also available in: Unified diff