feat: ajout de code en realmode pour initialisation du pmode et préparation du chargement du noyau
This commit is contained in:
parent
620f63d101
commit
21bc3d2e3d
|
@ -0,0 +1,41 @@
|
|||
/*******************************************************************************/
|
||||
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
|
||||
/* */
|
||||
#include "types.h"
|
||||
|
||||
typedef struct entrye820 {
|
||||
u64 addr;
|
||||
u64 size;
|
||||
u32 type;
|
||||
} entrye820 __attribute__((packed));
|
||||
|
||||
typedef struct miniregs {
|
||||
union {
|
||||
struct {
|
||||
u32 eax;
|
||||
u32 ebx;
|
||||
u32 ecx;
|
||||
u32 edx;
|
||||
u32 esi;
|
||||
u32 edi;
|
||||
u32 ebp;
|
||||
u32 eflags;
|
||||
};
|
||||
struct {
|
||||
u16 ax, hax;
|
||||
u16 bx, hbx;
|
||||
u16 cx, hcx;
|
||||
u16 dx, hdx;
|
||||
u16 si, hsi;
|
||||
u16 di, hdi;
|
||||
u16 bp, hbp;
|
||||
u16 flags, hflags;
|
||||
};
|
||||
struct {
|
||||
u8 bl, bh, hbx2, hbx3;
|
||||
u8 dl, dh, hdx2, hdx3;
|
||||
u8 cl, ch, hcx2, hcx3;
|
||||
u8 al, ah, hax2, hax3;
|
||||
};
|
||||
};
|
||||
} miniregs __attribute__ ((packed));
|
|
@ -1,34 +1,35 @@
|
|||
GCC=gcc -O0 -g -nostdinc -ffreestanding -fno-builtin -Wall -w -I ../include -m32 -fno-pie -no-pie -c -o
|
||||
GCCREAL=gcc -O0 -g -nostdinc -ffreestanding -fno-builtin -Wall -w -I ../include -m16 -fomit-frame-pointer -fno-pic -mno-mmx -mno-sse -mstack-alignment=4 -mno-80387 -mno-fp-ret-in-387 -c -o
|
||||
ASM=gcc -nostdinc -ffreestanding -fno-builtin -m32 -c -fno-pie -no-pie
|
||||
LINK=ld -m elf_i386 -n -o
|
||||
CONVERT=dos2unix
|
||||
INDENT=indent -nhnl -l75 -ppi3 -ts8 -bls -nbc -di8 -nbad -nbap -nsob -i8 -bl -bli0 -ncdw -nce -cli8 -cbi0 -npcs -cs -saf -sai -saw -nprs -lp -npsl
|
||||
REMOVE=rm -f
|
||||
CHANGEPERM=chmod 644
|
||||
NM=nm
|
||||
ZOFFSET=sed -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(startup_32\|startup_64\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|input_data\|_end\|_ehead\|_text\|z_.*\)$$/\#define ZO_\2 0x\1/p'
|
||||
VOFFSET=sed -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(_text\|__bss_start\|_end\)$$/\#define VO_\2 _AC(0x\1,UL)/p'
|
||||
|
||||
all: system.sys
|
||||
|
||||
system.sys: setup.bin system.bin
|
||||
system.sys: realmode/setup.bin system.bin
|
||||
$(NM) system.bin|$VOFFSET>voffset.h
|
||||
$(NM) setup.bin|$ZOFFSET>zoffset.h
|
||||
tools/build setup.bin system.bin zoffset.h system.sys
|
||||
sync
|
||||
|
||||
togit: clean indent
|
||||
|
||||
system.bin: system.o ../lib/libs.o
|
||||
$(LINK) -T linker.lds multiboot.o system.o ../lib/libs.o
|
||||
$(LINK) -T system.ld system.o ../lib/libs.o
|
||||
|
||||
setup.bin: setup.o
|
||||
$(LINK) $@ $^
|
||||
$(OBJDUMP)
|
||||
|
||||
setup.o:
|
||||
$(GCCREAL) $@ $^
|
||||
realmode/setup.bin:
|
||||
make -C realmode
|
||||
|
||||
system.o:
|
||||
$(GCC) $@ $^
|
||||
|
||||
clean:
|
||||
make -C realmode clean
|
||||
$(REMOVE) *.o
|
||||
$(REMOVE) *.out
|
||||
$(REMOVE) *.bin
|
||||
|
@ -38,6 +39,7 @@ clean:
|
|||
sync
|
||||
|
||||
indent:
|
||||
make -C realmode indent
|
||||
$(CHANGEPERM) *.c
|
||||
$(CONVERT) *.c
|
||||
$(INDENT) *.c
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
GCC=gcc -O0 -g -nostdinc -ffreestanding -fno-builtin -Wall -w -I ../../include -m16 -fomit-frame-pointer -fno-pic -mno-mmx -mno-sse -mno-80387 -mno-fp-ret-in-387 -c -o
|
||||
ASM=gcc -nostdinc -ffreestanding -fno-builtin -m16 -fomit-frame-pointer -fno-pic -mno-mmx -mno-sse -mno-80387 -mno-fp-ret-in-387 -c -o
|
||||
LINK=ld -m elf_i386 -n -o
|
||||
CONVERT=dos2unix
|
||||
INDENT=indent -nhnl -l75 -ppi3 -ts8 -bls -nbc -di8 -nbad -nbap -nsob -i8 -bl -bli0 -ncdw -nce -cli8 -cbi0 -npcs -cs -saf -sai -saw -nprs -lp -npsl
|
||||
REMOVE=rm -f
|
||||
CHANGEPERM=chmod 644
|
||||
|
||||
all: setup.bin
|
||||
sync
|
||||
|
||||
setup.bin: setupc.o setup.o
|
||||
$(LINK) -T setup.ld setupc.o setup.o
|
||||
$(OBJDUMP)
|
||||
|
||||
setupc.o: setup.c
|
||||
$(GCC) $@ $^
|
||||
|
||||
setup.o: setup.S
|
||||
$(ASM) $@ $^
|
||||
|
||||
clean:
|
||||
$(REMOVE) *.o
|
||||
$(REMOVE) *.out
|
||||
$(REMOVE) *.bin
|
||||
$(REMOVE) *.sys
|
||||
$(REMOVE) *.s
|
||||
$(REMOVE) *.c~
|
||||
sync
|
||||
|
||||
indent:
|
||||
$(CHANGEPERM) *.c
|
||||
$(CONVERT) *.c
|
||||
$(INDENT) *.c
|
||||
$(REMOVE) *.c~
|
||||
sync
|
|
@ -0,0 +1,3 @@
|
|||
/*******************************************************************************/
|
||||
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
|
||||
/* */
|
|
@ -0,0 +1,217 @@
|
|||
/*******************************************************************************/
|
||||
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
|
||||
/* */
|
||||
#include "types.h"
|
||||
#include "asm.h"
|
||||
#include "setup.h"
|
||||
|
||||
struct params {
|
||||
entrye820 *e820_table;
|
||||
u32 e820_numbers;
|
||||
u8 kbflag;
|
||||
} params;
|
||||
|
||||
#define EFLAGS_CF 0x00000001
|
||||
#define LOOPS_8042 100000
|
||||
#define FF_8042 32
|
||||
#define LOOPS_A20_ENABLE 255
|
||||
#define LOOPS_DELAY 32768
|
||||
#define SMAP 0x534d4150
|
||||
|
||||
#define interrupt(num, regs) ({\
|
||||
asm("pushal\n\
|
||||
mov %[eflagsregs],%%eax\n\
|
||||
pushl %%eax\n\
|
||||
popfl\n\
|
||||
mov %[eaxregs],%%eax\n\
|
||||
mov %[ebxregs],%%ebx\n\
|
||||
mov %[ecxregs],%%ecx\n\
|
||||
mov %[edxregs],%%edx\n\
|
||||
mov %[esiregs],%%esi\n\
|
||||
mov %[ediregs],%%edi\n\
|
||||
mov %[ebpregs],%%ebp\n\
|
||||
int %[numregs]\n\
|
||||
pushfl\n\
|
||||
popl %%eax\n\
|
||||
mov %%eax,%[eflagsregs]\n\
|
||||
mov %%eax,%[eaxregs]\n\
|
||||
mov %%ebx,%[ebxregs]\n\
|
||||
mov %%ecx,%[ecxregs]\n\
|
||||
mov %%edx,%[edxregs]\n\
|
||||
mov %%esi,%[esiregs]\n\
|
||||
mov %%edi,%[ediregs]\n\
|
||||
mov %%ebp,%[ebpregs]\n\
|
||||
popal":[eaxregs] "+m" (regs.eax),[ebxregs] "+m" (regs.ebx),[ecxregs] "+m" (regs.ecx),[edxregs] "+m" (regs.edx),[esiregs] "+m" (regs.esi),[ediregs] "+m" (regs.edi),[ebpregs] "+m" (regs.ebp),[eflagsregs] "+m" (regs.eflags):[numregs] "i" (num):);})
|
||||
|
||||
|
||||
u8 initmemory(void)
|
||||
{
|
||||
u32 count = 0;
|
||||
miniregs reg;
|
||||
entrye820 *desc = params.e820_table;
|
||||
static struct entrye820 buf;
|
||||
do {
|
||||
reg.ax = 0xe820;
|
||||
reg.cx = sizeof(buf);
|
||||
reg.edx = SMAP;
|
||||
reg.di = &buf;
|
||||
interrupt(0x15, reg);
|
||||
if (reg.eflags & EFLAGS_CF)
|
||||
break;
|
||||
if (reg.eax != SMAP)
|
||||
{
|
||||
count = 0;
|
||||
break;
|
||||
}
|
||||
*desc++ = buf;
|
||||
count++;
|
||||
} while (reg.ebx && count < ARRAY_SIZE(params.e820_table));
|
||||
return params.e820_numbers= count;
|
||||
}
|
||||
|
||||
void showchar(u8 achar)
|
||||
{
|
||||
miniregs reg;
|
||||
reg.bx = 0x0007;
|
||||
reg.cx = 0x0001;
|
||||
reg.ah = 0x0e;
|
||||
reg.al = achar;
|
||||
interrupt(0x10, reg); /* INT 10 - VIDEO - TELETYPE OUTPUT */
|
||||
}
|
||||
|
||||
void showstr(u8 *str)
|
||||
{
|
||||
while (*str!='\000')
|
||||
showchar(*str++);
|
||||
}
|
||||
|
||||
u8 gettime(void)
|
||||
{
|
||||
miniregs reg;
|
||||
reg.ah = 0x02;
|
||||
interrupt(0x1a, reg); /* TIME - GET REAL-TIME CLOCK TIME (AT,XT286,PS) */
|
||||
return reg.dh;
|
||||
}
|
||||
|
||||
u8 waitchar(void)
|
||||
{
|
||||
miniregs reg;
|
||||
reg.ah = 0x00;
|
||||
interrupt(0x16, reg); /* INT 16 - KEYBOARD - GET KEYSTROKE */
|
||||
return reg.al;
|
||||
}
|
||||
|
||||
void initkeyboard(void)
|
||||
{
|
||||
miniregs reg;
|
||||
reg.ah = 0x02;
|
||||
interrupt(0x16, reg); /* INT 16 - KEYBOARD - GET SHIFT FLAGS */
|
||||
params.kbflag=reg.al;
|
||||
reg.ah = 0x03;
|
||||
reg.al = 0x05;
|
||||
reg.bx = 0x00;
|
||||
interrupt(0x16, reg); /* INT 16 - KEYBOARD - SET TYPEMATIC RATE AND DELAY */
|
||||
}
|
||||
|
||||
u8 empty8042(void)
|
||||
{
|
||||
u8 status;
|
||||
u32 loops = LOOPS_8042;
|
||||
u8 ffs = FF_8042;
|
||||
while (loops--) {
|
||||
iodelay();
|
||||
status = inb(0x64);
|
||||
if (status == 0xff) {
|
||||
if (!--ffs)
|
||||
return NULL;
|
||||
}
|
||||
if (status & 1) {
|
||||
io_delay();
|
||||
(void)inb(0x60);
|
||||
} else if (!(status & 2)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void iodelay(void)
|
||||
{
|
||||
//asm("outb %%al,$0x80" ::);
|
||||
for(u32 loop=LOOPS_DELAY;loop>0;loop--) nop();
|
||||
}
|
||||
|
||||
|
||||
u8 testA20(void)
|
||||
{
|
||||
asm("xorw %%cx, %%cx\n\
|
||||
decw %%cx\n\
|
||||
movw %%cx, %%gs\n\
|
||||
movw $0x4000, %%cx\n\
|
||||
movw %%fs:(0x200), %%ax\n\
|
||||
pushw %%ax\n\
|
||||
1:\n\
|
||||
incw %%ax\n\
|
||||
movw %%ax, %%fs:(0x200)\n\
|
||||
call iodelay\n\
|
||||
cmpw %%gs:(0x210), %%ax\n\
|
||||
loope 1b\n\
|
||||
popw %%fs:(0x200)\n\
|
||||
xor %%ax,%%ax\n\
|
||||
je 2f\n\
|
||||
mov $0x1,%%ax\n\
|
||||
2:":::"ax","cx");
|
||||
}
|
||||
|
||||
void enableA20kbc(void)
|
||||
{
|
||||
empty8042();
|
||||
outb(0xd1, 0x64);
|
||||
empty8042();
|
||||
outb(0xdf, 0x60);
|
||||
empty8042();
|
||||
outb(0xff, 0x64);
|
||||
empty8042();
|
||||
}
|
||||
|
||||
void enableA20fast(void)
|
||||
{
|
||||
u8 port;
|
||||
port = inb(0x92);
|
||||
port |= 0x02;
|
||||
port &= ~0x01;
|
||||
outb(port, 0x92);
|
||||
}
|
||||
|
||||
u8 enableA20(void)
|
||||
{
|
||||
int loops = LOOPS_A20_ENABLE;
|
||||
int kbcerr;
|
||||
while (loops--) {
|
||||
if (testA20())
|
||||
return 1;
|
||||
kbcerr = empty8042();
|
||||
if (testA20())
|
||||
return 1;
|
||||
if (!kbcerr) {
|
||||
enableA20kbc();
|
||||
if (testA20())
|
||||
return 1;
|
||||
}
|
||||
enableA20fast();
|
||||
if (testA20())
|
||||
return NULL;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
showstr("Chargement de COS2000 - mode reel");
|
||||
initparams();
|
||||
initheap();
|
||||
initmemory();
|
||||
initkeyboard();
|
||||
initvideo();
|
||||
initpmode();
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* setup.ld
|
||||
*
|
||||
* Linker script for the i386 setup code
|
||||
*/
|
||||
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
|
||||
OUTPUT_ARCH(i386)
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = 0;
|
||||
.bstext : { *(.bstext) }
|
||||
.bsdata : { *(.bsdata) }
|
||||
|
||||
. = 495;
|
||||
.header : { *(.header) }
|
||||
.entrytext : { *(.entrytext) }
|
||||
.inittext : { *(.inittext) }
|
||||
.initdata : { *(.initdata) }
|
||||
__end_init = .;
|
||||
|
||||
.text : { *(.text) }
|
||||
.text32 : { *(.text32) }
|
||||
|
||||
. = ALIGN(16);
|
||||
.rodata : { *(.rodata*) }
|
||||
|
||||
.videocards : {
|
||||
video_cards = .;
|
||||
*(.videocards)
|
||||
video_cards_end = .;
|
||||
}
|
||||
|
||||
. = ALIGN(16);
|
||||
.data : { *(.data*) }
|
||||
|
||||
.signature : {
|
||||
setup_sig = .;
|
||||
LONG(0x5a5aaa55)
|
||||
}
|
||||
|
||||
|
||||
. = ALIGN(16);
|
||||
.bss :
|
||||
{
|
||||
__bss_start = .;
|
||||
*(.bss)
|
||||
__bss_end = .;
|
||||
}
|
||||
. = ALIGN(16);
|
||||
_end = .;
|
||||
|
||||
/DISCARD/ : { *(.note*) }
|
||||
|
||||
/*
|
||||
* The ASSERT() sink to . is intentional, for binutils 2.14 compatibility:
|
||||
*/
|
||||
. = ASSERT(_end <= 0x8000, "Setup too big!");
|
||||
. = ASSERT(hdr == 0x1f1, "The setup header has the wrong offset!");
|
||||
/* Necessary for the very-old-loader check to work... */
|
||||
. = ASSERT(__end_init <= 5*512, "init sections too big!");
|
||||
|
||||
}
|
Loading…
Reference in New Issue