Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upLong mode #8
Conversation
japaric
added some commits
Sep 18, 2016
This comment has been minimized.
This comment has been minimized.
|
@homunkulus try |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
|
japaric
reviewed
Sep 18, 2016
| accessed via pure Rust, AFAIK. For that reason, this part is written in inline assembly. | ||
| - Caveat: Because we are telling `rustc` to use a 32-bit target, `rustc` always emit 32-bit | ||
| instructions and we can't actually use 64-bit instructions/registers in the section of the program | ||
| where the CPU is already in long mode. Yikes, I'll have to think about how to solve this. |
This comment has been minimized.
This comment has been minimized.
japaric
Sep 18, 2016
Author
Contributor
I think this can be solved by splitting this crate in two: one crates that does the booting process and is compiled for a 32-bit target and the other crate that exposes the long_mode_start symbol and is compiled for a 64-bit target. The issue is that I think the compiler won't link together crates compiled for different types (imagine mixing a crate compiled for ARM with a crate compiled for x86). If that's the case we could compiled the boot crate as a staticlib and link that staticlib into the long crate. That should bypass the "same target" check.
All this is speculation from my part. I don't know if it will actually work.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
@homunkulus try |
This comment has been minimized.
This comment has been minimized.
japaric
reviewed
Sep 18, 2016
| // extra selector | ||
| asm!("mov es, ax" :::: "intel"); | ||
|
|
||
| // FIXME Is this the right syntax for a far jump? |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
@homunkulus try |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
|
steveklabnik
approved these changes
Sep 18, 2016
| accessed via pure Rust, AFAIK. For that reason, this part is written in inline assembly. | ||
| - Caveat: Because we are telling `rustc` to use a 32-bit target, `rustc` always emit 32-bit | ||
| instructions and we can't actually use 64-bit instructions/registers in the section of the program | ||
| where the CPU is already in long mode. Yikes, I'll have to think about how to solve this. |
This comment has been minimized.
This comment has been minimized.
|
|
||
| // move page table address to cr3 | ||
| asm!("mov eax, p4_table | ||
| mov cr3, eax" :::: "intel"); |
This comment has been minimized.
This comment has been minimized.
steveklabnik
Sep 18, 2016
https://crates.io/crates/x86 would be neat to use here, but it also only supports 64-bit for now, IIRC.
This comment has been minimized.
This comment has been minimized.
phil-opp
Sep 18, 2016
They added support for 32 bit lately, but I'm not sure if it's already on crates.io…
This comment has been minimized.
This comment has been minimized.
| // extra selector | ||
| asm!("mov es, ax" :::: "intel"); | ||
|
|
||
| // FIXME Is this the right syntax for a far jump? |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
steveklabnik
commented
Sep 23, 2016
|
A thought that I've been rolling around in my head, but haven't tried to implement yet. What about having a |
This comment has been minimized.
This comment has been minimized.
|
@steveklabnik That would have to shell out to an external assembler like |
This comment has been minimized.
This comment has been minimized.
steveklabnik
commented
Sep 23, 2016
|
Yeah, it would still require shelling out. It's not a perfect solution, but Even worse idea: one huge "inline asm" Rust block? lololol On Fri, Sep 23, 2016 at 2:48 PM, Jorge Aparicio notifications@github.com
|
This comment has been minimized.
This comment has been minimized.
|
Another approach that could work is have a single x86_64 target, split the boot code into its own crate, compile that I tried this but I couldn't figure a combination of |
This comment has been minimized.
This comment has been minimized.
|
This comment has been minimized.
This comment has been minimized.
steveklabnik
commented
Sep 23, 2016
|
I bet you could configure start? Hm. On Fri, Sep 23, 2016 at 2:54 PM, Jorge Aparicio notifications@github.com
|
This comment has been minimized.
This comment has been minimized.
phil-opp
commented
Sep 23, 2016
|
A naked extern function with |
This comment has been minimized.
This comment has been minimized.
Ericson2314
commented
Sep 23, 2016
|
I'm guessing a similar situation arises when using arm's dynamic endianness to mix ABIs. To me this is proof that the problem is general enough that Cargo should get a proper solution for this. I do believe baking exact targets into packages is bad, so I guess the solution would be "chameleon targets" that change their definition based on the crate being built? On the other hand two such crates may share the same dependency in which case it is should be configured (flags) + compiled differently, so naive per-crate target shape-shifting won't work. |
This comment has been minimized.
This comment has been minimized.
steveklabnik
commented
Sep 26, 2016
|
I implemented the "build using nasm in a build script" over here: intermezzOS/kernel#63 That nasty build script can be made much nicer with the gcc crate, but then you have to use a syntax gcc understands, which isn't nasm. and i haven't taken the time to port it over yet. I still find #8 (comment) very interesting |
This comment has been minimized.
This comment has been minimized.
steveklabnik
commented
Sep 26, 2016
|
So, I'm giving that idea a try. I got a
So, something must be slightly off. But I think this might work? |
This comment has been minimized.
This comment has been minimized.
steveklabnik
commented
Sep 26, 2016
|
So, @mkpankov pointed out this:
It's going to know that it's a 32-bit ELF file, and not link it in. Given this,
Seems like it's probably the correct approach. |
This comment has been minimized.
This comment has been minimized.
steveklabnik
commented
Sep 26, 2016
|
Regarding the "can inline asm do BITS 32", I got a tweet that says yes: https://twitter.com/rpjohnst/status/780474494066450433 |
This comment has been minimized.
This comment has been minimized.
|
@steveklabnik did the libboot.a approach work in the end? I tried the two targets, x86 and x86_64, approach and hitted the same problem: the libboot.a (a rust crate compiled as a staticlib) compiled for x86 was a 32-bit elf/library and got ignored by the linker when I tried to link it to the x86_64
Yeah, but LLVM isn't cooperating :-/. |
This comment has been minimized.
This comment has been minimized.
steveklabnik
commented
Sep 26, 2016
|
I couldn't get it to work, due to the 64/32 issue. |
This comment has been minimized.
This comment has been minimized.
steveklabnik
commented
Sep 26, 2016
|
One other idea I had: if we converted into intel syntax rather than nasm-specific, we could just use the gcc crate to build it. rust already uses gcc for the linker, so that would eliminate one more dep... |
steveklabnik
reviewed
Oct 12, 2016
| p4_table[0] = &p3_table[0] as *const _ as usize as u64 | 0b11; | ||
| p3_table[0] = &p2_table[0] as *const _ as usize as u64 | 0b11; | ||
|
|
||
| for (entry, i) in p2_table.iter_mut().zip(0..) { |
japaric commentedSep 18, 2016
cc @steveklabnik @phil-opp