Pure binary & BSS
Pure binary & BSS
Is there any way to get gcc/ld to fill the BSS section of my pure binary kernel file with zeros? If there isn't, is there any way for the kernel to know the size of it's BSS section?
P.S. Don't tell me to RTFM, I've been looking for an answer for these questions for weeks, but I can't seem to find a definitive yes or no answer.
P.S. Don't tell me to RTFM, I've been looking for an answer for these questions for weeks, but I can't seem to find a definitive yes or no answer.
RE:Pure binary & BSS
You can use ld scripts to find the length of the bss section.
Below is the ld script i use.
Where you see
Kernel_Base = .;
this means declare a variable in the link exe at that position within the exe.
So the Kernel_Base example there would result in that variable being placed at that offset into the linked exe (16mb).
Note: the variable, to my knowledge, does not contain anything. You must use assembly (or an equivelant C function) to find its physical address.
i.e. in asm i would do
lea eax, Kernel_base
Another Note: This is the effective offset from the selector in asm. My selector starts at 0bytes so would be the correct offset to that variable anyway (16mb).
To find the length of the bss section. All you would need to do is place a variable before the line
*(.bss)
in the same syntax as above, and another variable below the end bss brackets.
Then find their physical addresses of both variables, deduct one from the other and you have the length. Do this in your code of the kernel.
i.e.
Bss_End - Bss_Base = Bss_Length.
This is the same method i find out the size of my entire kernel.
Kernel_End - Kernel_Base = Kernel_Size;
You would of course need to link your kernel with the ld script parameter
'-T <scriptfilename>'.
SECTIONS {
.text 0x01000000 : {
Kernel_Base = .;
*(.text)
}
.data : {
*(.data)
}
.bss : {
*(.bss)
}
Kernel_End = .;
}
Below is the ld script i use.
Where you see
Kernel_Base = .;
this means declare a variable in the link exe at that position within the exe.
So the Kernel_Base example there would result in that variable being placed at that offset into the linked exe (16mb).
Note: the variable, to my knowledge, does not contain anything. You must use assembly (or an equivelant C function) to find its physical address.
i.e. in asm i would do
lea eax, Kernel_base
Another Note: This is the effective offset from the selector in asm. My selector starts at 0bytes so would be the correct offset to that variable anyway (16mb).
To find the length of the bss section. All you would need to do is place a variable before the line
*(.bss)
in the same syntax as above, and another variable below the end bss brackets.
Then find their physical addresses of both variables, deduct one from the other and you have the length. Do this in your code of the kernel.
i.e.
Bss_End - Bss_Base = Bss_Length.
This is the same method i find out the size of my entire kernel.
Kernel_End - Kernel_Base = Kernel_Size;
You would of course need to link your kernel with the ld script parameter
'-T <scriptfilename>'.
SECTIONS {
.text 0x01000000 : {
Kernel_Base = .;
*(.text)
}
.data : {
*(.data)
}
.bss : {
*(.bss)
}
Kernel_End = .;
}
RE:Pure binary & BSS
Thanx mate
I remember messing around with this before, and getting it to work, but I guess I forgot what I did and couldn't get it to work afterwards.
As you probably understand I need to know the size of my kernel in memory before I can start working on a kmalloc() function, which is pretty darn vital to any kernel beyond "Hello World".
If it's really this easy why would anyone bother with ELF or PE for their kernels anyway?
P.S. Sorry about the pre-emptive flame in my first post. I was rather cranky at the time...
Rogier
I remember messing around with this before, and getting it to work, but I guess I forgot what I did and couldn't get it to work afterwards.
As you probably understand I need to know the size of my kernel in memory before I can start working on a kmalloc() function, which is pretty darn vital to any kernel beyond "Hello World".
If it's really this easy why would anyone bother with ELF or PE for their kernels anyway?
P.S. Sorry about the pre-emptive flame in my first post. I was rather cranky at the time...
Rogier
RE:Pure binary & BSS
Well there is no real need to use complex file formats.
I use elf myself, but only because i dont have to do extra multiboot standard stuff when i first started development, which helped as a nebie to osdevelopment.
Dangermoose.
I use elf myself, but only because i dont have to do extra multiboot standard stuff when i first started development, which helped as a nebie to osdevelopment.
Dangermoose.
RE:Pure binary & BSS
Why use ELF? Consistency. And it's not any more "bother" than any other format (at least if you use multiboot), so why not?
RE:Pure binary & BSS
I think the most outstanding feature of it is its easily linkable.
elf stands for <something> linkable format.
Linux switched to using elf because it can link the object file drivers better than the original format used by linux (aout).
Moose.
elf stands for <something> linkable format.
Linux switched to using elf because it can link the object file drivers better than the original format used by linux (aout).
Moose.
RE:Pure binary & BSS
Executable and Linking Format
The main advantage was in dynamic/shared library creation and use... A.OUT could still do both of these, just not as easily.
I just wanted to note, however (from the original post), this it's impossible in _any_ binary format to ensure that the .BSS section is zero'd out. Since this section isn't included in the binary at all, the process of zeroing memory is taken by the OS/program loader, therefore I would _never_ assume that memory has been zero'd, unless you've explicitly done it yourself.
I _believe_ (although I'm not positive) that GRUB will zero the .bss section, however I'm not sure if this is an actual specification of Multiboot loaders, or just a feature of GRUB...
Cheers,
Jeff
The main advantage was in dynamic/shared library creation and use... A.OUT could still do both of these, just not as easily.
I just wanted to note, however (from the original post), this it's impossible in _any_ binary format to ensure that the .BSS section is zero'd out. Since this section isn't included in the binary at all, the process of zeroing memory is taken by the OS/program loader, therefore I would _never_ assume that memory has been zero'd, unless you've explicitly done it yourself.
I _believe_ (although I'm not positive) that GRUB will zero the .bss section, however I'm not sure if this is an actual specification of Multiboot loaders, or just a feature of GRUB...
Cheers,
Jeff
RE:Pure binary & BSS
"I _believe_ (although I'm not positive) that GRUB will zero the .bss section, however I'm not sure if this is an actual specification of Multiboot loaders, or just a feature of GRUB..."
I didn't find anywhere in the Multiboot specification that the .bss section should be zeroed by the loader. Therefore, I wouldn't count on it being zeroed by the loader unless your 100% sure that nobody will use anything but GRUB with your OS and that every version of GRUB zeroes the .bss. Of course, that has nothing to do with rogier's original question, as I'm assuming he's not using multiboot.
As a side note, I am going to make a multiboot loader with a BSD license (which should also be better than GRUB). If anyone's interested in helping (or just want's to know about it) e-mail me (xsadar) at users.sourceforge.net.
" . . . it's impossible in _any_ binary format to ensure that the .BSS section is zero'd out. . . . unless you've explicitly done it yourself."
I think rogier was asking how to put zeros into the actual file. There are certainly many ways of doing this. (They fall into the "explicitly done it yourself" category.) I would just recommend doing it at runtime though, unless your .bss section is small.
I didn't find anywhere in the Multiboot specification that the .bss section should be zeroed by the loader. Therefore, I wouldn't count on it being zeroed by the loader unless your 100% sure that nobody will use anything but GRUB with your OS and that every version of GRUB zeroes the .bss. Of course, that has nothing to do with rogier's original question, as I'm assuming he's not using multiboot.
As a side note, I am going to make a multiboot loader with a BSD license (which should also be better than GRUB). If anyone's interested in helping (or just want's to know about it) e-mail me (xsadar) at users.sourceforge.net.
" . . . it's impossible in _any_ binary format to ensure that the .BSS section is zero'd out. . . . unless you've explicitly done it yourself."
I think rogier was asking how to put zeros into the actual file. There are certainly many ways of doing this. (They fall into the "explicitly done it yourself" category.) I would just recommend doing it at runtime though, unless your .bss section is small.
RE:Pure binary & BSS - correction
The multiboot specification DOES require that the .bss section be zeroed. So any multiboot OS can safely assume that it has been zeroed. I don't know how I missed it when I was looking for it before.
RE:Pure binary & BSS
I wasn't planning on using multiboot (don't even know what it is) but I gather from posts here that it has something to do with GRUB? I was actually planning on writing my own bootloader.
The bootloader would load a small DOS-like 16-bit OS, with a shell and an editor, and would in turn load my kernel and any other processes required by the kernel to do anything usefull, like an IDE-driver.
Am I making any sense?
The bootloader would load a small DOS-like 16-bit OS, with a shell and an editor, and would in turn load my kernel and any other processes required by the kernel to do anything usefull, like an IDE-driver.
Am I making any sense?
RE:Pure binary & BSS
Multiboot is a standard set forth by the makers of Grub to make booting operating systems easier and to allow more operating systems to be placed on a single machine while having one bootloader for the os kernels to be compliant with that can load them all.
In multiboot the os kernel contains a special header with some details in, flags and details about the kernels sections. Then the bootloader can load it in a pre-defined way, catered to the kernels requests inside the flags, and place the computer in a standard state for the operating system to start running with.
I believe multiboot is only compliant with x86 machines, but im not sure, maybe some kind of standard is available for other architectures too.
http://www.mcc.ac.uk/Documentation/grub ... t_toc.html
Moose.
In multiboot the os kernel contains a special header with some details in, flags and details about the kernels sections. Then the bootloader can load it in a pre-defined way, catered to the kernels requests inside the flags, and place the computer in a standard state for the operating system to start running with.
I believe multiboot is only compliant with x86 machines, but im not sure, maybe some kind of standard is available for other architectures too.
http://www.mcc.ac.uk/Documentation/grub ... t_toc.html
Moose.
RE:Pure binary & BSS
I use this piece of code in my kernel to zero the .bss section. It is written in 32 bit assembly language. It works for my kernel because its elf format, dont know if it will successfully work for binary, give it a try. The code is pretty self explantory.
; Zero BSS
extern kernel_bss, kernel_end
mov edi,kernel_bss ; Defined in linker script [kernel_bss = .;]
mov ecx,kernel_end ; Also defined in linker script [kernel_end = .;]
sub ecx,edi
xor eax,eax
rep stosb
; Zero BSS
extern kernel_bss, kernel_end
mov edi,kernel_bss ; Defined in linker script [kernel_bss = .;]
mov ecx,kernel_end ; Also defined in linker script [kernel_end = .;]
sub ecx,edi
xor eax,eax
rep stosb