Full Code of ashleygwilliams/x86-kernel for AI

master e4f53e367f63 cached
12 files
12.6 KB
4.2k tokens
3 symbols
1 requests
Download .txt
Repository: ashleygwilliams/x86-kernel
Branch: master
Commit: e4f53e367f63
Files: 12
Total size: 12.6 KB

Directory structure:
gitextract_bzkp4t38/

├── .gitignore
├── Cargo.toml
├── LICENSE
├── Makefile
├── README.md
├── Vagrantfile
└── src/
    ├── arch/
    │   └── x86_64/
    │       ├── boot.asm
    │       ├── grub.cfg
    │       ├── linker.ld
    │       ├── long_mode_init.asm
    │       └── multiboot_header.asm
    └── lib.rs

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
multiboot_header
boot
*.o
*.bin
*.iso
.vagrant
target


================================================
FILE: Cargo.toml
================================================
[package]
name = "my_os"
version = "1.0.0"
authors = ["ag_dubs"]

[lib]
crate-type = ["staticlib"]

[dependencies]
rlibc = "0.1.4"


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2015 ashley williams

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.



================================================
FILE: Makefile
================================================
arch ?= x86_64
kernel := build/kernel-$(arch).bin
iso := build/os-$(arch).iso
target ?= $(arch)-unknown-linux-gnu
rust_os := target/$(target)/debug/libmy_os.a

linker_script := src/arch/$(arch)/linker.ld
grub_cfg := src/arch/$(arch)/grub.cfg
assembly_source_files := $(wildcard src/arch/$(arch)/*.asm)
assembly_object_files := $(patsubst src/arch/$(arch)/%.asm, \
	build/arch/$(arch)/%.o, $(assembly_source_files))

.PHONY: all clean run iso

all: $(kernel)

clean:
	@rm -r build

run: $(iso)
	@qemu-system-x86_64 -hda $(iso)

iso: $(iso)

$(iso): $(kernel) $(grub_cfg)
	@mkdir -p build/isofiles/boot/grub
	@cp $(kernel) build/isofiles/boot/kernel.bin
	@cp $(grub_cfg) build/isofiles/boot/grub
	@grub-mkrescue -o $(iso) build/isofiles 2> /dev/null
	@rm -r build/isofiles

$(kernel): cargo $(rust_os) $(assembly_object_files) $(linker_script)
	@ld -n --gc-sections -T $(linker_script) -o $(kernel) $(assembly_object_files) $(rust_os)

cargo:
	@cargo rustc --target $(target) -- -Z no-landing-pads

build/arch/$(arch)/%.o: src/arch/$(arch)/%.asm
	@mkdir -p $(shell dirname $@)
	@nasm -felf64 $< -o $@


================================================
FILE: README.md
================================================
# x86 kernel
> a simple x86 kernel, extended with Rust 

this is my work following along with a [@phil-opp][2]'s blog post series ["A minimal x86 kernel"][1]

## prerequisites

### virtualization
> (if you are on OSX, ChromeOS, Windows, etc)

- [Vagrant]: development environment manager
- [VirtualBox]: virtualizer
- [XQuartz]: X11 Graphics

### linux dependencies
- `nasm`: assembler (assembly -> binary)
- `ld`: linker (makes binary out of other files)
- `grub`: creates the bootable iso
- `xorriso`: req'd by grub, filesystem manipulator
- `QEMU`: fake-computer emulator

### utilities
you don't need these, but they are nice for viewing
generated code.

- `hexdump`: allows you to view generated binary
- `objdump`: a nicer viewer for .o files

## up and running

1. fork and clone this repository
2. navigate into the repo directory: `cd x86-kernel`
3. `$ vagrant up`
4. `$ vagrant ssh -- -Y`
    `-- -Y` forwards graphics
5. `$ multirust default nightly-2015-11-19`
    
    Sets your default rust to a stable nightly. 
    The features needed to do OS work in Rust are
    not yet in a stable release, so you must use
    a nightly build.

6. `$ cd /vagrant`

    The `/vagrant` directory is the virtualized directory
    that is synced with the `/` directory on your HD.

7. `$ make run`

[Vagrant]: https://www.vagrantup.com/
[VirtualBox]: https://www.virtualbox.org/
[XQuartz]: http://www.xquartz.org/
[1]: http://blog.phil-opp.com/rust-os/multiboot-kernel.html
[2]: https://github.com/phil-opp


================================================
FILE: Vagrantfile
================================================
# -*- mode: ruby -*-
# vi: set ft=ruby :

# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure(2) do |config|
  # The most common configuration options are documented and commented below.
  # For a complete reference, please see the online documentation at
  # https://docs.vagrantup.com.

  # Every Vagrant development environment requires a box. You can search for
  # boxes at https://atlas.hashicorp.com/search.
  config.vm.box = "debian/jessie64"

  # Disable automatic box update checking. If you disable this, then
  # boxes will only be checked for updates when the user runs
  # `vagrant box outdated`. This is not recommended.
  # config.vm.box_check_update = false

  # Create a forwarded port mapping which allows access to a specific port
  # within the machine from a port on the host machine. In the example below,
  # accessing "localhost:8080" will access port 80 on the guest machine.
  # config.vm.network "forwarded_port", guest: 80, host: 8080

  # Create a private network, which allows host-only access to the machine
  # using a specific IP.
  # config.vm.network "private_network", ip: "192.168.33.10"

  # Create a public network, which generally matched to bridged network.
  # Bridged networks make the machine appear as another physical device on
  # your network.
  # config.vm.network "public_network"

  # Share an additional folder to the guest VM. The first argument is
  # the path on the host to the actual folder. The second argument is
  # the path on the guest to mount the folder. And the optional third
  # argument is a set of non-required options.
  # config.vm.synced_folder "../data", "/vagrant_data"

  # Provider-specific configuration so you can fine-tune various
  # backing providers for Vagrant. These expose provider-specific options.
  # Example for VirtualBox:
  #
  # config.vm.provider "virtualbox" do |vb|
  #   # Display the VirtualBox GUI when booting the machine
  #   vb.gui = true
  #
  #   # Customize the amount of memory on the VM:
  #   vb.memory = "1024"
  # end
  #
  # View the documentation for the provider you are using for more
  # information on available options.

  # Define a Vagrant Push strategy for pushing to Atlas. Other push strategies
  # such as FTP and Heroku are also available. See the documentation at
  # https://docs.vagrantup.com/v2/push/atlas.html for more information.
  # config.push.define "atlas" do |push|
  #   push.app = "YOUR_ATLAS_USERNAME/YOUR_APPLICATION_NAME"
  # end

  # Enable provisioning with a shell script. Additional provisioners such as
  # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
  # documentation for more information about their specific syntax and use.
   config.vm.provision "shell", inline: <<-SHELL
      sudo apt-get update
      sudo apt-get install nasm -y
      sudo apt-get install xorriso -y
      sudo apt-get install git -y
      sudo apt-get install vim -y
      sudo apt-get install -y qemu
      curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sh -s -- --yes
      multirust default nightly-2015-11-19 
  SHELL

  config.ssh.forward_x11 = true
end


================================================
FILE: src/arch/x86_64/boot.asm
================================================
global start
extern long_mode_start

section .text
bits 32
start:
  mov esp, stack_top 

  ; tests
  call test_multiboot
  call test_cpuid
  call test_long_mode

  ; paging
  call setup_page_tables
  call enable_paging

  lgdt [gdt64.pointer]

  ; update selectors
  mov ax, gdt64.data
  mov ss, ax  ; stack selector
  mov ds, ax  ; data selector
  mov es, ax  ; extra selector

  jmp gdt64.code:long_mode_start ; "trampoline"

  hlt

; prints `ERR: ` + error code 
; parameter: error code (in ascii) in al
error:
  mov dword [0xb8000], 0x4f524f45
  mov dword [0xb8004], 0x4f3a4f52
  mov dword [0xb8008], 0xff204f20
  mov byte [0xb800a], al
  hlt

test_multiboot:
  cmp eax, 0x36d76289
  jne .no_multiboot
  ret
.no_multiboot:
  mov al, "0"
  jmp error

test_cpuid:
    pushfd               ; Store the FLAGS-register.
    pop eax              ; Restore the A-register.
    mov ecx, eax         ; Set the C-register to the A-register.
    xor eax, 1 << 21     ; Flip the ID-bit, which is bit 21.
    push eax             ; Store the A-register.
    popfd                ; Restore the FLAGS-register.
    pushfd               ; Store the FLAGS-register.
    pop eax              ; Restore the A-register.
    push ecx             ; Store the C-register.
    popfd                ; Restore the FLAGS-register.
    xor eax, ecx         ; Do a XOR-operation on the A-register and the C-register.
    jz .no_cpuid         ; The zero flag is set, no CPUID.
    ret                  ; CPUID is available for use.
.no_cpuid:
    mov al, "1"
    jmp error

test_long_mode:
    mov eax, 0x80000000    ; Set the A-register to 0x80000000.
    cpuid                  ; CPU identification.
    cmp eax, 0x80000001    ; Compare the A-register with 0x80000001.
    jb .no_long_mode       ; It is less, there is no long mode.
    mov eax, 0x80000001    ; Set the A-register to 0x80000001.
    cpuid                  ; CPU identification.
    test edx, 1 << 29      ; Test if the LM-bit, which is bit 29, is set in the D-register.
    jz .no_long_mode       ; They aren't, there is no long mode.
    ret
.no_long_mode:
    mov al, "2"
    jmp error

setup_page_tables:
  ; map p4 to p3
  mov eax, p3_table
  or eax, 0b11
  mov [p4_table], eax

  ; map p3 to p2
  mov eax, p2_table
  or eax, 0b11
  mov [p3_table], eax

  mov ecx, 0

.map_p2_table:
  mov eax, 0x200000
  mul ecx
  or eax, 0b10000011
  mov [p2_table + ecx * 8], eax

  ; for loop, increment, compare(=512)
  inc ecx
  cmp ecx, 512
  jne .map_p2_table

  ret

enable_paging:
  ; load P4 to cr3 register (cpu uses this to access the P4 table)
  mov eax, p4_table
  mov cr3, eax

  ; enable PAE-flag in cr4 (Physical Address Extension)
  mov eax, cr4
  or eax, 1 << 5
  mov cr4, eax

  ; set the long mode bit in the EFER MSR (model specific register)
  mov ecx, 0xC0000080
  rdmsr
  or eax, 1 << 8
  wrmsr

  ; enable paging in the cr0 register
  mov eax, cr0
  or eax, 1 << 31
  mov cr0, eax

  ret

section .bss
align 4096
p4_table:
  resb 4096
p3_table:
  resb 4096
p2_table:
  resb 4096
stack_bottom:
  resb 64
stack_top:

section .rodata
gdt64:
  dq 0 ; zero entry
.code: equ $ - gdt64
  dq (1<<44) | (1<<47) | (1<<41) | (1<<43) | (1<<53) ; code segment
.data: equ $ - gdt64
  dq (1<<44) | (1<<47) | (1<<41) ; data segment
.pointer:
  dw $ - gdt64 - 1
  dq gdt64


================================================
FILE: src/arch/x86_64/grub.cfg
================================================
set timeout=0
set default=0

menuentry "my os" {
  multiboot2 /boot/kernel.bin
  boot
}


================================================
FILE: src/arch/x86_64/linker.ld
================================================
ENTRY(start)

SECTIONS {
  /* sets load address to MiB (convention) */
  . = 1M;

  .boot : {
    /* put the header at the beginning */
    KEEP(*(.multiboot_header))
  }

  .text : {
    *(.text)
  }
}


================================================
FILE: src/arch/x86_64/long_mode_init.asm
================================================
global long_mode_start

section .text
bits 64
long_mode_start:
  extern rust_main
  call setup_SSE
  call rust_main 

.os_returned:
    ; rust main returned, print `OS returned!`
    mov rax, 0x4f724f204f534f4f
    mov [0xb8000], rax
    mov rax, 0x4f724f754f744f65
    mov [0xb8008], rax
    mov rax, 0x4f214f644f654f6e
    mov [0xb8010], rax
    hlt

error:
    mov rbx, 0x4f4f4f524f524f45
    mov [0xb8000], rbx
    mov rbx, 0x4f204f204f3a4f52
    mov [0xb8008], rbx
    mov byte [0xb800e], al
    hlt
    jmp error

setup_SSE:
    ; check for SSE
    mov rax, 0x1
    cpuid
    test edx, 1<<25
    jz .no_SSE

    ; enable SSE
    mov rax, cr0
    and ax, 0xFFFB      ; clear coprocessor emulation CR0.EM
    or ax, 0x2          ; set coprocessor monitoring  CR0.MP
    mov cr0, rax
    mov rax, cr4
    or ax, 3 << 9       ; set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time
    mov cr4, rax

    ret
.no_SSE:
    mov al, "a"
    jmp error


================================================
FILE: src/arch/x86_64/multiboot_header.asm
================================================
section .multiboot_header
header_start:
  dd 0xe85250d6                 ; magic number (multiboot 2)
  dd 0                          ; architecture 0 (protected mode i386)
  dd header_end - header_start  ; header length

  ; checksum (magic number + architecture + header length)
  ; we subtract from 0x1... to account for signedness 
  dd 0x100000000 - (0xe85250d6 + 0 + (header_end - header_start))

  ; required end tag (u16, u16, u32)
  dw 0                          ; type
  dw 0                          ; flags
  dd 8                          ; size
header_end:


================================================
FILE: src/lib.rs
================================================
#![feature(no_std)]
#![feature(lang_items)]
#![no_std]

extern crate rlibc;

#[no_mangle]
pub extern fn rust_main() {
  let hello = b"Hello World!";
  let color_byte = 0x1f;

  let mut hello_colored = [color_byte; 24];
  for (i, char_byte) in hello.into_iter().enumerate() {
    hello_colored[i * 2] = *char_byte;
  }

  let buffer_ptr = (0xb8000  +1988) as *mut _;
  unsafe { *buffer_ptr = hello_colored };

  loop{}
}

#[lang = "eh_personality"] extern fn eh_personality() {}
#[lang = "panic_fmt"] extern fn panic_fmt() -> ! { loop{} }
Download .txt
gitextract_bzkp4t38/

├── .gitignore
├── Cargo.toml
├── LICENSE
├── Makefile
├── README.md
├── Vagrantfile
└── src/
    ├── arch/
    │   └── x86_64/
    │       ├── boot.asm
    │       ├── grub.cfg
    │       ├── linker.ld
    │       ├── long_mode_init.asm
    │       └── multiboot_header.asm
    └── lib.rs
Download .txt
SYMBOL INDEX (3 symbols across 1 files)

FILE: src/lib.rs
  function rust_main (line 8) | pub extern fn rust_main() {
  function eh_personality (line 23) | extern fn eh_personality() {}
  function panic_fmt (line 24) | extern fn panic_fmt() -> ! { loop{} }
Condensed preview — 12 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (14K chars).
[
  {
    "path": ".gitignore",
    "chars": 54,
    "preview": "multiboot_header\nboot\n*.o\n*.bin\n*.iso\n.vagrant\ntarget\n"
  },
  {
    "path": "Cargo.toml",
    "chars": 131,
    "preview": "[package]\nname = \"my_os\"\nversion = \"1.0.0\"\nauthors = [\"ag_dubs\"]\n\n[lib]\ncrate-type = [\"staticlib\"]\n\n[dependencies]\nrlibc"
  },
  {
    "path": "LICENSE",
    "chars": 1083,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2015 ashley williams\n\nPermission is hereby granted, free of charge, to any person o"
  },
  {
    "path": "Makefile",
    "chars": 1099,
    "preview": "arch ?= x86_64\nkernel := build/kernel-$(arch).bin\niso := build/os-$(arch).iso\ntarget ?= $(arch)-unknown-linux-gnu\nrust_o"
  },
  {
    "path": "README.md",
    "chars": 1506,
    "preview": "# x86 kernel\n> a simple x86 kernel, extended with Rust \n\nthis is my work following along with a [@phil-opp][2]'s blog po"
  },
  {
    "path": "Vagrantfile",
    "chars": 3340,
    "preview": "# -*- mode: ruby -*-\n# vi: set ft=ruby :\n\n# All Vagrant configuration is done below. The \"2\" in Vagrant.configure\n# conf"
  },
  {
    "path": "src/arch/x86_64/boot.asm",
    "chars": 3313,
    "preview": "global start\nextern long_mode_start\n\nsection .text\nbits 32\nstart:\n  mov esp, stack_top \n\n  ; tests\n  call test_multiboot"
  },
  {
    "path": "src/arch/x86_64/grub.cfg",
    "chars": 88,
    "preview": "set timeout=0\nset default=0\n\nmenuentry \"my os\" {\n  multiboot2 /boot/kernel.bin\n  boot\n}\n"
  },
  {
    "path": "src/arch/x86_64/linker.ld",
    "chars": 203,
    "preview": "ENTRY(start)\n\nSECTIONS {\n  /* sets load address to MiB (convention) */\n  . = 1M;\n\n  .boot : {\n    /* put the header at t"
  },
  {
    "path": "src/arch/x86_64/long_mode_init.asm",
    "chars": 946,
    "preview": "global long_mode_start\n\nsection .text\nbits 64\nlong_mode_start:\n  extern rust_main\n  call setup_SSE\n  call rust_main \n\n.o"
  },
  {
    "path": "src/arch/x86_64/multiboot_header.asm",
    "chars": 569,
    "preview": "section .multiboot_header\nheader_start:\n  dd 0xe85250d6                 ; magic number (multiboot 2)\n  dd 0             "
  },
  {
    "path": "src/lib.rs",
    "chars": 538,
    "preview": "#![feature(no_std)]\n#![feature(lang_items)]\n#![no_std]\n\nextern crate rlibc;\n\n#[no_mangle]\npub extern fn rust_main() {\n  "
  }
]

About this extraction

This page contains the full source code of the ashleygwilliams/x86-kernel GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 12 files (12.6 KB), approximately 4.2k tokens, and a symbol index with 3 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!