feat: chargement pmode complet jusqu'à lancement du code pour la décompression

This commit is contained in:
Nicolas Hordé 2019-01-15 01:15:58 +01:00
parent b565d073c7
commit 63f7e530cc
13 changed files with 159 additions and 99 deletions

View File

@ -1,7 +1,10 @@
target remote localhost:1234
set disassembly-flavor att
symbol-file ./system/realmode/setup.sym
add-symbol-file ./system/realmode/setup.sym 0x902f6
set architecture i8086
break *0x90200
cont
clear *0x90200
break main
cont
clear main

View File

@ -882,7 +882,12 @@ class Source(Dashboard.Module):
if not gdb.selected_thread().is_stopped():
return []
# try to fetch the current line (skip if no line information)
sal = gdb.selected_frame().find_sal()
arch = gdb.parameter('architecture');
if arch=="i8086":
realpc=int(gdb.parse_and_eval('$pc'))+int(gdb.parse_and_eval('$cs'))*16
sal = gdb.find_pc_line(realpc)
else:
sal = gdb.selected_frame().find_sal()
current_line = sal.line
if current_line == 0:
return []
@ -962,7 +967,12 @@ instructions constituting the current statement are marked, if available."""
if not gdb.selected_thread().is_stopped():
return []
line_info = None
arch = gdb.parameter('architecture');
frame = gdb.selected_frame() # PC is here
if arch=="i8086":
realpc=frame.pc()+int(gdb.parse_and_eval('$cs'))*16
else:
realpc=frame.pc()
disassemble = frame.architecture().disassemble
try:
# try to fetch the function boundaries using the disassemble command
@ -971,21 +981,20 @@ instructions constituting the current statement are marked, if available."""
end = int(re.split('[ :]', output[-3][3:], 1)[0], 16)
asm = disassemble(start, end_pc=end)
# find the location of the PC
pc_index = next(index for index, instr in enumerate(asm)
if instr['addr'] == frame.pc())
pc_index = next(index for index, instr in enumerate(asm) if instr['addr'] == realpc)
start = max(pc_index - self.context, 0)
end = pc_index + self.context + 1
asm = asm[start:end]
# if there are line information then use it, it may be that
# line_info is not None but line_info.last is None
line_info = gdb.find_pc_line(frame.pc())
line_info = gdb.find_pc_line(realpc)
line_info = line_info if line_info.last else None
except (gdb.error, StopIteration):
# if it is not possible (stripped binary or the PC is not present in
# the output of `disassemble` as per issue #31) start from PC and
# end after twice the context
try:
asm = disassemble(frame.pc(), count=2 * self.context + 1)
asm = disassemble(realpc, count=2 * self.context + 1)
except gdb.error as e:
msg = '{}'.format(e)
return [ansi(msg, R.style_error)]
@ -1046,7 +1055,7 @@ instructions constituting the current statement are marked, if available."""
format_string = '{}{}{}{}{}'
indicator = ' '
text = ' ' + highlighter.process(text)
if addr == frame.pc():
if addr == realpc:
if not R.ansi:
indicator = '>'
addr_str = ansi(addr_str, R.style_selected_1)

View File

@ -91,12 +91,10 @@ u8 testA20(void);
void enableA20kbc(void);
void enableA20fast(void);
u8 enableA20(void);
void memset(void *dst, u8 val, u32 count, u32 size);
void memcpy(void *src, void *dst, u32 count, u32 size);
void initselectors(u32 executingoffset);
void memcpyto(void *src, void *dst, u32 count);
void makegdtdes(u32 base, u32 limite, u8 acces, u8 flags, gdtdes * desc);
void initgdt();
void maskinterrupts(void);
void initcoprocessor(void);
void initpmode(u32 offset);
void initpmode();
void main(void);

View File

@ -1,4 +1,5 @@
/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* */
extern restart;
extern restart;
int main(u8* info);

View File

@ -6,9 +6,61 @@
#include "types.h"
#include "memory.h"
/* registre gdt */
static struct gdtr gdtreg;
/* table de GDT */
static gdtdes gdt[GDT_SIZE];
/* TSS */
static struct tss tss0;
/*******************************************************************************/
/* Créé un descripteur GDT */
void makegdtdes(u32 base, u32 limite, u8 acces, u8 flags, gdtdes * desc)
{
desc->lim0_15 = (limite & 0xffff);
desc->base0_15 = (base & 0xffff);
desc->base16_23 = (base & 0xff0000) >> 16;
desc->acces = acces;
desc->lim16_19 = (limite & 0xf0000) >> 16;
desc->flags = (flags & 0xf);
desc->base24_31 = (base & 0xff000000) >> 24;
return;
}
/*******************************************************************************/
/* Initialise la GDT */
void initgdt(u32 offset)
{
makegdtdes(0x0, 0x00000, 0x00, 0x00, &gdt[0]); /* descripteur nul */
makegdtdes(0x0, 0xFFFFF, SEG_PRESENT | SEG_NORMAL | SEG_CODE | SEG_RING0 | SEG_READ | SEG_ACCESSED, GRANULARITY_4K | OPSIZE_32B | SYS_AVAILABLE, &gdt[1]); /* code -> SEL_KERNEL_CODE */
makegdtdes(0x0, 0x00000, SEG_PRESENT | SEG_NORMAL | SEG_DATA | SEG_RING0 | SEG_EXPAND_DOWN | SEG_READ_WRITE | SEG_ACCESSED, GRANULARITY_4K | OPSIZE_32B | SYS_AVAILABLE, &gdt[2]); /* pile -> SEL_KERNEL_STACK */
makegdtdes(0x0, 0xFFFFF, SEG_PRESENT | SEG_NORMAL | SEG_CODE | SEG_RING3 | SEG_CONFORMING | SEG_READ | SEG_ACCESSED, GRANULARITY_4K | OPSIZE_32B | SYS_AVAILABLE, &gdt[3]); /* code -> SEL_USER_CODE */
makegdtdes(0x0, 0x00000, SEG_PRESENT | SEG_NORMAL | SEG_DATA | SEG_RING3 | SEG_EXPAND_DOWN | SEG_READ_WRITE | SEG_ACCESSED, GRANULARITY_4K | OPSIZE_32B | SYS_AVAILABLE, &gdt[4]); /* pile -> SEL_USER_STACK */
makegdtdes(0x0, 0xFFFFF, SEG_PRESENT | SEG_NORMAL | SEG_DATA | SEG_RING0 | SEG_READ_WRITE | SEG_ACCESSED, GRANULARITY_4K | OPSIZE_32B | SYS_AVAILABLE, &gdt[5]); /* data -> SEL_KERNEL_DATA */
makegdtdes(0x0, 0xFFFFF, SEG_PRESENT | SEG_NORMAL | SEG_DATA | SEG_RING3 | SEG_READ_WRITE | SEG_ACCESSED, GRANULARITY_4K | OPSIZE_32B | SYS_AVAILABLE, &gdt[6]); /* data -> SEL_USER_DATA */
tss0.trapflag = 0x00;
tss0.iomap = 0x00;
tss0.esp0 = 0x6000;
tss0.ss0 = SEL_TSS;
makegdtdes(&tss0, 0x67, SEG_PRESENT | SEG_CODE | SEG_RING3 | SEG_ACCESSED, 0x00, &gdt[7]); /* descripteur de tss */
/* initialise le registre gdt */
gdtreg.limite = GDT_SIZE * sizeof(gdtdes);
gdtreg.base = GDT_ADDR;
/* recopie de la GDT a son adresse */
memcpy(&gdt, (u8 *) gdtreg.base, gdtreg.limite, 1);
/* chargement du registre GDT */
lgdt(gdtreg);
/* initialisation des segments */
initselectors(offset);
}
/*******************************************************************************/
/* Initialise les selecteurs avec la GDT */

View File

@ -1,4 +1,4 @@
DEBUG=exec gnome-terminal --geometry=120x40+1+1 -x ./debug/debug.sh
DEBUG=exec gnome-terminal --geometry=120x55+1+1 -x ./debug/debug.sh
REMOVE=rm -f
INSTALL=sudo apt-get install
COPY=cp
@ -81,15 +81,15 @@ backup: clean
cd ..
tar cf - Source\ C | gzip -f - > backup.tar.gz
test: programs bits32 harddisk qemu
test: tools programs bits32 harddisk qemu
test64: programs bits64 uefi qemu64
test64: tools programs bits64 uefi qemu64
retest: littleclean test
retest64: littleclean test64
testbochs: programs bits32 harddisk bochs-debug
testbochs: tools programs bits32 harddisk bochs-debug
view:
hexdump -C ./final/harddisk.img.final|head -c10000
@ -104,15 +104,15 @@ redebug64: littleclean debug-system64
kernel: debug-kernel
debug-boot: programs bits32 harddisk qemu-debug
debug-boot: tools programs bits32 harddisk qemu-debug
sleep 2
$(DEBUG) ./debug/boot.txt
debug-system: programs bits32 harddisk qemu-debug
debug-system: tools programs bits32 harddisk qemu-debug
sleep 2
$(DEBUG) ./debug/system.txt
debug-system64: programs bits64 uefi qemu-debug64
debug-system64: tools programs bits64 uefi qemu-debug64
sleep 2
$(DEBUG) ./debug/system.txt

View File

@ -34,7 +34,7 @@ togit: clean indent
piggy.o: piggy.S
$(ASM) $@ $^
system: systemc.o system.o ../lib/libs.o
system: system.o system_asm.o ../lib/libs.o
$(LINK) -T system.ld system.o ../lib/libs.o
$(OBJDEBUG) system system.sym
$(NM) system > system.map
@ -51,10 +51,10 @@ piggy.S: system.bin.gz
realmode/setup.bin:
make -C realmode
systemc.o: system.c
system.o: system.c
$(GCC) $@ $^
system.o: system.S
system_asm.o: system_asm.S
$(ASM) $@ $^
clean:

View File

@ -1,4 +1,4 @@
GCC=gcc -O0 -g -nostdinc -ffreestanding -Wall -Wstrict-prototypes -fno-stack-protector -march=i386 -m16 -mpreferred-stack-boundary=2 -mregparm=3 -fno-pic -fno-strict-aliasing -mno-mmx -mno-sse -w -I ../../include -c
GCC=gcc -O0 -g -nostdinc -ffreestanding -Wall -Wstrict-prototypes -fno-stack-protector -march=i386 -m16 -fno-pic -fno-strict-aliasing -mno-mmx -mno-sse -w -I ../../include -c
ASM=gcc -O0 -m16 -march=i386 -fno-pic -D__ASSEMBLY__ -I ../ -I ../../include -c -o
LINK=ld -m elf_i386 -n
CONVERT=dos2unix
@ -13,8 +13,8 @@ $(eval VERSION=$(shell git describe --tags))
all: setup.bin
sync
setup: setupc.o setup.o
$(LINK) -T setup.ld setupc.o setup.o
setup: setupc.o setup.o setup32.o
$(LINK) -T setup.ld setupc.o setup.o setup32.o
setup.bin: setup
$(OBJCOPY) $^ $@
@ -27,6 +27,9 @@ setupc.o: setup.c
setup.o: setup.S
$(ASM) $@ $^
setup32.o: pmode.S
$(ASM) $@ $^
clean:
$(REMOVE) setup
$(REMOVE) *.o

40
system/realmode/pmode.S Normal file
View File

@ -0,0 +1,40 @@
#include "memory.h"
#include "gdt.h"
.text
.code16
.global gotopmode
gotopmode:
jmp 1f
1:
xorl %eax,%eax
movl %ds,%ax
shl $0x4,%eax
add %eax,(2f)
movl %cr0, %eax
orb $0x01, %al
movl %eax, %cr0
.byte 0x66, 0xea
2: .long pmode
.word SEL_KERNEL_CODE
.code32
.section ".text32","ax"
.global pmode
pmode:
movw $SEL_KERNEL_DATA, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movl $KERNEL_CODE_ADDR, %ebx
movw $SEL_KERNEL_STACK, %ax
movw %ax, %ss
movl $KERNEL_STACK_ADDR, %esp
xor %eax,%eax
xor %ecx,%ecx
xor %edx,%edx
xor %esi,%esi
xor %edi,%edi
xor %ebp,%ebp
jmp *%ebx

View File

@ -123,7 +123,7 @@ setup_move_size: .word 0x8000 # size to move, when setup is not
code32_start: # here loaders can put a different
# start address for 32-bit code.
.long 0x100000 # 0x100000 = default for big kernel
.long LOAD_PHYSICAL_ADDR # 0x100000 = default for big kernel
ramdisk_image: .long 0 # address of loaded ramdisk image
# Here the loader puts the 32-bit

View File

@ -175,86 +175,37 @@ u8 enableA20(void)
int loops = LOOPS_A20_ENABLE;
int kbcerr;
while (loops--) {
if (testA20())
return 1;
if (!testA20())
return NULL;
kbcerr = empty8042();
if (testA20())
return 1;
if (!testA20())
return NULL;
if (!kbcerr) {
enableA20kbc();
if (testA20())
return 1;
if (!testA20())
return NULL;
}
enableA20fast();
if (testA20())
if (!testA20())
return NULL;
}
return 1;
}
/*******************************************************************************/
/* Copie un octet une ou plusieurs fois en mémoire */
void memset(void *dst, u8 val, u32 count, u32 size)
{
u8 *d = (u8 *) dst;
if (size > 0)
size--;
for (; count != 0; count--)
{
*(d++) = val;
d += size;
}
}
/*******************************************************************************/
/* Copie une portion de mémoire vers une autre */
void memcpy(void *src, void *dst, u32 count, u32 size)
void memcpyto(void *src, void *dst, u32 count)
{
u8 *s = (u8 *) src;
u8 *d = (u8 *) dst;
if (size > 0)
size--;
for (; count != 0; count--)
{
*(d++) = *(s++);
d += size;
}
asm("push %%es\n\
cld\n\
xor %%eax,%%eax\n\
mov %%ax,%%es\n\
rep movsb\n\
pop %%es"::"S" (src), "D" (dst), "c" (count):);
}
/*******************************************************************************/
/* Initialise les selecteurs avec la GDT */
void initselectors(u32 executingoffset)
{
asm(" movl %%cr0, %%eax \n \
orb $0x00000001, %%eax \n \
movl %%eax, %%cr0 \n \
ljmp %[code], $raz\n\
raz:\n \
.code32\n\
movw %[data], %%ax \n \
movw %%ax, %%ds \n \
movw %%ax, %%es \n \
movw %%ax, %%fs \n \
movw %%ax, %%gs \n \
movl %[offset], %%ebx \n \
movw %[stack], %%ax \n \
movw %%ax, %%ss \n \
movl %[stackoff], %%esp \n \
xor %%eax,%%eax\n\
xor %%ebx,%%ebx\n\
xor %%ecx,%%ecx\n\
xor %%edx,%%edx\n\
xor %%esi,%%esi\n\
xor %%edi,%%edi\n\
xor %%ebp,%%ebp\n\
jmp %%ebx\n\
.code16gcc"::[data] "i"(SEL_KERNEL_DATA),[code] "i"(SEL_KERNEL_CODE),[stack] "i"(SEL_KERNEL_STACK),[stackoff] "i"(KERNEL_STACK_ADDR),[offset] "m"(executingoffset));
}
/*******************************************************************************/
/* Créé un descripteur GDT */
@ -278,16 +229,16 @@ void initgdt()
makegdtdes(0x0, 0x00000, 0x00, 0x00, &gdt[0]); /* descripteur nul */
makegdtdes(0x0, 0xFFFFF, SEG_PRESENT | SEG_NORMAL | SEG_CODE | SEG_RING0 | SEG_READ | SEG_ACCESSED, GRANULARITY_4K | OPSIZE_32B | SYS_AVAILABLE, &gdt[1]); /* code -> SEL_KERNEL_CODE */
makegdtdes(0x0, 0x00000, SEG_PRESENT | SEG_NORMAL | SEG_DATA | SEG_RING0 | SEG_EXPAND_DOWN | SEG_READ_WRITE | SEG_ACCESSED, GRANULARITY_4K | OPSIZE_32B | SYS_AVAILABLE, &gdt[2]); /* pile -> SEL_KERNEL_STACK */
makegdtdes(0x0, 0xFFFFF, SEG_PRESENT | SEG_NORMAL | SEG_CODE | SEG_RING3 | SEG_CONFORMING | SEG_READ | SEG_ACCESSED, GRANULARITY_4K | OPSIZE_32B | SYS_AVAILABLE, &gdt[3]); /* code -> SEL_USER_CODE */
makegdtdes(0x0, 0x00000, SEG_PRESENT | SEG_NORMAL | SEG_DATA | SEG_RING3 | SEG_EXPAND_DOWN | SEG_READ_WRITE | SEG_ACCESSED, GRANULARITY_4K | OPSIZE_32B | SYS_AVAILABLE, &gdt[4]); /* pile -> SEL_USER_STACK */
makegdtdes(0x0, 0x00000, 0x00, 0x00, &gdt[3]); /* LIBRE */
makegdtdes(0x0, 0x00000, 0x00, 0x00, &gdt[4]); /* LIBRE */
makegdtdes(0x0, 0xFFFFF, SEG_PRESENT | SEG_NORMAL | SEG_DATA | SEG_RING0 | SEG_READ_WRITE | SEG_ACCESSED, GRANULARITY_4K | OPSIZE_32B | SYS_AVAILABLE, &gdt[5]); /* data -> SEL_KERNEL_DATA */
makegdtdes(0x0, 0xFFFFF, SEG_PRESENT | SEG_NORMAL | SEG_DATA | SEG_RING3 | SEG_READ_WRITE | SEG_ACCESSED, GRANULARITY_4K | OPSIZE_32B | SYS_AVAILABLE, &gdt[6]); /* data -> SEL_USER_DATA */
makegdtdes(0x0, 0x67, SEG_PRESENT | SEG_CODE | SEG_RING3 | SEG_ACCESSED, 0x00, &gdt[7]); /* descripteur de tss */
makegdtdes(0x0, 0x00000, 0x00, 0x00, &gdt[6]); /* LIBRE */
makegdtdes(0x0, 0x00000, 0x00, 0x00, &gdt[7]); /* LIBRE */
/* initialise le registre gdt */
gdtreg.limite = GDT_SIZE * sizeof(gdtdes);
gdtreg.base = GDT_ADDR;
/* recopie de la GDT a son adresse */
memcpy(&gdt, (u8 *) gdtreg.base, gdtreg.limite, 1);
memcpyto(&gdt, (u8 *) gdtreg.base, gdtreg.limite);
/* chargement du registre GDT */
lgdt(gdtreg);
}
@ -311,7 +262,7 @@ void initcoprocessor(void)
iodelay();
}
void initpmode(u32 offset)
void initpmode()
{
if (enableA20()) {
showstr("impossible d'ouvrir la ligne A20...\n");
@ -319,7 +270,7 @@ void initpmode(u32 offset)
}
maskinterrupts();
initgdt();
initselectors(offset);
gotopmode();
}
void main(void)
@ -334,5 +285,5 @@ void main(void)
showstr(" -Initialisation du coprocesseur\r\n");
initcoprocessor();
showstr(" -Passage en mode protege\r\n");
initpmode(0x10000);
initpmode();
}

View File

@ -15,6 +15,7 @@
#include "shell.h"
#include "syscall.h"
#include "memory.h"
#include "system.h"
static u8 warnmsg[] =
"\033[150C\033[8D\033[37m\033[1m[ \033[36mNON\033[37m ]\033[0m";
@ -59,6 +60,8 @@ int main(u8* info)
logo();
print("\033[37m\033[0m -Initilisation de la memoire virtuelle");
initgdt(&&next);
next:
initpaging();
remap_memory(VESA_FBMEM);
ok();

View File

@ -8,9 +8,8 @@
.code32
.section ".text"
.global start
.extern main
start:
ljmp $SEL_KERNEL_CODE,$suite
suite:
movw $SEL_KERNEL_DATA, %ax
movw %ax, %ds
movw %ax, %es
@ -26,3 +25,4 @@ suite:
xor %esi,%esi
xor %edi,%edi
xor %ebp,%ebp
call main