Compare commits
3 Commits
e8fa7e1f28
...
cd0e1cafae
| Author | SHA1 | Date | |
|---|---|---|---|
| cd0e1cafae | |||
| f42d65267b | |||
| 6d9ab26423 |
@@ -7,7 +7,7 @@
|
|||||||
# - CMake + Ninja for the build system
|
# - CMake + Ninja for the build system
|
||||||
# - xorriso and mtools used internally by grub-mkrescue / grub-mkimage
|
# - xorriso and mtools used internally by grub-mkrescue / grub-mkimage
|
||||||
|
|
||||||
FROM alpine:3.23
|
FROM --platform=linux/amd64 alpine:3.23
|
||||||
|
|
||||||
RUN apk add --no-cache \
|
RUN apk add --no-cache \
|
||||||
# Core build tools
|
# Core build tools
|
||||||
@@ -19,6 +19,7 @@ RUN apk add --no-cache \
|
|||||||
git \
|
git \
|
||||||
# GRUB image generation
|
# GRUB image generation
|
||||||
grub \
|
grub \
|
||||||
|
grub-bios \
|
||||||
xorriso \
|
xorriso \
|
||||||
mtools \
|
mtools \
|
||||||
# QEMU for running the OS
|
# QEMU for running the OS
|
||||||
|
|||||||
9
CMakeLists.txt
Normal file
9
CMakeLists.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.20)
|
||||||
|
|
||||||
|
project(ClaudeOS C ASM)
|
||||||
|
|
||||||
|
set(CMAKE_C_STANDARD 11)
|
||||||
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
# Kernel
|
||||||
|
add_subdirectory(src)
|
||||||
2
HUMAN.md
2
HUMAN.md
@@ -3,7 +3,7 @@ This document describes which files are written fully by humans, which had human
|
|||||||
|
|
||||||
## Fully Human
|
## Fully Human
|
||||||
The following files were written completely by humans:
|
The following files were written completely by humans:
|
||||||
- `HUMAN.md`
|
- `HUMAN.md` (except for the checkmarks in the tasklist)
|
||||||
- `README.md`
|
- `README.md`
|
||||||
- Everything in `vendor/`. While we don't actually know if it was written by humans, certainly the AI used for this project has not touched it.
|
- Everything in `vendor/`. While we don't actually know if it was written by humans, certainly the AI used for this project has not touched it.
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ An AI implementing this operating system should implement features in this order
|
|||||||
After each feature, it should create a new Git commit and push the commit.
|
After each feature, it should create a new Git commit and push the commit.
|
||||||
The git commit should describe what is done and why certain choices were made.
|
The git commit should describe what is done and why certain choices were made.
|
||||||
The title of the commit should always end with (AI), to indicate that it was written by an AI.
|
The title of the commit should always end with (AI), to indicate that it was written by an AI.
|
||||||
|
Once a task is completed, it should be checked off.
|
||||||
|
|
||||||
- [ ] Create directory structure
|
- [ ] Create directory structure
|
||||||
- [ ] Create initial build system
|
- [ ] Create initial build system
|
||||||
|
|||||||
59
cmake/toolchain-i386-clang.cmake
Normal file
59
cmake/toolchain-i386-clang.cmake
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# Cross-compilation toolchain for i386-elf using Clang + LLD.
|
||||||
|
#
|
||||||
|
# This targets a bare-metal i386 (80386) environment with no host OS
|
||||||
|
# libraries. lld is used as the linker because the macOS system ld does
|
||||||
|
# not support the ELF32 output format required for a GRUB-bootable kernel.
|
||||||
|
|
||||||
|
set(CMAKE_SYSTEM_NAME Generic)
|
||||||
|
set(CMAKE_SYSTEM_PROCESSOR i386)
|
||||||
|
|
||||||
|
# Use Clang for both C and assembly.
|
||||||
|
set(CMAKE_C_COMPILER clang)
|
||||||
|
set(CMAKE_ASM_COMPILER clang)
|
||||||
|
|
||||||
|
# Prevent CMake from trying to run the cross-compiled test binaries.
|
||||||
|
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||||
|
|
||||||
|
# Target triple and architecture flags shared by all compilation steps.
|
||||||
|
set(CROSS_TARGET "i386-elf")
|
||||||
|
set(CROSS_ARCH_FLAGS "-target ${CROSS_TARGET} -m32 -march=i386 -mtune=i386")
|
||||||
|
|
||||||
|
# C compiler flags:
|
||||||
|
# - ffreestanding : no hosted C runtime assumptions
|
||||||
|
# - fno-stack-protector : no __stack_chk_fail dependency
|
||||||
|
# - fno-builtin : avoid implicit replacements of standard functions
|
||||||
|
set(CMAKE_C_FLAGS_INIT
|
||||||
|
"${CROSS_ARCH_FLAGS} -ffreestanding -fno-stack-protector -fno-builtin -Wall -Wextra"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Assembler flags: only the flags the assembler front-end actually accepts.
|
||||||
|
# C-only flags like -ffreestanding, -fno-stack-protector, etc. must NOT be
|
||||||
|
# passed here — clang treats them as unused and errors out with -Werror.
|
||||||
|
# -Wno-unused-command-line-argument suppresses CMake's auto-added -MD/-MT/-MF
|
||||||
|
# dependency-tracking flags that clang ignores in pure assembler mode.
|
||||||
|
set(CMAKE_ASM_FLAGS_INIT
|
||||||
|
"-target ${CROSS_TARGET} -m32 -march=i386 -Wno-unused-command-line-argument"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Linking:
|
||||||
|
# On aarch64 Alpine the clang driver delegates link steps to the host gcc,
|
||||||
|
# which does not support -m32 and therefore fails. Bypass the driver entirely
|
||||||
|
# and call ld.lld directly. The CMake rule variables below replace the normal
|
||||||
|
# "compile-with-compiler-driver" link invocation.
|
||||||
|
#
|
||||||
|
# Rule variables use these placeholders:
|
||||||
|
# <TARGET> — output binary path
|
||||||
|
# <OBJECTS> — all compiled object files
|
||||||
|
# <LINK_FLAGS> — extra flags from target_link_options / CMAKE_EXE_LINKER_FLAGS
|
||||||
|
# <LINK_LIBRARIES> — libraries to link (empty for a freestanding kernel)
|
||||||
|
set(CMAKE_LINKER "ld.lld")
|
||||||
|
set(CMAKE_C_LINK_EXECUTABLE
|
||||||
|
"ld.lld -m elf_i386 <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
|
||||||
|
set(CMAKE_ASM_LINK_EXECUTABLE
|
||||||
|
"ld.lld -m elf_i386 <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
|
||||||
|
|
||||||
|
# Keep CMake from accidentally picking up host system headers/libraries.
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||||
33
src/CMakeLists.txt
Normal file
33
src/CMakeLists.txt
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
set(KERNEL_SOURCES
|
||||||
|
boot/boot.s
|
||||||
|
kernel.c
|
||||||
|
debugport.c
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(kernel ${KERNEL_SOURCES})
|
||||||
|
|
||||||
|
target_include_directories(kernel PRIVATE
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_options(kernel PRIVATE
|
||||||
|
# C-only flags — not valid for the assembler front-end.
|
||||||
|
$<$<COMPILE_LANGUAGE:C>:-Werror>
|
||||||
|
$<$<COMPILE_LANGUAGE:C>:-ffreestanding>
|
||||||
|
$<$<COMPILE_LANGUAGE:C>:-fno-stack-protector>
|
||||||
|
$<$<COMPILE_LANGUAGE:C>:-fno-exceptions>
|
||||||
|
# Suppress the harmless "argument unused" warnings that clang emits
|
||||||
|
# when CMake passes -MD/-MT/-MF to the assembler.
|
||||||
|
$<$<COMPILE_LANGUAGE:ASM>:-Wno-unused-command-line-argument>
|
||||||
|
)
|
||||||
|
|
||||||
|
set_target_properties(kernel PROPERTIES
|
||||||
|
OUTPUT_NAME "claudeos.elf"
|
||||||
|
SUFFIX ""
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_options(kernel PRIVATE
|
||||||
|
# Pass the linker script directly to ld.lld (CMAKE_C_LINK_EXECUTABLE
|
||||||
|
# calls ld.lld directly, so these are raw ld flags, not clang driver flags).
|
||||||
|
-T ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld
|
||||||
|
)
|
||||||
92
src/boot/boot.s
Normal file
92
src/boot/boot.s
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* boot.s — Multiboot-compliant bootstrap for ClaudeOS.
|
||||||
|
*
|
||||||
|
* This file is the very first code executed by GRUB after the kernel is
|
||||||
|
* loaded. Its responsibilities are:
|
||||||
|
*
|
||||||
|
* 1. Provide a valid Multiboot header so that GRUB recognises the image.
|
||||||
|
* 2. Zero the BSS segment (the C runtime requires it to start at zero).
|
||||||
|
* 3. Set up a small temporary stack.
|
||||||
|
* 4. Forward the Multiboot magic value and info-structure pointer to
|
||||||
|
* kernel_main() as its first and second arguments.
|
||||||
|
* 5. Halt the CPU if kernel_main() ever returns (it should not).
|
||||||
|
*
|
||||||
|
* Multiboot flags used:
|
||||||
|
* Bit 0 — 4 KiB-align all boot modules.
|
||||||
|
* Bit 1 — Include memory map in the Multiboot info structure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------
|
||||||
|
* Multiboot header
|
||||||
|
* ------------------------------------------------------------------------- */
|
||||||
|
.set MULTIBOOT_MAGIC, 0x1BADB002
|
||||||
|
.set MULTIBOOT_FLAGS, (1 << 0) | (1 << 1)
|
||||||
|
.set MULTIBOOT_CHECKSUM, -(MULTIBOOT_MAGIC + MULTIBOOT_FLAGS)
|
||||||
|
|
||||||
|
.section .multiboot, "a"
|
||||||
|
.align 4
|
||||||
|
.long MULTIBOOT_MAGIC
|
||||||
|
.long MULTIBOOT_FLAGS
|
||||||
|
.long MULTIBOOT_CHECKSUM
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------
|
||||||
|
* Bootstrap stack — 16 KiB, 16-byte aligned (required by the i386 ABI).
|
||||||
|
* ------------------------------------------------------------------------- */
|
||||||
|
.section .bss
|
||||||
|
.align 16
|
||||||
|
stack_bottom:
|
||||||
|
.skip 16384
|
||||||
|
stack_top:
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------
|
||||||
|
* Kernel entry point
|
||||||
|
* ------------------------------------------------------------------------- */
|
||||||
|
.section .text
|
||||||
|
.global _start
|
||||||
|
.type _start, @function
|
||||||
|
_start:
|
||||||
|
/* Set up the temporary kernel stack. */
|
||||||
|
mov $stack_top, %esp
|
||||||
|
|
||||||
|
/* Preserve the Multiboot magic before the BSS-clearing loop clobbers EAX.
|
||||||
|
*
|
||||||
|
* Registers on entry (Multiboot spec §3.2):
|
||||||
|
* eax — 0x2BADB002 (magic)
|
||||||
|
* ebx — multiboot_info_t* (physical address of info structure)
|
||||||
|
*
|
||||||
|
* 'rep stosb' only modifies EAX, EDI and ECX, so EBX survives intact.
|
||||||
|
* We park EAX in ESI (callee-saved, not used by the BSS loop). */
|
||||||
|
mov %eax, %esi /* save Multiboot magic */
|
||||||
|
|
||||||
|
/* Zero the BSS segment.
|
||||||
|
* The C standard requires that all static storage is zero-initialised.
|
||||||
|
* The linker script exports _bss_start and _bss_end for this purpose. */
|
||||||
|
mov $_bss_start, %edi
|
||||||
|
mov $_bss_end, %ecx
|
||||||
|
sub %edi, %ecx /* byte count */
|
||||||
|
xor %eax, %eax
|
||||||
|
rep stosb
|
||||||
|
|
||||||
|
/* Restore magic; EBX (info pointer) is still intact. */
|
||||||
|
mov %esi, %eax
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call kernel_main(uint32_t multiboot_magic, uint32_t multiboot_info).
|
||||||
|
*
|
||||||
|
* The Multiboot specification passes:
|
||||||
|
* eax — 0x2BADB002 (bootloader magic)
|
||||||
|
* ebx — physical address of the multiboot_info_t structure
|
||||||
|
*
|
||||||
|
* We push them in reverse order to match the C calling convention.
|
||||||
|
*/
|
||||||
|
push %ebx /* arg1: multiboot_info pointer */
|
||||||
|
push %eax /* arg0: multiboot magic */
|
||||||
|
call kernel_main
|
||||||
|
|
||||||
|
/* kernel_main should never return; halt the machine if it does. */
|
||||||
|
.L_halt:
|
||||||
|
cli
|
||||||
|
hlt
|
||||||
|
jmp .L_halt
|
||||||
|
|
||||||
|
.size _start, . - _start
|
||||||
39
src/debugport.c
Normal file
39
src/debugport.c
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* @file debugport.c
|
||||||
|
* @brief QEMU/Bochs debug port (I/O port 0xE9) implementation.
|
||||||
|
*
|
||||||
|
* Writing a byte to I/O port 0xE9 causes QEMU (when run with
|
||||||
|
* `-debugcon stdio`) to echo that byte verbatim to the host's stdout.
|
||||||
|
* This requires no peripheral initialisation and is available from the
|
||||||
|
* very first instruction after the bootloader hands control to the kernel.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <debugport.h>
|
||||||
|
#include <io.h>
|
||||||
|
|
||||||
|
/** I/O port address of the QEMU/Bochs debug console. */
|
||||||
|
#define DEBUG_PORT 0xE9U
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write a single character to the QEMU debug port.
|
||||||
|
*
|
||||||
|
* @param c Character to transmit.
|
||||||
|
*/
|
||||||
|
void debugport_putc(char c)
|
||||||
|
{
|
||||||
|
outb((uint16_t)DEBUG_PORT, (uint8_t)c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write a NUL-terminated string to the QEMU debug port.
|
||||||
|
*
|
||||||
|
* Each character is transmitted individually via debugport_putc().
|
||||||
|
*
|
||||||
|
* @param s Pointer to the NUL-terminated string. Must not be NULL.
|
||||||
|
*/
|
||||||
|
void debugport_puts(const char *s)
|
||||||
|
{
|
||||||
|
while (*s) {
|
||||||
|
debugport_putc(*s++);
|
||||||
|
}
|
||||||
|
}
|
||||||
34
src/include/debugport.h
Normal file
34
src/include/debugport.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* @file debugport.h
|
||||||
|
* @brief QEMU/Bochs debug port (I/O port 0xE9) output interface.
|
||||||
|
*
|
||||||
|
* Port 0xE9 is a de-facto standard "debug port" supported by both Bochs and
|
||||||
|
* QEMU (when launched with `-debugcon stdio`). Any byte written to this port
|
||||||
|
* is immediately forwarded to the host's standard output, making it the
|
||||||
|
* simplest possible kernel logging mechanism — no interrupt handling, VGA, or
|
||||||
|
* serial initialisation is required.
|
||||||
|
*
|
||||||
|
* Usage in QEMU:
|
||||||
|
* qemu-system-i386 -debugcon stdio ...
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write a single character to the QEMU debug port.
|
||||||
|
*
|
||||||
|
* Issues a single OUT instruction to port 0xE9.
|
||||||
|
*
|
||||||
|
* @param c Character to transmit.
|
||||||
|
*/
|
||||||
|
void debugport_putc(char c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write a NUL-terminated string to the QEMU debug port.
|
||||||
|
*
|
||||||
|
* Iterates over every character in @p s and calls debugport_putc() for each
|
||||||
|
* one. The terminating NUL byte is not transmitted.
|
||||||
|
*
|
||||||
|
* @param s Pointer to the NUL-terminated string. Must not be NULL.
|
||||||
|
*/
|
||||||
|
void debugport_puts(const char *s);
|
||||||
41
src/include/io.h
Normal file
41
src/include/io.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/**
|
||||||
|
* @file io.h
|
||||||
|
* @brief Low-level x86 port I/O helpers.
|
||||||
|
*
|
||||||
|
* Provides thin wrappers around the x86 IN/OUT instructions so that C code
|
||||||
|
* throughout the kernel can read from and write to I/O ports without
|
||||||
|
* resorting to inline assembly at every call site.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write an 8-bit value to an I/O port.
|
||||||
|
*
|
||||||
|
* Issues an x86 OUT instruction. Execution halts until the peripheral
|
||||||
|
* acknowledges the write (the CPU inserts appropriate bus wait-states).
|
||||||
|
*
|
||||||
|
* @param port 16-bit I/O port address.
|
||||||
|
* @param value 8-bit value to send.
|
||||||
|
*/
|
||||||
|
static inline void outb(uint16_t port, uint8_t value)
|
||||||
|
{
|
||||||
|
__asm__ volatile("outb %0, %1" : : "a"(value), "Nd"(port));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read an 8-bit value from an I/O port.
|
||||||
|
*
|
||||||
|
* Issues an x86 IN instruction.
|
||||||
|
*
|
||||||
|
* @param port 16-bit I/O port address.
|
||||||
|
* @return The 8-bit value returned by the peripheral.
|
||||||
|
*/
|
||||||
|
static inline uint8_t inb(uint16_t port)
|
||||||
|
{
|
||||||
|
uint8_t value;
|
||||||
|
__asm__ volatile("inb %1, %0" : "=a"(value) : "Nd"(port));
|
||||||
|
return value;
|
||||||
|
}
|
||||||
45
src/kernel.c
Normal file
45
src/kernel.c
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/**
|
||||||
|
* @file kernel.c
|
||||||
|
* @brief Kernel entry point.
|
||||||
|
*
|
||||||
|
* Called by the Multiboot bootstrap (boot/boot.s) after the BSS has been
|
||||||
|
* zeroed and a temporary stack has been established. The bootloader passes
|
||||||
|
* the Multiboot magic value and a pointer to the Multiboot info structure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <debugport.h>
|
||||||
|
|
||||||
|
/** Magic value the bootloader stores in EAX before jumping to _start. */
|
||||||
|
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002U
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Main kernel entry point.
|
||||||
|
*
|
||||||
|
* Validates the Multiboot magic so we know the bootloader handed us a proper
|
||||||
|
* info structure, then writes a greeting to the QEMU debug port so the host
|
||||||
|
* can confirm the kernel reached C code successfully.
|
||||||
|
*
|
||||||
|
* @param multiboot_magic 0x2BADB002 when booted by a Multiboot-compliant
|
||||||
|
* bootloader (e.g. GRUB).
|
||||||
|
* @param multiboot_info Physical address of the multiboot_info_t structure
|
||||||
|
* provided by the bootloader.
|
||||||
|
*/
|
||||||
|
void kernel_main(uint32_t multiboot_magic, uint32_t multiboot_info)
|
||||||
|
{
|
||||||
|
(void)multiboot_info;
|
||||||
|
|
||||||
|
/* Announce ourselves on the QEMU debug port.
|
||||||
|
* QEMU must be launched with -debugcon stdio for this to appear. */
|
||||||
|
if (multiboot_magic == MULTIBOOT_BOOTLOADER_MAGIC) {
|
||||||
|
debugport_puts("Hello, World!\n");
|
||||||
|
debugport_puts("ClaudeOS kernel booted successfully.\n");
|
||||||
|
} else {
|
||||||
|
debugport_puts("ERROR: bad Multiboot magic — not booted by GRUB?\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Spin forever. Subsequent commits will add real work here. */
|
||||||
|
for (;;) {
|
||||||
|
__asm__ volatile("hlt");
|
||||||
|
}
|
||||||
|
}
|
||||||
53
src/linker.ld
Normal file
53
src/linker.ld
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Linker script for the ClaudeOS kernel.
|
||||||
|
*
|
||||||
|
* The kernel is loaded by GRUB at physical address 0x00100000 (1 MiB).
|
||||||
|
* All kernel sections follow immediately after the multiboot header so that
|
||||||
|
* GRUB can locate it within the first 8 KiB of the ELF image as required by
|
||||||
|
* the Multiboot specification.
|
||||||
|
*
|
||||||
|
* Symbol _bss_start / _bss_end are exported so the bootstrap can zero the
|
||||||
|
* BSS segment before jumping to C code. _kernel_end marks the first byte
|
||||||
|
* after the kernel image, which the physical memory allocator will use as
|
||||||
|
* its starting address.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OUTPUT_FORMAT(elf32-i386)
|
||||||
|
OUTPUT_ARCH(i386)
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x00100000;
|
||||||
|
|
||||||
|
/* The multiboot header must appear within the first 8 KiB. */
|
||||||
|
.multiboot ALIGN(4) :
|
||||||
|
{
|
||||||
|
KEEP(*(.multiboot))
|
||||||
|
}
|
||||||
|
|
||||||
|
.text ALIGN(4096) :
|
||||||
|
{
|
||||||
|
*(.text*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.rodata ALIGN(4096) :
|
||||||
|
{
|
||||||
|
*(.rodata*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.data ALIGN(4096) :
|
||||||
|
{
|
||||||
|
*(.data*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.bss ALIGN(4096) :
|
||||||
|
{
|
||||||
|
_bss_start = .;
|
||||||
|
*(COMMON)
|
||||||
|
*(.bss*)
|
||||||
|
_bss_end = .;
|
||||||
|
}
|
||||||
|
|
||||||
|
_kernel_end = .;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user