How does GRUB load the kernel at 0x100000 - x86-64

I'm writing a bootloader and kernel from scratch and my goal is to create a kernel that can both be loaded by GRUB and my bootloader. The issue isn't with the kernel, though. I don't know how to load the kernel at 0x100000 which is where grub loads the kernel. 0x100000 is not small enough to fit into a 16 bit register and it is too large to reach using segmentation (using address buffer es:bx when reading the disk using BIOS interrupt).
So my question is, how does GRUB load the kernel that far into memory?

I am working on building a kernel through the Little Os Book and as far as I can tell the kernel is loaded at the 1MB address because it is specified in a linker script.
You can check out the book here, read the section Linking The Kernel

Related

Machinecode and hardware

first of all hello to all hope you are good and safe.
well i have some questions about machine code and hardware and operating system.
1- i was search about how is pure machine code and i find somethings in here and net but not enough to answer my questions since im new to low level programming language. so how to write a pure machine code like open just my computer with 0,1 are machine code have any file extensions like assembly and .exe i wana write code just directly get area in ram and talk with processor and do what i writed for example open my computer or open a text file for example. so i wana know how to do it are pure machine code have a file extension like .exe or .asm
2- i know each cpu have it owen machine language somethigns is different on them it could not be a way to all cpu's undrestand our machine code. also i wana know for example we have 2 cpu both of them are x64 or x32 but 1 of them are windows other is linux are machine code of x64 windows will work also on x64 cpu linux?
thank you for give your time to me and read.
for now gathering information
An operating system provides the capability to run programs.  So, one program, like the desktop or command line shell, can ask the operating system to run another program.
When that happens, the operating system creates an environment to run the program called a process, and then loads a program file from disc into the process, and directs the CPU to begin executing that program file starting at its beginning.
The operating system has a loader, whose job is to load the disc-based program file into memory of the process.
The loader knows about certain executable file formats.  Different operating system have different loaders and most likely understand different executable formats.
Machine code is contained in these program files, stored on disc using those file formats.  There are other ways to load machine code into memory, though a program file stored on disc loaded by the loader is the most common approach.
Asm, .asm, is a text file, human readable, for storing program code in assembly language.  To use it, such text file is given as input to a build system, which converts that human readable program code into a program file containing equivalent machine code, for later loading into a process by the operating system.
Not only do different operating systems support different file formats for program files, they also support different ways to interact with the operating system, which goes to their programming model that is described by an Application Binary Interface aka ABI.  All programs need to interact with the operating system for basic services like input, output, mouse, keyboard, etc..  Because ABIs differ between operating systems, the machine code in a program written for one operating system won't necessarily run on a different operating system, even if the processor is exactly the same.
Most disc-based file formats for executable program files contain indicators telling what processor the program will run on, so the same operating system on different processors requires different machine code, and hence usually different executable program files.  (Some file formats support "fat" binaries meaning that the machine code for several different processors is in one program file.)
Operating systems also have features that allow execution of new machine code within an existing process.  That machine code can be generated on the fly as with JTT compilers, or loaded more informally by an application program rather than the operating system loader.  Further, most operating system loaders support dynamically loading additional program file content from executable program files.
So, there's lots of ways to get machine code into the memory of a process for execution — support for machine code is one of the fundamental features of operating systems.
Let's also note that no real program is pure machine code — programs use machine code & data together, so all executable file formats store both machine code and data (and metadata).

How page directory is generated on Windows kernel on process creation

how page directory is generated on Windows kernel ?
GDT setups memory limits for user memory layout.
But i want to learn how windows internally setups process page directory & VAD tree
Windows does not use the GDT to isolate user mode from kernel mode on the x86, it uses per-page protection in the page tables. Check the Windows Internals book for details.

In Debian Linux can I build a single driver to become permanently part of my kernel image and part of my vmlinux file (for debugging)

I've got a custom kernel that I've built locally with gdb and kgdb enabled and installed. I have the vmlinux file for it that I use for source level kgdb. Each time I make a change I've been rebuilding the entire kernel. But I want to become more efficient than rebuilding whole kernels for every code change.
So I made a mod to my ata driver. Then I did a
make M=drivers/ata
It succeeded. Now how do I replace my previous ata driver with this ata driver and get this updated info into my vmlinux file for source debugging this new driver.
I'm not considering doing an insmod. I want to permanently modify my kernel image to replace the previous ata driver with this ata driver.
I think that is not possible to replace a driver in the Linux binary with a new version. You must use insmod, or recompile the entire kernel. I do not see any problem to recompile the whole kernel. If you already compiled it before, it takes few seconds

Develop Simple OS under Mac OS X, how to build the boot img from the Mach-O?

I am writing a simple OS under Mac OS X environment. I can build a simple bootloader by nasm. when i develop the more part by C language, i should build them together. The GCC of Mac OS X will compile a Mach-O output format. I want to know how to cat the instruction part of the output object, and link it together with the nasm part.
thanks.
There's a bigger problem which you aren't seeing.
GCC does not generate 16-bit x86 code, only 32-bit or 64-bit. x86 PC bootloaders start execution in the real addressing mode, which is a 16-bit mode for 16-bit code only.
So, even if you manage to link together the C code compiled with gcc and the assembly code compiled with NASM, you won't be able to execute the C code part (any 32-bit code part for that matter) until after you've switched into the 32-bit protected mode, which is not a very easy thing to do.
And you don't want to switch into protected mode in the 512-byte-long boot sector either. BIOS functions cannot be used in protected mode. If you switch too early, you won't be able to load any more stuff from the disk.
The most practical strategy is to split the bootloader into several parts. The 512-byte-long bootsector would load the next part(s) using the BIOS disk I/O functions. And those other parts will either contain the whole OS, or enough code that would load the rest of the OS either by using the same BIOS I/O functions or by using its own disk driver(s) in the real or protected mode.
So, you are doomed to writing 16-bit code in assembly language by hand for the bootsector, no C, no 32-bit.
You can, however, use other C compilers capable of producing 16-bit x86 code for the other parts of the bootloader. There are at least two of such compilers freely available online:
Turbo C++ 1.01 (runs only in DOS, Windows XP or below, VMs with DOS/Windows, e.g. DosBox)
Open Watcom C/C++ 1.9 (runs in DOS, Windows and probably Linux)

How BIOS boot from floppy and CD-ROM differently?

My test OS boots from floppy before, now I am trying to boot it from CD-ROM. But I am not quite sure how BIOS treat the floppy boot sector and CD boot sector differently. It seems the CD boot sector is much bigger than floppy boot sector. Is there any other things I need to notice?
Could anyone elabrate the details about it or point me to some links?
Thanks.
I would recommend booting with GRUB. Use the eltorito image to make the CD bootable. Then include your kernel in the CD image and make an entry in the GRUB configuration file use your kernel file like: kernel mykernel
Include any initrd if you have and boot.
To know about CD boot sectors i would tell you to have a look to the ISO Specifications
Wikipedia link
The ISO 9660 File System
ISO9660 Simplified for DOS/Windows
OSDev Link
I hope these links would help
To start, you should know that the bios does not use sector one of the CDrom to boot but sector 17 if I remember right.
You can learn alot by looking at the cdrom boot files which bootloaders such as grub or lilo use. Maby even minix has a cdboot option.