Page 2 of 3

Re: Placing kernel in 4MB in RAM on real hardware.

Posted: Thu Apr 24, 2014 12:37 am
by BASICFreak
Waszka wrote: Paging is done like that:

Code: Select all

   //! 1st 4mb are idenitity mapped
   for( i=0, frame=0x0, virt=0x00000000; i<1024; i++, frame+=4096, virt+=4096) {

      //! create a new page
      unsigned int page=0;
      st_wpis_dodaj_atryb (&page, I86_PTE_PRESENT);
      st_wpis_ustaw_ramke (&page, frame);

      //! ...and add it to the page table
      table2->m_entries [INDEKS_TABLICY_STRON (virt) ] = page;
   }

   // mapping for my kernel
   for( i=0, frame=0x400000, virt=0xc0000000; i<1024; i++, frame+=4096, virt+=4096) {

      //! create a new page
      unsigned int page=0;
      st_wpis_dodaj_atryb (&page, I86_PTE_PRESENT);
      st_wpis_ustaw_ramke (&page, frame);

      //! ...and add it to the page table
      table->m_entries [INDEKS_TABLICY_STRON (virt) ] = page;
   }
Ok, I see we have page tables, but (how) are you initializing the Page Directory?

Sorry for delay I read threw all posts a time or two to see what I may have missed...

Code: Select all

_start:
   cli
   call SetGDT
       [.... rest of the code..... ]
       lea ebx, [jadro]
   call ebx

jadro:
   jmp 0x8:fix_cs
fix_cs:

    [... rest of code....]
This is an opinion as your way should work, but uses more space:

Code: Select all

_start:
   cli
   call SetGDT
       [.... rest of the code..... ]
   jmp 0x8:fix_cs
fix_cs:
    [... rest of code....]
P.S. Just realized the Polish structure and comments :) .


[Off for the night.]

Re: Placing kernel in 4MB in RAM on real hardware.

Posted: Thu Apr 24, 2014 11:04 am
by Waszka
Here is how I initialize Page Directory:

Code: Select all

//! create default directory table
   pd_struct*   dir = (pd_struct*) alloc (sizeof(pd_struct));
   if (!dir)
      return;

  /* Czyścimy nowy katalog stron i ustawiamy jako bieżący */
  //for(i=0; i<PAGES_PER_DIRECTORY; i++)
  //     dir->m_entries[i] = 0;
  memset((unsigned char*)dir, 0, sizeof(pd_struct));
Ok, but I somehow managed to solve problems with Page Fault (??? how - it's still mystery to me...).
Really, I don't know... :|
I moved some code between files and then... it worked!

But, there's another problem here - I have corrupted variables all around.
For example:

Code: Select all

volatile unsigned int tic_toc_counter = 0;
which is defined inside one of the files.
When starting OS on real hardware (it wasn't like this before) I get random numbers inside.
Sometimes it's 8454542... sometimes just 15464... Unless I make:

Code: Select all

tic_toc_counter = 0 in the code itself, it's just useless. The placement in memory is the same as in bochs.
It also works as expected - it is incremented every clock tick.There are of course other variables corrupted, and I have to change their values before using them...

Could those problems be related to my linker script? :O

Re: Placing kernel in 4MB in RAM on real hardware.

Posted: Thu Apr 24, 2014 4:41 pm
by BASICFreak
I noticed variable garbage on real H/W too, and on Bochs if i hit reset instead of shutdown.

When you computer boots up your ram is not 0'ed in fact the data there is random, it depends on which pins got power which nanosecond.

this is how I over came the issue (timer example)

Code: Select all

void timer_install()
{
	UPTIME_ACTIVE = TRUE;
	timer_seconds = 0;
	timer_minutes = 0;
	timer_hours = 0;
	timer_days = 0;
	timer_years = 0;
	timer_ticks = 0;
    /* Installs 'timer_handler' to IRQ0 */
    irq_install_handler(0, timer_handler);
}
And with the working after moving data around, I have had that problem a few times and it has always ended up being my StageTwo loader, or high level of fragmentation of kernel - which my StageTwo doesn't handle correctly... it's fine with a few fragments.

I will be looking into a way to write StageTwo in C, as ASM is not my strong suit.

Anyways... glad to see you have solved your issue.

Now I get to rewrite my HAL so I have usermode support... (I managed to avoid it for two days :D )



NEVER USE UNINITIALIZED VARIABLES especially in OSDEV!

Re: Placing kernel in 4MB in RAM on real hardware.

Posted: Fri Apr 25, 2014 6:08 am
by Waszka
BASICFreak wrote:NEVER USE UNINITIALIZED VARIABLES especially in OSDEV!
I agree and never did that (at least that's what I thought). But tell me, is something like this:

Code: Select all

volatile int variable = 0; 
         [....] rest of the code
isn't already initialization?

Re: Placing kernel in 4MB in RAM on real hardware.

Posted: Fri Apr 25, 2014 7:05 am
by Combuster
I see a "volatile", therefore assumptions don't apply.

Re: Placing kernel in 4MB in RAM on real hardware.

Posted: Fri Apr 25, 2014 8:43 am
by Waszka
Combuster wrote:I see a "volatile", therefore assumptions don't apply.
Thanks! I totally forgot about this rule! :D
Another thing - do You guys use -O2 or -O3 flags?
In my case they break my kernel (something with wrong vector)

Re: Placing kernel in 4MB in RAM on real hardware.

Posted: Fri Apr 25, 2014 1:20 pm
by jnc100
Do you zero the bss anywhere?

Regards,
John.

Re: Placing kernel in 4MB in RAM on real hardware.

Posted: Fri Apr 25, 2014 3:14 pm
by Waszka
jnc100 wrote:Do you zero the bss anywhere?

Regards,
John.
Hi, and how I'm supposed to do that?

I have my linker script:

Code: Select all

OUTPUT_FORMAT("binary")
ENTRY(_start)
phys = 0xC0000000;
SECTIONS
{
  .text phys : AT(phys) {
    code = .;
    *(.text)
    *(.rodata)
    . = ALIGN(4096);
  }
  .data : AT(phys + (data - code))
  {
    data = .;
    *(.data)
    . = ALIGN(4096);
  }
  .bss : AT(phys + (bss - code))
  {
    bss = .;
    *(.bss)
    . = ALIGN(4096);
  }
  end = .;
}
As for my problems with -O3 flag. I get GDT corrupted.
From bochs after running info gdt 0 I get:

Code: Select all

Global Descriptor Table (base=0x0000000000000000, limit=65535):
GDT[0x00]=Code segment, base=0xf053f000, limit=0x0000ff53, Execute/Read, Conforming, Accessed, 16-bit
which is obviously bad. My code for loading GDT is presented somewhere before in this thread.

Re: Placing kernel in 4MB in RAM on real hardware.

Posted: Fri Apr 25, 2014 3:34 pm
by iansjack
Hi, and how I'm supposed to do that?
A crazy suggestion, but why not write zeros to the memory reserved for the bss?

Re: Placing kernel in 4MB in RAM on real hardware.

Posted: Fri Apr 25, 2014 3:58 pm
by Waszka
iansjack wrote:A crazy suggestion, but why not write zeros to the memory reserved for the bss?
:) Nice one ;)

But I guess this was to help me with my variables not being initialized.
Combuster gave me right clue, and it worked like a charm :)

Right now I have problem with -O3 and -O2 flags, and I'm not sure if it's good idea to use them in compiling the kernel (but somewhere on OS Dev Wiki was said that those flags are really good for checking reliability of the code).

Could somebody tell me if it's good idea to try to make them work or is it just another "problem generator"?

With only -O flag I have in bochs:

Code: Select all

Global Descriptor Table (base=0x00000000c00001cd, limit=23):
GDT[0x00]=??? descriptor hi=0x00000000, lo=0x00000000
GDT[0x01]=Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Non-Conforming, Accessed, 32-bit
GDT[0x02]=Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed

Re: Placing kernel in 4MB in RAM on real hardware.

Posted: Sat Apr 26, 2014 2:38 am
by Combuster
If optimisations are not working, your code is broken.

Re: Placing kernel in 4MB in RAM on real hardware.

Posted: Sat Apr 26, 2014 7:55 am
by hometue
So...that means its fine to use -O2 or -O3 flags for compiling the OSes and there should not be any problems?

Edit: That is assuming the code has no bugs.

Re: Placing kernel in 4MB in RAM on real hardware.

Posted: Sat Apr 26, 2014 12:09 pm
by Waszka
Combuster wrote:If optimisations are not working, your code is broken.
That's what I feared :cry:
But what could those problems be related to?
In my case it looks like GDT pointer is not right, but I load it inside asm function and C code has nothing to do with it.
I know even where it breaks, and I'll investigate it on the next occasion. It's again sti() function which brings interrupts up... :|

Last question: can I use "normal" gcc which I had on my distro from the start?

Re: Placing kernel in 4MB in RAM on real hardware.

Posted: Sun Apr 27, 2014 5:30 am
by sortie
No, no reliably. Use a gcc cross compiler.

Re: Placing kernel in 4MB in RAM on real hardware.

Posted: Sun Apr 27, 2014 6:30 am
by Waszka
sortie wrote:No, no reliably. Use a gcc cross compiler.
Ok, thanks for the answer, I'll do that in my spare time. Does it take a lot time to do it?

As to my problem:

Hmm, this whole -O3 flag thing was caused by broken IDT.
Why was that? I had to change order of functions from:

Code: Select all

/* Initializing IDT */
	_idtr.limit = sizeof(struct idt_deskryptor) * MAX_INTERRUPTS -1; 
	_idtr.base  = (unsigned int)&_idt; 
	idt_install();
	install_isrs();
	install_irq();
to:

Code: Select all

/* Initializing IDT */
	_idtr.limit = sizeof(struct idt_deskryptor) * MAX_INTERRUPTS -1; 
	_idtr.base  = (unsigned int)&_idt; 
	install_isrs();
	install_irq();
	idt_install();
Before, everything worked until install_irq(); - after that instruction (inside it was the PIC initialization) IDT got corrupted.
Changing order solved the problem.

Do You think this is good solution? Where should I investigate further? I really would like to write good code and don't want to have further problems caused by my mistakes from past. :P