boot loader, irregular output on physical hardware [solved]

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
theosDev
Posts: 9
Joined: Fri Jan 04, 2019 6:05 am
Libera.chat IRC: theOSdev

boot loader, irregular output on physical hardware [solved]

Post by theosDev »

I am working my way through https://www.cs.bham.ac.uk/~exr/lectures ... os-dev.pdf by Nick Blundell and am having some trouble, I googled his name and followed the trail here where I decided to leave a post.

I am currently at the close of chapter 3 of the book and everything has been fine thus far, all of the code I have written works fine when run on an x86_64 emulator from QEMU-system-x86_64 but when I run it on physical hardware I get irregular output, sometimes it will print only some of a sequence of chars indicating it is skipping some lines, while sometimes a white cursor will dance around the screen for a moment then settle as the ascii sign of a male sex symbol ( a circle with an arrow up and to the right ) and the bottom center of my screen.

I've included a zip file which contains all the files of the current build, boots.asm is the boot file the other .asm files are functions, I've including the made .bin file from NASM for convenience, the 'foundry' is a makefile, chmod u+x so that you can run it. It is only the nasm compile command followed by the QEMU emulation command I am using.

as I said everything works absolutely fine in emulation but on physical hardware the results are unreliable. I am not sure if I am missing something or it is possible that my machine does some strange things when in 16 bit real mode.
any help would be appreciated
Attachments
theos.zip
(2.79 KiB) Downloaded 140 times
Last edited by theosDev on Mon Jan 07, 2019 3:15 am, edited 1 time in total.
quirck
Member
Member
Posts: 42
Joined: Sun Nov 23, 2008 5:56 am
Location: Russia, Saint-Petersburg

Re: boot loader will not run or runs irregularly on real har

Post by quirck »

You seem to be ignoring the segment registers altogether. DS is implicitly used when you store boot_device, for example, so you don't know what you overwrite there. Then, SS controls stack location. Finally, int 0x13 loads sectors at ES:BX, not just BX. On emulators these segment registers are likely to contain good values like zeroes, but on real hardware they will contain something left after BIOS startup code, so you need to set them manually.

Actually, the pdf you linked discusses it at the end of the third chapter, but the code it presents still does not set them, which is incorrect. You need to initialize them at the beginning:

Code: Select all

xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7C00 ; I wouldn't say that 0x8000 is "safely out of the way"
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: boot loader will not run or runs irregularly on real har

Post by Schol-R-LEA »

Welcome to the OS Dev forums, theosDev. I try to get this out to all new members, either in a thread or by PM, to get everyone started on the same footing. I hope this helps.

----------------------------------
The first thing I want to say is this: if you aren't already using version control for all software projects you are working on, drop everything and start to do that now. Set up a VCS such as Git, Subversion, Mercurial, Bazaar, or what have you - which you use is less important than the fact that you need to use it. Similarly, setting up your repos on an offsite host such as Gitlab, Github, Sourceforge, CloudForge, or BitBucket should be the very first thing you do whenever you start a new project, no matter how large or small it is.

If nothing else, it makes it easy to share your code with us on the forum, as you can just post a link, rather than pasting oodles and oodles of code into a post.

Once you have that out of the way (if you didn't already), you can start to consider the OS specific issues.

If you haven't already, I would strongly advise you to read the introductory material in the wiki:
After this, go through the material on the practical aspects of
running an OS-dev project: I strongly suggest that you read through these pages in detail, along with the appropriate ones to follow, before doing any actual development. These pages should ensure that you have at least the basic groundwork for learning about OS dev covered.

This brings you to your first big decision: which platform, or platforms, to target. Commonly options include:
  • x86 - the CPU architecture of the stock PC desktops and laptops, and the system which remains the 'default' for OS dev on this group. However, it is notoriously quirky, especially regarding Memory Segmentation, and the sharp divisions between 16-bit Real Mode, 16-bit and 32-bit Protected Modes, and 64-bit Long Mode.
  • ARM - a RISC architecture widely used on mobile devices and for 'Internet of Things' and 'Maker' equipment, including the popular Raspberry Pi and Beagleboard single board computers. While it is generally seen as easier to work with that x86, most notably in the much less severe differences in between the 32-bit and 64-bit modes and the lack of memory segmentation, the wiki and other resources don't cover it nearly as well (though this is changing over time as it becomes more commonly targeted).
  • MIPS, another RISC design which is slightly older than ARM. It is one of the first RISC design to come out, being part of the reason the idea caught on, and is even simpler than ARM in terms of programming, though a bit tedious when it comes to assembly programming. While it was widely used in workstations and game consoles in the 1990s, it has declined significantly due to mismanagement by the owners of the design, and is mostly seen in devices such as routers. There are a handful of System on Chip single-board computers that use it, such as the Creator Board and the Onion Omega2, and manufacturers in both China and Russia have licensed the ISA with the idea of breaking their dependence on Intel. Finding good information on the instruction set is easy, as it is widely used in courses on assembly language and computer architecture and there are several emulators that run MIPS code, but finding usable information on the actual hardware systems using it is often difficult at best.
  • RISC-V is an up and coming open source hardware ISA, but so far is Not Ready For Prime Time. This may change in the next few years, though.
You then need to decide which Language to use for the kernel. For most OS-Developers this means knowing and using C; while other languages can be used, it is important to know how to read C code, even if you don't use C, as most OS examples are written in it. You will also need to know at least some assembly language for the target platform, as there are always parts of the kernel and the device drivers which cannot be done in high-level languages.

You further need to choose the compiler, assembler, linker, build tool, and support utilities to use - what is called the 'toolchain' for your OS. For most platforms, there aren't many to choose from, and the obvious choice would be GCC and the Binutils toolchain due to their ubiquity. However, on the Intel x86 platform, it isn't as simple, as there are several other toolchains which are in widespread use for it, the most notable being the Microsoft one - a very familiar one to Windows programmers, but one which presents problems in OSDev. The biggest issue with Visual Studio, and with proprietary toolchains in general, is that using it rules out the possibility of your OS being "self-hosting" - that is to say, being able to develop your OS in the OS itself, something most OSdevs do want to eventually be able to do. The fact that Porting GCC to your OS is feasible, whereas porting proprietary x86 toolchains isn't, is a big factor in the use Binutils and GCC, as it their deep connection to Linux and other Unix derivatives.

Regardless of the high-level language you use for OS dev (if any), you will still need to use assembly language, which means choosing an assembler. If you are using Binutils and GCC, the obvious choice would be GAS, but for x86 especially, there are other assemblers which many OSdevs prefer, such as Netwide Assembler (NASM) and Flat Assembler (FASM).

The important thing here is that assembly language syntax varies more among the x86 assemblers than it does for most other platforms, with the biggest difference being that between the Intel syntax used in the majority of x86 assemblers, and the AT&T syntax used in GAS. You can see an overview of the differences on the somewhat misnamed wiki page Opcode syntax. While it is possible to coax GAS to use the Intel syntax using the .intel_syntax noprefix directive, the opposite is generally not true for Intel-based assemblers such as NASM, and even with that directive, GAS is still quite different from other x86 assemblers in other regards.

It is still important to understand that the various Intel syntax assemblers - NASM, FASM, and YASM among others - have differences in how they handle indexing, in the directives they use, and in their support for features such as macros and defining data structures. While most of these follow the general syntax of Microsoft Assembler (MASM), they all diverge from it in various ways.

Once you know which platform you are targeting, and the toolchain you want to use, you need to understand them. You should read up on the core technologies for the platform. Assuming that you are targeting the PC architecture, this would include: This leads to the next big decision: which Bootloader to use. There are a number of different standard bootloaders for x86, with the most prominent being GRUB. We strong recommend against Rolling Your Own Bootloader, but it is an option as well.

You need to consider what kind of File System to use. Common ones used when starting out in OS dev include: We generally don't recommend designing your own, but as with boot loaders, it is a possibility as well.

While this is a lot of reading, it simply reflects the due diligence that any OS-devver needs to go through in order to get anywhere. OS development, even as a simple project, is not amenable to the Stack Overflow cut-and-paste model of software development; you really need to understand a fair amount of the concepts and principles before writing any code, and the examples given in tutorials and forum posts generally are exactly that. Copying an existing code snippet without at least a basic idea of what it is doing simply won't do. While learning itself is an iterative process - you learn one thing, try it out, see what worked and what didn't, read some more, etc. - in this case a basic foundation is needed at the start. Without a solid understanding of at least some of the core ideas before starting, you simply can't get very far in OS dev.

Hopefully, this won't scare you off; it isn't nearly as bad as it sounds. It just takes a lot of patience and a bit of effort, a little at a time.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
theosDev
Posts: 9
Joined: Fri Jan 04, 2019 6:05 am
Libera.chat IRC: theOSdev

Re: boot loader will not run or runs irregularly on real har

Post by theosDev »

quirck wrote:You seem to be ignoring the segment registers altogether. DS is implicitly used when you store boot_device, for example, so you don't know what you overwrite there. Then, SS controls stack location. Finally, int 0x13 loads sectors at ES:BX, not just BX. On emulators these segment registers are likely to contain good values like zeroes, but on real hardware they will contain something left after BIOS startup code, so you need to set them manually.

Actually, the pdf you linked discusses it at the end of the third chapter, but the code it presents still does not set them, which is incorrect. You need to initialize them at the beginning:

Code: Select all

xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7C00 ; I wouldn't say that 0x8000 is "safely out of the way"

I appended the code you provided before my main runtime area and it solved my issues much thanks for that. I have also added in a BPB sector for the USB emulated floppy that I was able to find elsewhere. Some people found that adding that would fix the issue I had but I did not experience this effect. I did elect to omit your final line 'mov sp, 0x7c00' because I already set my stack base and top in a previous line to be 8000h. you mention that this is not "safely out of the way" and elect to use 0x7c00 which I understand to be the loadsite for the boot loader code. I would appreciate you explaining this last line for me.

much thanks for your help
here is a link to the GitHub repo https://github.com/sowens26/theOS
theosDev
Posts: 9
Joined: Fri Jan 04, 2019 6:05 am
Libera.chat IRC: theOSdev

Re: boot loader will not run or runs irregularly on real har

Post by theosDev »

Schol-R-LEA wrote:Welcome to the OS Dev forums, theosDev. I try to get this out to all new members, either in a thread or by PM, to get everyone started on the same footing. I hope this helps.

----------------------------------
The first thing I want to say is this: if you aren't already using version control for all software projects you are working on, drop everything and start to do that now. Set up a VCS such as Git, Subversion, Mercurial, Bazaar, or what have you - which you use is less important than the fact that you need to use it. Similarly, setting up your repos on an offsite host such as Gitlab, Github, Sourceforge, CloudForge, or BitBucket should be the very first thing you do whenever you start a new project, no matter how large or small it is.

If nothing else, it makes it easy to share your code with us on the forum, as you can just post a link, rather than pasting oodles and oodles of code into a post.

Once you have that out of the way (if you didn't already), you can start to consider the OS specific issues.

If you haven't already, I would strongly advise you to read the introductory material in the wiki:
After this, go through the material on the practical aspects of
running an OS-dev project: I strongly suggest that you read through these pages in detail, along with the appropriate ones to follow, before doing any actual development. These pages should ensure that you have at least the basic groundwork for learning about OS dev covered.

This brings you to your first big decision: which platform, or platforms, to target. Commonly options include:
  • x86 - the CPU architecture of the stock PC desktops and laptops, and the system which remains the 'default' for OS dev on this group. However, it is notoriously quirky, especially regarding Memory Segmentation, and the sharp divisions between 16-bit Real Mode, 16-bit and 32-bit Protected Modes, and 64-bit Long Mode.
  • ARM - a RISC architecture widely used on mobile devices and for 'Internet of Things' and 'Maker' equipment, including the popular Raspberry Pi and Beagleboard single board computers. While it is generally seen as easier to work with that x86, most notably in the much less severe differences in between the 32-bit and 64-bit modes and the lack of memory segmentation, the wiki and other resources don't cover it nearly as well (though this is changing over time as it becomes more commonly targeted).
  • MIPS, another RISC design which is slightly older than ARM. It is one of the first RISC design to come out, being part of the reason the idea caught on, and is even simpler than ARM in terms of programming, though a bit tedious when it comes to assembly programming. While it was widely used in workstations and game consoles in the 1990s, it has declined significantly due to mismanagement by the owners of the design, and is mostly seen in devices such as routers. There are a handful of System on Chip single-board computers that use it, such as the Creator Board and the Onion Omega2, and manufacturers in both China and Russia have licensed the ISA with the idea of breaking their dependence on Intel. Finding good information on the instruction set is easy, as it is widely used in courses on assembly language and computer architecture and there are several emulators that run MIPS code, but finding usable information on the actual hardware systems using it is often difficult at best.
  • RISC-V is an up and coming open source hardware ISA, but so far is Not Ready For Prime Time. This may change in the next few years, though.
You then need to decide which Language to use for the kernel. For most OS-Developers this means knowing and using C; while other languages can be used, it is important to know how to read C code, even if you don't use C, as most OS examples are written in it. You will also need to know at least some assembly language for the target platform, as there are always parts of the kernel and the device drivers which cannot be done in high-level languages.

You further need to choose the compiler, assembler, linker, build tool, and support utilities to use - what is called the 'toolchain' for your OS. For most platforms, there aren't many to choose from, and the obvious choice would be GCC and the Binutils toolchain due to their ubiquity. However, on the Intel x86 platform, it isn't as simple, as there are several other toolchains which are in widespread use for it, the most notable being the Microsoft one - a very familiar one to Windows programmers, but one which presents problems in OSDev. The biggest issue with Visual Studio, and with proprietary toolchains in general, is that using it rules out the possibility of your OS being "self-hosting" - that is to say, being able to develop your OS in the OS itself, something most OSdevs do want to eventually be able to do. The fact that Porting GCC to your OS is feasible, whereas porting proprietary x86 toolchains isn't, is a big factor in the use Binutils and GCC, as it their deep connection to Linux and other Unix derivatives.

Regardless of the high-level language you use for OS dev (if any), you will still need to use assembly language, which means choosing an assembler. If you are using Binutils and GCC, the obvious choice would be GAS, but for x86 especially, there are other assemblers which many OSdevs prefer, such as Netwide Assembler (NASM) and Flat Assembler (FASM).

The important thing here is that assembly language syntax varies more among the x86 assemblers than it does for most other platforms, with the biggest difference being that between the Intel syntax used in the majority of x86 assemblers, and the AT&T syntax used in GAS. You can see an overview of the differences on the somewhat misnamed wiki page Opcode syntax. While it is possible to coax GAS to use the Intel syntax using the .intel_syntax noprefix directive, the opposite is generally not true for Intel-based assemblers such as NASM, and even with that directive, GAS is still quite different from other x86 assemblers in other regards.

It is still important to understand that the various Intel syntax assemblers - NASM, FASM, and YASM among others - have differences in how they handle indexing, in the directives they use, and in their support for features such as macros and defining data structures. While most of these follow the general syntax of Microsoft Assembler (MASM), they all diverge from it in various ways.

Once you know which platform you are targeting, and the toolchain you want to use, you need to understand them. You should read up on the core technologies for the platform. Assuming that you are targeting the PC architecture, this would include: This leads to the next big decision: which Bootloader to use. There are a number of different standard bootloaders for x86, with the most prominent being GRUB. We strong recommend against Rolling Your Own Bootloader, but it is an option as well.

You need to consider what kind of File System to use. Common ones used when starting out in OS dev include: We generally don't recommend designing your own, but as with boot loaders, it is a possibility as well.

While this is a lot of reading, it simply reflects the due diligence that any OS-devver needs to go through in order to get anywhere. OS development, even as a simple project, is not amenable to the Stack Overflow cut-and-paste model of software development; you really need to understand a fair amount of the concepts and principles before writing any code, and the examples given in tutorials and forum posts generally are exactly that. Copying an existing code snippet without at least a basic idea of what it is doing simply won't do. While learning itself is an iterative process - you learn one thing, try it out, see what worked and what didn't, read some more, etc. - in this case a basic foundation is needed at the start. Without a solid understanding of at least some of the core ideas before starting, you simply can't get very far in OS dev.

Hopefully, this won't scare you off; it isn't nearly as bad as it sounds. It just takes a lot of patience and a bit of effort, a little at a time.

much thanks for the reading material. I am a computer science major from a public university in the US so while I do technically have an education it was not what I feel to be adequate. I am undergoing this as attempt to learn and fully understand how difficult it is and that I don't yet know enough. but that is why I'm doing it, to know enough afterwards. I appreciate the reading material as it has been difficult to find. As another commenter mentioned the pdf I am currently working through has a number of errors that may not be technically wrong but are not fully considerate and fail in some circumstances like running on real hardware. \\
quirck
Member
Member
Posts: 42
Joined: Sun Nov 23, 2008 5:56 am
Location: Russia, Saint-Petersburg

Re: boot loader will not run or runs irregularly on real har

Post by quirck »

theosDev wrote:I did elect to omit your final line 'mov sp, 0x7c00' because I already set my stack base and top in a previous line to be 8000h. you mention that this is not "safely out of the way" and elect to use 0x7c00 which I understand to be the loadsite for the boot loader code. I would appreciate you explaining this last line for me.
As the stack grows toward smaller addresses, if SP = 0x8000, then after 512 bytes it will start to overwrite your bootsector that was loaded to 0x7C00-0x7DFF. With SP = 0x7C00, stack will consume memory right before the bootsector, and they won't overlap. While 512 bytes might seem like a lot for your code, BIOS INT 0x13 might happen to be quite complicated and actually use more than that, one can't be sure, as BIOS makes no guarantees about stack usage.

Another note: it is strongly advised to set SP right after you set SS.
The stack is determined by the pair SS:SP. After you modify SS, the SP still contains the old value, and the resulting stack pointer SS:SP points who knows where. If, say, a timer interrupt occurs just in the "right" time, it will use half-configured stack and overwrite random memory. The workaround is to set SP immediately following MOV SS, as the MOV SS instruction blocks all interrupts until the end of the next instruction, which is sufficient to complete stack setup. So, I'd say that the correct code would be

Code: Select all

mov ss, ax
mov sp, 0x8000
mov bp, sp
theosDev
Posts: 9
Joined: Fri Jan 04, 2019 6:05 am
Libera.chat IRC: theOSdev

Re: boot loader will not run or runs irregularly on real har

Post by theosDev »

quirck wrote:
theosDev wrote:I did elect to omit your final line 'mov sp, 0x7c00' because I already set my stack base and top in a previous line to be 8000h. you mention that this is not "safely out of the way" and elect to use 0x7c00 which I understand to be the loadsite for the boot loader code. I would appreciate you explaining this last line for me.
As the stack grows toward smaller addresses, if SP = 0x8000, then after 512 bytes it will start to overwrite your bootsector that was loaded to 0x7C00-0x7DFF. With SP = 0x7C00, stack will consume memory right before the bootsector, and they won't overlap. While 512 bytes might seem like a lot for your code, BIOS INT 0x13 might happen to be quite complicated and actually use more than that, one can't be sure, as BIOS makes no guarantees about stack usage.

Another note: it is strongly advised to set SP right after you set SS.
The stack is determined by the pair SS:SP. After you modify SS, the SP still contains the old value, and the resulting stack pointer SS:SP points who knows where. If, say, a timer interrupt occurs just in the "right" time, it will use half-configured stack and overwrite random memory. The workaround is to set SP immediately following MOV SS, as the MOV SS instruction blocks all interrupts until the end of the next instruction, which is sufficient to complete stack setup. So, I'd say that the correct code would be

Code: Select all

mov ss, ax
mov sp, 0x8000
mov bp, sp
I've looked over what you said as well as figure 3.4 in the pdf on page 14 where it shows a layout of the memory layout before boot. My understanding of the information is as follows, please feel free to correct me if I am wrong:

there is free space between the end of BIOS DATA AREA at 0x500 and the beginning of LOADED BOOT SECTOR at 0x7c00
that space is equivalent to 500h - 7c00h bytes = 30464 bytes in decimal.

there is another free space between the end of BOOT SECTOR at 0x7e00 and beginning of EXTENDED BIOS DATA AREA at 0x9fc00
that space is equivalent to 9fc00h - 7e00f bytes = 622080 bytes in decimal .

the space I initially was using beginning at 0x8000 would have only allowed me the space between 0x8000 and 0x7e00
which would be equivalent to 8000h - 7e00h bytes = 512 bytes in decimal.

because of this decision to begin my stack at 0x8000 after the stack reached a size of 512 bytes I would overwrite my boot sector.
because of this 0x8000 is a bad location to begin the stack.
0x7c00 would be better because it would not overwrite any of my boot sector because it would never extend upward into it.

my question is this, would it be better for me to start my stack at 0x9fc00 and to allow myself 622080 bytes or should I begin before the boot sector and prevent overwrites by being below the boot sector, but have only 30464 bytes for my stack? would it be better to have the stack stored below the boot sector to prevent overwrites so that I can then place any data I need to write after the boot sector?

again thank you for your help.
quirck
Member
Member
Posts: 42
Joined: Sun Nov 23, 2008 5:56 am
Location: Russia, Saint-Petersburg

Re: boot loader will not run or runs irregularly on real har

Post by quirck »

Your understanding of the memory map is correct.

In real mode a given segment register allows to access only 64K of contiguous memory. A far pointer of the form A:B gives the physical address 16*A+B. Thus, if you fix A, you get only 64K addresses. The stack can't get more than that. So, if you want to be sure that stack will not overlap with anything, choose any 64K range 16-byte aligned, set SS to its address divided by 16, and SP to zero. But often this is an overkill.

There can be no single way to set up the stack. It's entirely your choice where to put it. It's just that when you've decided, draw the stack on your map and don't use that space for anything else.
User avatar
JAAman
Member
Member
Posts: 879
Joined: Wed Oct 27, 2004 11:00 pm
Location: WA

Re: boot loader will not run or runs irregularly on real har

Post by JAAman »

couple of important comments...
theosDev wrote: there is free space between the end of BIOS DATA AREA at 0x500 and the beginning of LOADED BOOT SECTOR at 0x7c00
that space is equivalent to 500h - 7c00h bytes = 30464 bytes in decimal.
that is correct, and, since this is the only area that is certain to contain usable RAM, many people like to put the stack here
there is another free space between the end of BOOT SECTOR at 0x7e00 and beginning of EXTENDED BIOS DATA AREA at 0x9fc00
that space is equivalent to 9fc00h - 7e00f bytes = 622080 bytes in decimal .
this is only partially true

the starting address (0x7E00) should actually be defined as the end of your boot sector -- for some rare disks the bootsector can be sizes other than 512bytes, both larger and smaller are possible

the ending address (0x9_FC00) is actually defined to be the start of the EBDA, the number you are assuming is only true for bochs, on other emulators, real hardware, or even bochs if configured differently, this address can be different (again, both higher and lower numbers are possible)
my question is this, would it be better for me to start my stack at 0x9fc00 and to allow myself 622080 bytes or should I begin before the boot sector and prevent overwrites by being below the boot sector, but have only 30464 bytes for my stack? would it be better to have the stack stored below the boot sector to prevent overwrites so that I can then place any data I need to write after the boot sector?

again thank you for your help.
as I stated above, the address 0x9_FC00 is only true for bochs (it might coincidentally be true for any random machine, but it is not guaranteed) -- you should always check what the actual address is before using any memory above the bootsector




having said that, I would not expect this code to work on most real machines at all -- modern computers (that is, all computers newer than 2006) use a completely different method of booting (UEFI), and while most computers between 2006 and 2012 actually support both methods, most computers newer than 2012 no longer support the older method
theosDev
Posts: 9
Joined: Fri Jan 04, 2019 6:05 am
Libera.chat IRC: theOSdev

Re: boot loader will not run or runs irregularly on real har

Post by theosDev »

quirck wrote:You seem to be ignoring the segment registers altogether. DS is implicitly used when you store boot_device, for example, so you don't know what you overwrite there. Then, SS controls stack location. Finally, int 0x13 loads sectors at ES:BX, not just BX. On emulators these segment registers are likely to contain good values like zeroes, but on real hardware they will contain something left after BIOS startup code, so you need to set them manually.

Actually, the pdf you linked discusses it at the end of the third chapter, but the code it presents still does not set them, which is incorrect. You need to initialize them at the beginning:

Code: Select all

xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7C00 ; I wouldn't say that 0x8000 is "safely out of the way"
The original problem in this posting has been solved and the GitHub page has been updated with the new code. I am now at the point where I have the boot loader and some c code that's been compiled down to binary and appended as the pdf shows in chapter 5. Just like the last time everything works perfectly in the virtual machine but when running on physical hardware the outcome is different.

the number of sectors to load can be changed by altering the incoming figure on line 33 of boots.asm "mov dh, 1"

1: when booting in QEMU from the usb drive everything works fine up to trying to read about 20 sectors

2: when booting from the usb on physical hardware, if I set it to only try to load a single sector I get the error I put in "unable to load expected amount of sectors ", if I set it to search for more than one (say 10 for example) I get the same error

3: when booting in QEMU from the local file os-image, if I set it to only try to load a single sector everything works as expected, any other number will cause the "disk read error" error to throw.

I expect situation 3 to behave the way it is because that os-image file contains no information about drive sectors it is only the two sectors necessary to hold the boot loader and the c code.
Given that everything is perfect in the simulator just like in the original problem I believe it may be another issue of registers holding garbage values, possibly from switching between 16 and 32 bit modes?

It is my understanding that the -Ttext 0x1000 option on the ld command in the makefile should specify that the additional c code should be written to 0x1000, there is then a label KERNEL_OFFSET that holds this same value and is passed into bx before loadDisk is called but it is never used in loadDisk unless there is an error in which case it is overwritten for the printing function.

TLDR; my boot loader is not able to load in the correct number of sectors on physical hardware, works on QEMU.

if anyone knows what I am missing and could help me out I would appreciate it.

https://github.com/sowens26/theOS
MichaelPetch
Member
Member
Posts: 772
Joined: Fri Aug 26, 2016 1:41 pm
Libera.chat IRC: mpetch

Re: boot loader, irregular output on physical hardware [solv

Post by MichaelPetch »

When booting from USB, is your BIOS set to boot as Floppy Drive Emulation (FDD)? If so,it could be that the BIOS has overwritten part of the code before transferring control to your bootloader. This can happen because some BIOSes blindly assume that there is a BIOS Parameter Block in your bootloader and it updates the drive geometry information for the USB media you are using. I have written more about that here: https://stackoverflow.com/a/47320115/3857942 . What happens if you add a BPB to your bootloader?
theosDev
Posts: 9
Joined: Fri Jan 04, 2019 6:05 am
Libera.chat IRC: theOSdev

Re: boot loader, irregular output on physical hardware [solv

Post by theosDev »

MichaelPetch wrote:When booting from USB, is your BIOS set to boot as Floppy Drive Emulation (FDD)? If so,it could be that the BIOS has overwritten part of the code before transferring control to your bootloader. This can happen because some BIOSes blindly assume that there is a BIOS Parameter Block in your bootloader and it updates the drive geometry information for the USB media you are using. I have written more about that here: https://stackoverflow.com/a/47320115/3857942 . What happens if you add a BPB to your bootloader?
This solutions worked perfectly. much thanks my friend
Post Reply