mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-16 22:37:49 +00:00
Add section about kernel elf sections
This commit is contained in:
@@ -72,6 +72,46 @@ If you give QEMU more than 4GiB of memory by passing `-m 5G`, you get another un
|
|||||||
[Memory_map]: http://wiki.osdev.org/Memory_Map_(x86)
|
[Memory_map]: http://wiki.osdev.org/Memory_Map_(x86)
|
||||||
|
|
||||||
### Kernel ELF Sections
|
### Kernel ELF Sections
|
||||||
|
To read and print the sections of our kernel ELF file, we can use the _Elf-sections_ tag:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
println!("kernel sections:");
|
||||||
|
for section in boot_info.elf_sections_tag().unwrap().sections() {
|
||||||
|
println!(" addr: 0x{:x}, size: 0x{:x}, flags: 0x{:x}",
|
||||||
|
section.addr, section.size, section.flags);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
This should print out the start address and size of all kernel sections. If the section is writable, the `0x1` is set in `flags`. The `0x4` bit marks an executable section and the `0x2` indicates that the section was loaded in memory. For example, the `.text` section is executable but not writable and the `.data` section just the opposite.
|
||||||
|
|
||||||
|
But when we execute it, tons of really small sections are printed. We can use the `objdump -h build/kernel-x86_64.bin` command to list the sections with name. There seem to be over 200 sections and many of them start with `.text.*` or `.data.rel.ro.local.*`. The Rust compiler puts each function in an own `.text` subsection. To merge these subsections, we can update our linker script:
|
||||||
|
|
||||||
|
```
|
||||||
|
SECTIONS {
|
||||||
|
. = 1M;
|
||||||
|
|
||||||
|
.boot :
|
||||||
|
{
|
||||||
|
KEEP(*(.multiboot_header))
|
||||||
|
}
|
||||||
|
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
*(.text .text.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.rodata : {
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.data.rel.ro : {
|
||||||
|
*(.data.rel.ro.local*) *(.data.rel.ro .data.rel.ro.*)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
These lines are taken from the default linker script of `ld`, which can be obtained through `ld ‑verbose`. Now there are only 12 sections left and we get a much more useful output:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## Start and End of Kernel
|
## Start and End of Kernel
|
||||||
We can now use the ELF section tag to calculate the start and end address of our loaded kernel:
|
We can now use the ELF section tag to calculate the start and end address of our loaded kernel:
|
||||||
|
|||||||
@@ -27,6 +27,14 @@ SECTIONS {
|
|||||||
|
|
||||||
.text :
|
.text :
|
||||||
{
|
{
|
||||||
*(.text)
|
*(.text .text.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.rodata : {
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.data.rel.ro : {
|
||||||
|
*(.data.rel.ro.local*) *(.data.rel.ro .data.rel.ro.*)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,12 @@ pub extern fn rust_main(multiboot_information_address: usize) {
|
|||||||
println!(" start: 0x{:x}, length: 0x{:x}", area.base_addr, area.length);
|
println!(" start: 0x{:x}, length: 0x{:x}", area.base_addr, area.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println!("kernel sections:");
|
||||||
|
for section in boot_info.elf_sections_tag().unwrap().sections() {
|
||||||
|
println!(" addr: 0x{:x}, size: 0x{:x}, flags: 0x{:x}",
|
||||||
|
section.addr, section.size, section.flags);
|
||||||
|
}
|
||||||
|
|
||||||
loop{}
|
loop{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user