main.c

Commit: 7f340f67 Author: jokerz Raw Copy
1
/* ============================================================================
2
 * Pactor64 Kernel Main — x86-64
3
 * Core kernel: I/O, printf, CPU detection, init sequence
4
 * ============================================================================ */
5
6
#include "types.h"
7
8
/* === GCC builtins for va_list (no libc) === */
9
typedef __builtin_va_list va_list;
10
#define va_start(ap, last) __builtin_va_start(ap, last)
11
#define va_end(ap)         __builtin_va_end(ap)
12
#define va_arg(ap, type)   __builtin_va_arg(ap, type)
13
14
/* === Port I/O === */
15
void outb(uint16_t port, uint8_t val) {
16
    __asm__ volatile ("outb %0, %1" : : "a"(val), "Nd"(port));
17
}
18
uint8_t inb(uint16_t port) {
19
    uint8_t val;
20
    __asm__ volatile ("inb %1, %0" : "=a"(val) : "Nd"(port));
21
    return val;
22
}
23
24
/* === String utilities === */
25
size_t kstrlen(const char *s) { size_t n=0; while(s[n]) n++; return n; }
26
int kstrcmp(const char *a, const char *b) { while(*a&&*a==*b){a++;b++;} return (uint8_t)*a-(uint8_t)*b; }
27
int kstrncmp(const char *a, const char *b, size_t n) { for(size_t i=0;i<n;i++){if(a[i]!=b[i])return(uint8_t)a[i]-(uint8_t)b[i];if(!a[i])return 0;}return 0; }
28
void *kmemset(void *d, int c, size_t n) { uint8_t *p=d; while(n--) *p++=(uint8_t)c; return d; }
29
void *kmemcpy(void *d, const void *s, size_t n) { uint8_t *dp=d; const uint8_t *sp=s; while(n--) *dp++=*sp++; return d; }
30
31
/* === Serial I/O (COM1) === */
32
#define COM1 0x3F8
33
34
void serial_init(void) {
35
    outb(COM1+1, 0x00);
36
    outb(COM1+3, 0x80);
37
    outb(COM1+0, 0x03);
38
    outb(COM1+1, 0x00);
39
    outb(COM1+3, 0x03);
40
    outb(COM1+2, 0xC7);
41
    outb(COM1+4, 0x0B);
42
}
43
44
void serial_putc(char c) {
45
    while (!(inb(COM1+5) & 0x20)) {}
46
    outb(COM1, c);
47
}
48
49
void serial_puts(const char *s) { while(*s) serial_putc(*s++); }
50
51
int serial_poll(void) { return inb(COM1+5) & 0x01; }
52
int serial_getc(void) { return serial_poll() ? inb(COM1) : -1; }
53
54
/* === Number printing === */
55
void kprint_hex(uint64_t val) {
56
    serial_puts("0x");
57
    for (int i = 60; i >= 0; i -= 4) {
58
        int n = (val >> i) & 0xF;
59
        serial_putc(n < 10 ? '0'+n : 'A'+n-10);
60
    }
61
}
62
63
void kprint_dec(uint64_t val) {
64
    if (!val) { serial_putc('0'); return; }
65
    char buf[21]; int i = 0;
66
    while (val) { buf[i++] = '0'+(val%10); val /= 10; }
67
    while (i > 0) serial_putc(buf[--i]);
68
}
69
70
/* === kprintf === */
71
void kprintf(const char *fmt, ...) {
72
    va_list ap;
73
    va_start(ap, fmt);
74
    for (int i = 0; fmt[i]; i++) {
75
        if (fmt[i] == '%' && fmt[i+1]) {
76
            i++;
77
            switch (fmt[i]) {
78
                case 'd': kprint_dec(va_arg(ap, uint64_t)); break;
79
                case 'x': kprint_hex(va_arg(ap, uint64_t)); break;
80
                case 's': { const char *s = va_arg(ap, const char*);
81
                            serial_puts(s ? s : "(null)"); break; }
82
                case 'c': serial_putc((char)va_arg(ap, int)); break;
83
                case '%': serial_putc('%'); break;
84
                default:  serial_putc('%'); serial_putc(fmt[i]); break;
85
            }
86
        } else serial_putc(fmt[i]);
87
    }
88
    va_end(ap);
89
}
90
91
/* === Assembly functions === */
92
extern void idt_init(void);
93
extern void pic_remap(int offset1, int offset2);
94
95
/* === Module init functions === */
96
extern void timer_init(uint32_t hz);
97
extern void keyboard_init(void);
98
extern void pmm_init(uint64_t mb2_info);
99
extern void heap_init(void);
100
extern void vga_init(void);
101
extern void vga_clear(void);
102
extern void vga_puts(const char *s);
103
extern void ata_init(void);
104
extern void syscall_init(void);
105
extern void shell_init(void);
106
107
extern void shell_run(void);
108
109
extern uint64_t kernel_end;
110
111
/* === Timer tick counter (from isr.asm) === */
112
extern volatile uint64_t timer_ticks;
113
114
/* === CPU Detection === */
115
static void detect_cpu(void) {
116
    uint32_t eax, ebx, ecx, edx;
117
    char vendor[13] = {0};
118
    __asm__ volatile ("cpuid":"=a"(eax),"=b"(ebx),"=c"(ecx),"=d"(edx):"a"(0));
119
    *(uint32_t*)&vendor[0]=ebx; *(uint32_t*)&vendor[4]=edx; *(uint32_t*)&vendor[8]=ecx;
120
    kprintf("  CPU Vendor:     %s\n", vendor);
121
    __asm__ volatile ("cpuid":"=a"(eax),"=d"(edx):"a"(1));
122
    kprintf("  Family/Model:   %d/%d Stepping %d\n", (eax>>8)&0xF, (eax>>4)&0xF, eax&0xF);
123
    kprintf("  Features:       ");
124
    if(edx&(1<<4))  kprintf("TSC ");
125
    if(edx&(1<<8))  kprintf("CX8 ");
126
    if(edx&(1<<23)) kprintf("MMX ");
127
    if(edx&(1<<25)) kprintf("SSE ");
128
    if(edx&(1<<26)) kprintf("SSE2 ");
129
    __asm__ volatile ("cpuid":"=a"(eax),"=d"(edx):"a"(0x80000001));
130
    if(edx&(1<<29)) kprintf("LM ");
131
    kprintf("\n");
132
}
133
134
static void dump_registers(void) {
135
    uint64_t rsp, cr0, cr3, cr4;
136
    __asm__ volatile ("mov %%rsp,%0":"=r"(rsp));
137
    __asm__ volatile ("mov %%cr0,%0":"=r"(cr0));
138
    __asm__ volatile ("mov %%cr3,%0":"=r"(cr3));
139
    __asm__ volatile ("mov %%cr4,%0":"=r"(cr4));
140
    kprintf("  RSP:            %x\n", rsp);
141
    kprintf("  CR0:            %x (PE=%d PG=%d)\n", cr0, cr0&1, (cr0>>31)&1);
142
    kprintf("  CR3 (PML4):     %x\n", cr3);
143
    kprintf("  CR4:            %x (PAE=%d)\n", cr4, (cr4>>5)&1);
144
}
145
146
/* === Exception Handler === */
147
void exception_handler(uint64_t int_num, uint64_t err_code, uint64_t rip) {
148
    kprintf("\n*** EXCEPTION %d at RIP %x err=%x ***\n", int_num, rip, err_code);
149
    for (;;) __asm__ volatile ("cli; hlt");
150
}
151
152
/* === Kernel Main === */
153
void kernel_main_64(uint64_t mb2_info, uint64_t mb2_magic) {
154
    serial_init();
155
156
    kprintf("\n========================================\n");
157
    kprintf("  Pactor64 — x86-64 Kernel\n");
158
    kprintf("  Built from NT source code analysis\n");
159
    kprintf("========================================\n\n");
160
161
    if (mb2_magic == 0x36D76289) kprintf("  [OK] Multiboot2 verified\n");
162
    else kprintf("  [WARN] Multiboot magic: %x\n", mb2_magic);
163
164
    detect_cpu();
165
    dump_registers();
166
167
    /* PIC + IDT */
168
    pic_remap(0x20, 0x28);
169
    kprintf("  [OK] PIC remapped (IRQs 0x20-0x2F)\n");
170
    idt_init();
171
    kprintf("  [OK] IDT initialized (256 vectors, 64-bit)\n");
172
173
    /* Enable interrupts */
174
    __asm__ volatile ("sti");
175
    kprintf("  [OK] Interrupts enabled\n");
176
177
    /* Timer */
178
    timer_init(100);
179
    kprintf("  [OK] PIT timer at 100 Hz\n");
180
181
    /* Keyboard */
182
    keyboard_init();
183
    kprintf("  [OK] PS/2 keyboard initialized\n");
184
185
    /* Physical memory */
186
    pmm_init(mb2_info);
187
188
    /* Heap */
189
    heap_init();
190
    syscall_init();
191
    kprintf("  [OK] SYSCALL interface (STAR/LSTAR MSRs)\n");
192
193
    /* VGA */
194
    vga_init();
195
    vga_clear();
196
    vga_puts("Pactor64 VGA active.\n");
197
    kprintf("  [OK] VGA text mode (80x25)\n");
198
199
    /* ATA */
200
    ata_init();
201
202
    kprintf("\n  Kernel at 0x100000, end at %x\n", (uint64_t)&kernel_end);
203
    kprintf("  PML4 at ");
204
    uint64_t cr3; __asm__ volatile ("mov %%cr3,%0":"=r"(cr3));
205
    kprint_hex(cr3);
206
    kprintf("\n\n");
207
208
    /* Shell */
209
    shell_init();
210
211
    shell_run();
212
213
    kprintf("\n  System halted.\n");
214
    for (;;) __asm__ volatile ("cli; hlt");
215
}
216