Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > alt.os.development > #9549 > unrolled thread
| Started by | "Isaac D. Cohen" <8switchsoftware@gmail.com> |
|---|---|
| First post | 2016-05-23 22:07 -0700 |
| Last post | 2016-05-25 22:18 -0700 |
| Articles | 20 on this page of 23 — 6 participants |
Back to article view | Back to alt.os.development
Questions about the Implementation of the ELF format "Isaac D. Cohen" <8switchsoftware@gmail.com> - 2016-05-23 22:07 -0700
Re: Questions about the Implementation of the ELF format Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> - 2016-05-24 03:48 -0400
Questions about the Implementation of the ELF format Peter Cheung <mcheung63@gmail.com> - 2016-05-24 01:10 -0700
Re: Questions about the Implementation of the ELF format "Alexei A. Frounze" <alexfrunews@gmail.com> - 2016-05-24 01:18 -0700
Re: Questions about the Implementation of the ELF format "Mike Gonta" <mikegonta@gmail.com> - 2016-05-24 10:34 -0400
Re: Questions about the Implementation of the ELF format Herbert Kleebauer <klee@unibwm.de> - 2016-05-24 17:24 +0200
Re: Questions about the Implementation of the ELF format "Isaac D. Cohen" <8switchsoftware@gmail.com> - 2016-05-24 14:18 -0700
Re: Questions about the Implementation of the ELF format "Alexei A. Frounze" <alexfrunews@gmail.com> - 2016-05-25 02:21 -0700
Re: Questions about the Implementation of the ELF format "Isaac D. Cohen" <8switchsoftware@gmail.com> - 2016-05-25 15:02 -0700
Re: Questions about the Implementation of the ELF format "Mike Gonta" <mikegonta@gmail.com> - 2016-05-25 19:03 -0400
Re: Questions about the Implementation of the ELF format "Isaac D. Cohen" <8switchsoftware@gmail.com> - 2016-05-26 14:51 -0700
Re: Questions about the Implementation of the ELF format Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> - 2016-05-27 02:55 -0400
Re: Questions about the Implementation of the ELF format "Isaac D. Cohen" <8switchsoftware@gmail.com> - 2016-05-27 13:43 -0700
Re: Questions about the Implementation of the ELF format "Mike Gonta" <mikegonta@gmail.com> - 2016-05-27 17:40 -0400
Re: Questions about the Implementation of the ELF format "Isaac D. Cohen" <8switchsoftware@gmail.com> - 2016-05-28 20:15 -0700
Re: Questions about the Implementation of the ELF format Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> - 2016-05-29 02:35 -0400
Re: Questions about the Implementation of the ELF format "Isaac D. Cohen" <8switchsoftware@gmail.com> - 2016-06-15 13:51 -0700
Re: Questions about the Implementation of the ELF format Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> - 2016-05-27 03:09 -0400
Re: Questions about the Implementation of the ELF format "Alexei A. Frounze" <alexfrunews@gmail.com> - 2016-05-27 00:10 -0700
Re: Questions about the Implementation of the ELF format Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> - 2016-06-02 16:25 -0400
Re: Questions about the Implementation of the ELF format Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> - 2016-05-27 02:38 -0400
Re: Questions about the Implementation of the ELF format "Mike Gonta" <mikegonta@gmail.com> - 2016-05-27 04:11 -0400
Re: Questions about the Implementation of the ELF format "Alexei A. Frounze" <alexfrunews@gmail.com> - 2016-05-25 22:18 -0700
Page 1 of 2 [1] 2 Next page →
| From | "Isaac D. Cohen" <8switchsoftware@gmail.com> |
|---|---|
| Date | 2016-05-23 22:07 -0700 |
| Subject | Questions about the Implementation of the ELF format |
| Message-ID | <06b38764-b3ee-4eed-9b82-f62c1d68b0ec@googlegroups.com> |
Hi, While what I’m about to write may at first seem off topic, it can somehow have something to do with OS Development. If anyone knows of a newsgroup in which this would be more on topic, please let me know. In any case, I’m trying to figure out how to include C/C++ in my operating system. So I googled around and found that I have to cross-compile the C/C++ file into some kind of format, for example ELF. So my first question is, why? Why can’t the compiler just generate plain binary files? Anyway, I quickly realized that I’m going to have to learn all about ELFs, because otherwise, I won’t know how to jump into the executable from an assembly file in my OS. So I got the ELF specification (from here: http://flint.cs.yale.edu/cs422/doc/ELF_Format.pdf), and began reading it. Also, I thought it would be helpful to look at an ELF executable as I read the specification and follow along. So for example, if the specification says that an ELF file begins with 0x7F followed by the ASCII characters ‘E’, ‘L’ and ‘F’, I would take a look at the beginning of the ELF file and see if it has the 0x7F ‘ELF’. So I opened a 64-bit ELF executable compiled for Linux, in Bless Hex Editor and began to follow along. It did not take long until I noticed that the program does not appear to be following the specification. Here is what happened. The specification says that the first 16 bytes make up the “ELF Identification” and then there is a two byte field indicating what type of ELF file it is. The program I was looking at had a 2 in this field meaning it is an executable. So far so good. The specification also states that executables must have a Program Header Table. Later on, the specification says that at offset 28 there is a 4 byte field containing the offset (from the beginning of the file) of the Program Header Table. “If the file has no program header table, this member holds zero.” the specification says. However, in the program I was looking at, this field seems to contain a zero despite the program being an executable. How can that be? Also the specification says that files that don’t have a program header table must have a section header table and vise versa. So in that case, the ELF I was looking at, should at least have a section header table. But to my surprise, the fields in the ELF header that should contain the length of each section header in the table and the amount of entries in the section header table both contain zeros! How can that be? Especially when the field that is supposed to contain the offset of the section header table (from the beginning of the file), contains 64, meaning that the section header table with 0 entries that are 0 bytes each, is at offset 64 from the beginning of the file. How is this possible? Thank you very much, Isaac D. Cohen
[toc] | [next] | [standalone]
| From | Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> |
|---|---|
| Date | 2016-05-24 03:48 -0400 |
| Message-ID | <20160524034801.357f351a@_> |
| In reply to | #9549 |
On Mon, 23 May 2016 22:07:38 -0700 (PDT) "Isaac D. Cohen" <8switchsoftware@gmail.com> wrote: > In any case, I’m trying to figure out how to include C/C++ in my > operating system. 1) in-lined assembly in C 2) link assembly object with C object I tend to prefer #1 since you only need a few special instructions and maybe one or two routines in assembly for an OS. Everything else can be done in C. Having most of the code in C reduces compiler dependence if you're using multiple C compilers. Others tend to like the convenience of using an assembler of their choice and linking the assembly with C, e.g. GCC C compiler with NASM assembler instead of GNU AS (GAS). Notice that I didn't mention C++. My understanding is that if you use C++ code in an OS that you must provide your own routines for "new" and "delete" since C++ code frequently calls these. If this is actually an issue with C++, i.e., if the C++ code is not independent of them, then you'll most likely know when you try to link the C++ code as stand-alone code, i.e., missing new and delete functions, or it may crash when executed. I would stick with C or assembly for OS development. I just happen to find assembly to be more tedious, but some people, like Wolfgang, perhaps Mike Gonta, have had excellent results with an assembly only approach. Many of the people who have posted here over many years seem to develop from Linux using C. I'm one of the rare ones to develop from DOS using redundant C compilers. The advantage of developing from DOS is that there isn't a protected OS blocking you from running code that directly programs the hardware. So, you can develop and test your OS code in DOS without having to boot or re-boot your OS repeatedly. You also don't have the issue of incorrect emulation of various emulators. E.g., I developed my mouse driver, keyboard driver, and video driver, code to initialize and reprogram PICs, RTC, video registers, mouse, keyboard, etc and even OS setup such as GDT etc, all while running DOS. After the code was working, I merged the code into my OS. > So I googled around and found that I have to cross-compile the > C/C++ file into some kind of format, for example ELF. Um ... Generally, C compilers have certain native formats which are needed by the host OS. E.g., Linux may only support a few flavors of ELF, e.g., 32-bit and 64-bit, while an old DOS C compiler, like Watcom or OpenWatcom may support a half-dozen formats, since many formats were used for different reasons with DOS, historically. So, you have no choice but to produce code for the intended format(s) that can be used by the OS, but C compilers can usually produce both executable and object files. The latter are linked together to create an executable file. > So my first question is, why? Why can’t the compiler just > generate plain binary files? So, I think the base answer is that compilers produce output that the host OS can use, i.e., execute, otherwise they don't. I.e., the file must be executable by the OS, or linkable by the compiler into an executable for that OS to be of use. Sometimes C compilers have utilities to strip the stub or header off of an executable or object file. AFAIK, 32-bit DOS C compilers, Linux C compilers, and Windows C compilers can only produce executable and object formats. However, 16-bit DOS C compilers can produce plain binary, since DOS can execute 16-bit .com files which are plain binary. As an aside, it's also a security risk to be able to execute raw code. The OS isn't really able to perform any safety checks or relocation of the code without a header. Certain C compilers, like GCC for Linux, have switches needed to produce stand-alone OS images, since said compilers are used to produce the host OS. Other C compilers, e.g., Windows or DOS, aren't used to produce the host OS. So, there is no need for them to have such functionality. If they could, it would be a major security concern. E.g., imagine if you could modify, re-compile, and re-install Windows 10 yourself, or someone else could ... Some C compilers have switches which will reduce or eliminate dependence on the host's OS calls, but that has nothing to do with the object or executable format. That just makes sure your OS doesn't call an external C library or CRT start-up code, which is half the problem of producing stand-alone code for the OS. The other half is getting the code into a bootable format, e.g., ELF, COFF, Multiboot compliant, DOS OMF, etc. > Anyway, I quickly realized that I’m going to have to learn all about > ELFs, because otherwise, I won’t know how to jump into the executable > from an assembly file in my OS. So I got the ELF specification (from > here: http://flint.cs.yale.edu/cs422/doc/ELF_Format.pdf), and began > reading it. Chris Giese ELF format summary http://geezer.osdevbrasil.net/osd/exec/elf.txt > Also, I thought it would be helpful to look at an ELF > executable as I read the specification and follow along. So for > example, if the specification says that an ELF file begins with 0x7F > followed by the ASCII characters ‘E’, ‘L’ and ‘F’, I would take a > look at the beginning of the ELF file and see if it has the 0x7F > ‘ELF’. So I opened a 64-bit ELF executable compiled for Linux, in > Bless Hex Editor and began to follow along. It did not take long > until I noticed that the program does not appear to be following the > specification. ... > [ELF questions] I'm not familiar with the ELF format. I know that GRUB and GRUB4DOS should load ELF format OSes. I know that some executable formats also have an object format of the same name, e.g., COFF has both COFF executables and COFF objects. I.e., make sure you're looking at the correct data. Rod Pemberton
[toc] | [prev] | [next] | [standalone]
| From | Peter Cheung <mcheung63@gmail.com> |
|---|---|
| Date | 2016-05-24 01:10 -0700 |
| Message-ID | <41cbd0a0-6c72-41a8-801c-23043fbdac5c@googlegroups.com> |
| In reply to | #9549 |
elf can do dynamic linking
[toc] | [prev] | [next] | [standalone]
| From | "Alexei A. Frounze" <alexfrunews@gmail.com> |
|---|---|
| Date | 2016-05-24 01:18 -0700 |
| Message-ID | <dfad6e5e-dc6e-4e40-94a6-64d0ebb864ab@googlegroups.com> |
| In reply to | #9549 |
On Monday, May 23, 2016 at 10:07:40 PM UTC-7, Isaac D. Cohen wrote: > In any case, I’m trying to figure out how to include C/C++ in my operating system. So I googled around and found that I have to cross-compile the C/C++ file into some kind of format, for example ELF. So my first question is, why? Why can’t the compiler just generate plain binary files? > Because plain binary files cannot easily include additional information supporting various useful features (relocation, code vs data distinguishing, stack unwinding on exceptions, debug/symbol info, DLLs, embedded data files, etc etc). > Anyway, I quickly realized that I’m going to have to learn all about ELFs, because otherwise, I won’t know how to jump into the executable from an assembly file in my OS. So I got the ELF specification (from here: http://flint.cs.yale.edu/cs422/doc/ELF_Format.pdf), and began reading it. Also, I thought it would be helpful to look at an ELF executable as I read the specification and follow along. So for example, if the specification says that an ELF file begins with 0x7F followed by the ASCII characters ‘E’, ‘L’ and ‘F’, I would take a look at the beginning of the ELF file and see if it has the 0x7F ‘ELF’. So I opened a 64-bit ELF executable compiled for Linux, in Bless Hex Editor and began to follow along. It did not take long until I noticed that the program does not appear to be following the specification. > What does objdump tell you about your file? What headers, sections and other things does it find in the file? objdump -x file Alex
[toc] | [prev] | [next] | [standalone]
| From | "Mike Gonta" <mikegonta@gmail.com> |
|---|---|
| Date | 2016-05-24 10:34 -0400 |
| Message-ID | <ni1op3$1ndv$1@gioia.aioe.org> |
| In reply to | #9549 |
"Isaac D. Cohen" wrote:
> I’m trying to figure out how to include C/C++ in my
> operating system. So I googled around and found that I
> have to cross-compile the C/C++ file into some kind of
> format, for example ELF. So my first question is, why? Why
> can’t the compiler just generate plain binary files?
If you want to use GCC on Windows - that's the way it is.
> Anyway, I quickly realized that I’m going to have to learn
> all about ELFs, ....
No need to if you're going to generate a flat binary file.
Simple link the object files and specify:
OUTPUT_FORMAT("binary")
in the linker file.
> because otherwise, I won’t know how to jump into the
> executable from an assembly file in my OS.
Simply link with the asm object file and include a jmp or
call to the function name used in the "C" file.
Another simple technique to use when running a loaded flat
binary from the OS is to call the beginning address of the
loaded file. In this case since you can never be sure of
where the actually address of the "main" function will be in
the actual binary simply put an inline asm statement at the
end of a "#include"d file:
__asm__ ("jmp main");
and the linker will take care of the rest.
Also, for example, if you load the the file to (for example)
0x400000, you can call it from "C" in the OS loader with:
((int (*)(void ))0x400000)();
(with the appropriate return type and parameters).
Mike Gonta
look and see - many look but few see
http://mikegonta.com
http://tawk.to/mikegonta
[toc] | [prev] | [next] | [standalone]
| From | Herbert Kleebauer <klee@unibwm.de> |
|---|---|
| Date | 2016-05-24 17:24 +0200 |
| Message-ID | <ni1roj$1sp6$1@gioia.aioe.org> |
| In reply to | #9549 |
On 24.05.2016 07:07, Isaac D. Cohen wrote: > In any case, I’m trying to figure out how to include C/C++ in > my operating system. So I googled around and found that I have > to cross-compile the C/C++ file into some kind of format, for > example ELF. So my first question is, why? Why can’t the > compiler just generate plain binary files? > Anyway, I quickly realized that I’m going to have to learn all > about ELFs, because otherwise, I won’t know how to jump into > the executable from an assembly file in my OS. If you already have a working system on your OS which let you compile and run assembly programs, then cross compile C code not to binary but to assembly source code, transfer it to your OS and then use the assembler in your OS.
[toc] | [prev] | [next] | [standalone]
| From | "Isaac D. Cohen" <8switchsoftware@gmail.com> |
|---|---|
| Date | 2016-05-24 14:18 -0700 |
| Message-ID | <3098f645-49d7-4d3d-9bf3-75ba43a5ddde@googlegroups.com> |
| In reply to | #9549 |
Rod Pemberton Wrote:
> The OS isn't really able to perform any safety checks or relocation of
> the code without a header.
Alexei A. Frounze wrote:
> Because plain binary files cannot easily include additional
> information supporting various useful features (relocation,
> code vs data distinguishing, stack unwinding on exceptions,
> debug/symbol info, DLLs, embedded data files, etc etc).
I don't quite understand this whole thing about relocation. I thought the whole
reason the phenomenon of paging exists is because it solves the relocation
problem by creating a virtual address space for each process and that the only
code that still has a relocation problem are the shared libraries which is why
they are compiled as position independent code. But what is this about relocation
with regular executables?
> What does objdump tell you about your file? What headers,
> sections and other things does it find in the file?
Hmmm. That's a good idea. Let's see...
a.out: file format elf64-x86-64
a.out
architecture: i386:x86-64, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x0000000000400430
Program Header:
PHDR off 0x0000000000000040 vaddr 0x0000000000400040 paddr 0x0000000000400040 align 2**3
filesz 0x00000000000001f8 memsz 0x00000000000001f8 flags r-x
INTERP off 0x0000000000000238 vaddr 0x0000000000400238 paddr 0x0000000000400238 align 2**0
filesz 0x000000000000001c memsz 0x000000000000001c flags r--
LOAD off 0x0000000000000000 vaddr 0x0000000000400000 paddr 0x0000000000400000 align 2**21
filesz 0x00000000000006f4 memsz 0x00000000000006f4 flags r-x
LOAD off 0x0000000000000e10 vaddr 0x0000000000600e10 paddr 0x0000000000600e10 align 2**21
filesz 0x0000000000000228 memsz 0x0000000000000230 flags rw-
DYNAMIC off 0x0000000000000e28 vaddr 0x0000000000600e28 paddr 0x0000000000600e28 align 2**3
filesz 0x00000000000001d0 memsz 0x00000000000001d0 flags rw-
NOTE off 0x0000000000000254 vaddr 0x0000000000400254 paddr 0x0000000000400254 align 2**2
filesz 0x0000000000000044 memsz 0x0000000000000044 flags r--
EH_FRAME off 0x00000000000005cc vaddr 0x00000000004005cc paddr 0x00000000004005cc align 2**2
filesz 0x0000000000000034 memsz 0x0000000000000034 flags r--
STACK off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4
filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
RELRO off 0x0000000000000e10 vaddr 0x0000000000600e10 paddr 0x0000000000600e10 align 2**0
filesz 0x00000000000001f0 memsz 0x00000000000001f0 flags r--
This is not the entire output, but it's probably the most important part of it as
it shows that the ELF indeed does have a program header. Notice that according
this output the offset of the program header table is 0x40. When I open the file
with Bless Hex Editor 0x40 is the offset of the Section Header Table. The offset
of the program header table, according to what I see in Bless, is 0x0 meaning it
doesn't exist.
But how is it possible that objdump and I are reading a file differently? What
does objdump see in the file that tells it that there is a program header even
though when I read the file it seems otherwise?
Thank you very much,
Isaac D. Cohen
[toc] | [prev] | [next] | [standalone]
| From | "Alexei A. Frounze" <alexfrunews@gmail.com> |
|---|---|
| Date | 2016-05-25 02:21 -0700 |
| Message-ID | <a74a8fff-76f2-40c3-ba3f-2cdaeadb2e98@googlegroups.com> |
| In reply to | #9557 |
On Tuesday, May 24, 2016 at 2:18:08 PM UTC-7, Isaac D. Cohen wrote:
> I don't quite understand this whole thing about relocation. I thought the whole
> reason the phenomenon of paging exists is because it solves the relocation
> problem by creating a virtual address space for each process and that the only
> code that still has a relocation problem are the shared libraries which is why
> they are compiled as position independent code. But what is this about relocation
> with regular executables?
Paging exists to fool big fat programs into believing they have
lots of fast and expensive RAM to use when in fact most of it
is backed by your cheap and slow disk storage. Virtual memory
it is.
Position-independent code is a good thing, but it's not always
cheap (the CPU simply may have no decent PC-relative addressing)
and it itself may need a tiny bit of relocation.
Let's say you have this tiny bit of C code:
#include <stdio.h>
int a = 123;
int* pa = &a;
int main(void)
{
printf("%d\n", *pa);
return 0;
}
On the x86, direct calls are PC-relative, so calling printf()
may be deemed covered in terms of position independence.
But data accesses to pa and a in non-64-bit modes are not
PC-relative. Hence relocations and/or complex indirection
schemes.
OTOH, in the 64-bit mode you can access both pa and a relative
to PC. However, how does pa get its initial value, the address
of a? There must be some code somewhere that takes the address
of a and stores it in memory at the address of pa. That is a form
of relocation. Bummer!
Alex
[toc] | [prev] | [next] | [standalone]
| From | "Isaac D. Cohen" <8switchsoftware@gmail.com> |
|---|---|
| Date | 2016-05-25 15:02 -0700 |
| Message-ID | <ba3e35ec-d8f7-4d00-940b-e04c1ba1d581@googlegroups.com> |
| In reply to | #9549 |
> Paging exists to fool big fat programs into believing they have
> lots of fast and expensive RAM to use when in fact most of it
> is backed by your cheap and slow disk storage. Virtual memory
> it is.
It also exists to solve the relocation problem. :)
> Position-independent code is a good thing, but it's not always
> cheap (the CPU simply may have no decent PC-relative addressing)
> and it itself may need a tiny bit of relocation.
> Let's say you have this tiny bit of C code:
> #include <stdio.h>
> int a = 123;
> int* pa = &a;
> int main(void)
> {
> printf("%d\n", *pa);
> return 0;
> }
> On the x86, direct calls are PC-relative, so calling printf()
> may be deemed covered in terms of position independence.
> But data accesses to pa and a in non-64-bit modes are not
> PC-relative. Hence relocations and/or complex indirection
> schemes.
> OTOH, in the 64-bit mode you can access both pa and a relative
> to PC. However, how does pa get its initial value, the address
> of a? There must be some code somewhere that takes the address
> of a and stores it in memory at the address of pa. That is a form
> of relocation. Bummer!
But what does ELF have to do with this whole thing? I understand that certain
things are relative and certain things have to be relocated. But what does ELF
have to do with it? Why can't we just compile position independent code when we
need it and when not, use pure binary files? Obviously we would need paging in
order to solve the relocation problem with these pure binary files, but wouldn't
the same thing be necessary for ELFs?
Mike Gonta wrote:
> No need to if you're going to generate a flat binary file.
> Simple link the object files and specify:
> OUTPUT_FORMAT("binary")
> in the linker file.
>> because otherwise, I won’t know how to jump into the
>> executable from an assembly file in my OS.
> Simply link with the asm object file and include a jmp or
> call to the function name used in the "C" file.
> Another simple technique to use when running a loaded flat
> binary from the OS is to call the beginning address of the
> loaded file. In this case since you can never be sure of
> where the actually address of the "main" function will be in
> the actual binary simply put an inline asm statement at the
> end of a "#include"d file:
> __asm__ ("jmp main");
> and the linker will take care of the rest.
> Also, for example, if you load the the file to (for example)
> 0x400000, you can call it from "C" in the OS loader with:
> ((int (*)(void ))0x400000)();
> (with the appropriate return type and parameters).
So let's say I write an assembly file and a C file and then I link them together.
How would I call this executable file from an assembly file in my OS? If I load
it to 0x400000, can I just write "jmp 0x400000"? I think this would only work if
the code of the assembly file (that was linked in) is placed (by the linker)
right at the beginning of the resulting executable. Would that be the case?
Thank you very much,
Isaac D. Cohen
[toc] | [prev] | [next] | [standalone]
| From | "Mike Gonta" <mikegonta@gmail.com> |
|---|---|
| Date | 2016-05-25 19:03 -0400 |
| Message-ID | <ni5b17$10pn$1@gioia.aioe.org> |
| In reply to | #9564 |
"Isaac D. Cohen" wrote:
> So let's say I write an assembly file and a C file and
> then I link them together. How would I call this
> executable file from an assembly file in my OS? If I load
> it to 0x400000, can I just write "jmp 0x400000"? I think
> this would only work if the code of the assembly file
> (that was linked in) is placed (by the linker) right at
> the beginning of the resulting executable. Would that be
> the case?
If the loaded binary is an asm file then it is up to you to
make sure that the first instruction is the start or will
get to the start (such as "jmp start") and link the asm file
first. "start" of course could be a function in the "C" file.
If the loaded binary is a "C" file then use the #include
__asm__ ("jmp main");
Mike Gonta
look and see - many look but few see
http://mikegonta.com
http://tawk.to/mikegonta
[toc] | [prev] | [next] | [standalone]
| From | "Isaac D. Cohen" <8switchsoftware@gmail.com> |
|---|---|
| Date | 2016-05-26 14:51 -0700 |
| Message-ID | <d26c82e5-f9db-4247-80a7-97f5157d84e3@googlegroups.com> |
| In reply to | #9565 |
Mike Gonta wrote:
> "Isaac D. Cohen" wrote:
>> So let's say I write an assembly file and a C file and
>> then I link them together. How would I call this
>> executable file from an assembly file in my OS? If I load
>> it to 0x400000, can I just write "jmp 0x400000"? I think
>> this would only work if the code of the assembly file
>> (that was linked in) is placed (by the linker) right at
>> the beginning of the resulting executable. Would that be
>> the case?
> If the loaded binary is an asm file then it is up to you to
> make sure that the first instruction is the start or will
> get to the start (such as "jmp start") and link the asm file
> first. "start" of course could be a function in the "C" file.
> If the loaded binary is a "C" file then use the #include
> __asm__ ("jmp main");
So how would we implement this? Let's say we have a C file that looks something like this:
int a=10;
int b=20;
int main(){
int c=a+b;}
Note that this example file does not include any system libraries (or any libraries at all, for that matter) such as "stdio.h".
So we can compile this independent code as follows:
gcc -c <filename.c>
But wait. That just created an ELF object file. Furthermore, we can only link with an assembly file that has also been assembled into an object file. We can't link with pure binary. So how can we create a pure binary kernel?
Thank you very much,
Isaac D. Cohen
[toc] | [prev] | [next] | [standalone]
| From | Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> |
|---|---|
| Date | 2016-05-27 02:55 -0400 |
| Message-ID | <20160527025559.72612eda@_> |
| In reply to | #9569 |
On Thu, 26 May 2016 14:51:42 -0700 (PDT) "Isaac D. Cohen" <8switchsoftware@gmail.com> wrote: > So how can we create a pure binary kernel? A more important question might be, "Why do you want one?" ... You generally need a pure binary for a bootable code such as a bootloader, but usually not much else. A bootloader will usually only start an OS image that is _NOT_ a pure binary. Bootloaders will start execution of an OS image which has a specific executable or object format or a special header, such as ELF, or DOS OMF, or COFF, or whatever M$ uses, or that which has a Multiboot header, etc. If you've coded your own bootloader, then you just need to call or jump to the entry point in your executable image, e.g., to main() for C or a "start" label for assembly. Usually, C compilers include some assembly labels which are accessible, such as some variation of "start". However, if the compiler or assembler produces an executable format, such as ELF, COFF, PE, etc, then the executable header provides an entry point to start execution. I.e., this has been done for you, if your bootloader can obtain information from the executable header. You definitely need to make sure the kernel is not dependent on any system libraries, e.g., static code, or not doesn't use them. This usually requires some compiler specific flags to warn or error if you do. Of course, you can, if careful, use some system code since some of it won't be dependent on the host OS. These will be very basic functions. Rod Pemberton
[toc] | [prev] | [next] | [standalone]
| From | "Isaac D. Cohen" <8switchsoftware@gmail.com> |
|---|---|
| Date | 2016-05-27 13:43 -0700 |
| Message-ID | <b0063221-fd4c-4276-9ffa-da12d0bfe821@googlegroups.com> |
| In reply to | #9573 |
Rod Pemberton wrote: >> So how can we create a pure binary kernel? > A more important question might be, "Why do you want one?" ... > You generally need a pure binary for a bootable code such as a > bootloader, but usually not much else. A bootloader will usually only > start an OS image that is _NOT_ a pure binary. Bootloaders will start > execution of an OS image which has a specific executable or object > format or a special header, such as ELF, or DOS OMF, or COFF, or > whatever M$ uses, or that which has a Multiboot header, etc. Well, originally, that's what I wanted to do. But when I has many questions about ELF Mike suggested that I use plain binary so that I can simply jump to the address at which I loaded the file rather than having to read all those headers first. Thank you very much, Isaac D. Cohen
[toc] | [prev] | [next] | [standalone]
| From | "Mike Gonta" <mikegonta@gmail.com> |
|---|---|
| Date | 2016-05-27 17:40 -0400 |
| Message-ID | <niaesn$1t8c$1@gioia.aioe.org> |
| In reply to | #9578 |
"Isaac D. Cohen" wrote: > Rod Pemberton wrote: >> "Isaac D. Cohen" wrote: >>> So how can we create a pure binary kernel? >> A more important question might be, "Why do you want >> one?" ... > Well, originally, that's what I wanted to do. No it's not. "Isaac D. Cohen" wrote: >>>> In any case, I'm trying to figure out how to include C/C++ >>>> in my operating system. So I googled around and found that >>>> I have to cross-compile the C/C++ file into some kind of >>>> format, for example ELF. So my first question is, why? Why >>>> can't the compiler just generate plain binary files? The compiler generates object files and the linker produces the binary. > But when I has many questions about ELF Mike suggested > that I use plain binary.... It's simple to link the ELF object file to produce a plain binary (and no knowledge of ELF is required). > ....so that I can simply jump to the address at which I > loaded the file rather than having to read all those > headers first. I thought that others (as well as yourself) might be interested in how to do things by "not following the rules". Mike Gonta look and see - many look but few see http://mikegonta.com http://tawk.to/mikegonta
[toc] | [prev] | [next] | [standalone]
| From | "Isaac D. Cohen" <8switchsoftware@gmail.com> |
|---|---|
| Date | 2016-05-28 20:15 -0700 |
| Message-ID | <a577f76c-aaad-4a79-930b-ccee99b3f9e2@googlegroups.com> |
| In reply to | #9579 |
Mike Gonta wrote: > "Isaac D. Cohen" wrote: >> Rod Pemberton wrote: >>> "Isaac D. Cohen" wrote: >>>> So how can we create a pure binary kernel? >>> A more important question might be, "Why do you want >>> one?" ... >> Well, originally, that's what I wanted to do. > No it's not. No use arguing over facts. > "Isaac D. Cohen" wrote: >>>>> In any case, I'm trying to figure out how to include C/C++ >>>>> in my operating system. So I googled around and found that >>>>> I have to cross-compile the C/C++ file into some kind of >>>>> format, for example ELF. So my first question is, why? Why >>>>> can't the compiler just generate plain binary files? > The compiler generates object files and the linker produces > the binary. >> But when I has many questions about ELF Mike suggested >> that I use plain binary.... > It's simple to link the ELF object file to produce a plain > binary (and no knowledge of ELF is required). >> ....so that I can simply jump to the address at which I >> loaded the file rather than having to read all those >> headers first. > I thought that others (as well as yourself) might be > interested in how to do things by "not following the rules". I tried building a kernel as you say (i.e. compiling into ELFs and then linking into binary) and jumping to the address at which I loaded the kernel, but it caused a page fault. I would guess that the reason for this is because the file has some kind of format or another (not ELF) and just jumping to the beginning of it is making the CPU execute something that is not code (or the wrong code). Thank you very much, Isaac D. Cohen "Religion is an illusion and it derives its strength from the fact that it falls in with our instinctual desires." - Sigmund Freud
[toc] | [prev] | [next] | [standalone]
| From | Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> |
|---|---|
| Date | 2016-05-29 02:35 -0400 |
| Message-ID | <20160529023551.23d916a9@_> |
| In reply to | #9580 |
On Sat, 28 May 2016 20:15:17 -0700 (PDT) "Isaac D. Cohen" <8switchsoftware@gmail.com> wrote: > I tried building a kernel as you say (i.e. compiling into ELFs and > then linking into binary) and jumping to the address at which I > loaded the kernel, but it caused a page fault. I would guess that the > reason for this is because the file has some kind of format or > another (not ELF) and just jumping to the beginning of it is making > the CPU execute something that is not code (or the wrong code). A page fault? Why would you have paging enabled? Isn't it a bit early in development to have activated paging? If you haven't implemented paging yet, as I would suspect. Then, it's a problem with your emulator. Otherwise, disable paging until after everything works. Rod Pemberton
[toc] | [prev] | [next] | [standalone]
| From | "Isaac D. Cohen" <8switchsoftware@gmail.com> |
|---|---|
| Date | 2016-06-15 13:51 -0700 |
| Message-ID | <f6fff84f-3f54-44c7-898b-c84183c36a20@googlegroups.com> |
| In reply to | #9583 |
I wrote: > I tried building a kernel as you say (i.e. compiling into ELFs and > then linking into binary) and jumping to the address at which I > loaded the kernel, but it caused a page fault. I would guess that the > reason for this is because the file has some kind of format or > another (not ELF) and just jumping to the beginning of it is making > the CPU execute something that is not code (or the wrong code). Well, as it turns out, I guessed wrong. The page fault was because of an error in my linker script. I fixed it now and all is well. Thank you everyone (especially Mike Gonta and Rod Pemberton) for your help! Isaac D. Cohen
[toc] | [prev] | [next] | [standalone]
| From | Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> |
|---|---|
| Date | 2016-05-27 03:09 -0400 |
| Message-ID | <20160527030956.5383a466@_> |
| In reply to | #9569 |
On Thu, 26 May 2016 14:51:42 -0700 (PDT) "Isaac D. Cohen" <8switchsoftware@gmail.com> wrote: > So we can compile this independent code as follows: > > gcc -c <filename.c> > > But wait. That just created an ELF object file. Furthermore, we can > only link with an assembly file that has also been assembled into an > object file. We can't link with pure binary. So how can we create a > pure binary kernel? After compiling or assembling your code to object file, but prior to linking, you may be able to use a linker line like below with the object file. This is for GNU ld: ld --oformat binary -Ttext=0xORG -e start -o file.bin file.o You should be able to put multiple objects on the ld line to be linked. I'm not sure if this will link together what you need. (If you're not using GNU toolchain, that will be something different. You'll need to specify which compiler or assembler or toolchain.) "start" is the entry label. 0xORG is the hexadecimal start address or offset the code is being compiled for. That would require a "start" label in GAS assembly like this: .global _start _start: For 64-bit Linux, GCC inserts a "cmain" label: .globl cmain cmain: I'm sure there are some missing details there that you'll have to work out by reading the manuals or or trial and error or help options or searching the net. Rod Pemberton
[toc] | [prev] | [next] | [standalone]
| From | "Alexei A. Frounze" <alexfrunews@gmail.com> |
|---|---|
| Date | 2016-05-27 00:10 -0700 |
| Message-ID | <dd82b9b8-a943-4e41-b73f-620971caf1bd@googlegroups.com> |
| In reply to | #9569 |
On Thursday, May 26, 2016 at 2:51:43 PM UTC-7, Isaac D. Cohen wrote: ... > gcc -c <filename.c> > > But wait. That just created an ELF object file. Furthermore, we can only link with an assembly file that has also been assembled into an object file. We can't link with pure binary. So how can we create a pure binary kernel? > You can tinker with the linker (some support generation of raw/flat/whatever executables; AFAIK you may need a special version of GNU ld, not just any, to be able to make such binaries) or convert the executable into what you want. I have my own linker that can produce raw/flat executables, but it doesn't support 64-bit ELF objects, so it's probably of no use to you (oh, and I didn't test it with gcc's output, only with ELF files produced by NASM, YASM and FASM since my C compiler generates assembly code that needs assembling). Alex
[toc] | [prev] | [next] | [standalone]
| From | Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> |
|---|---|
| Date | 2016-06-02 16:25 -0400 |
| Message-ID | <20160602162528.39880eb6@_> |
| In reply to | #9569 |
On Thu, 26 May 2016 14:51:42 -0700 (PDT) "Isaac D. Cohen" <8switchsoftware@gmail.com> wrote: > So how would we implement this? So, I ran across another project that uses the following options to link NASM code with GCC C code using a linker script and produces a binary. It generates a binary from the linked executable. nasm -f aout gcc -fno-builtin ld -nostdlib -T linker.ld objcopy -O binary Rod Pemberton
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | alt.os.development
csiph-web