Skip to content
Advertisement

How do I implement basic I/O functionality as in x86 when writing an OS on ARM? [closed]

I’m trying to write a simple operating system from scratch as a way to improve understanding on how OS and computer works. I think some concepts like real mode and protection mode is complex and heavy on keeping compatibility. So I’d like to try writing this on ARM platform.

I found a great tutorial on write an ARM OS: Writing a simple OS kernel. I read through a large part of it and knew how to use serial port to output to QEMU terminal and change CPU mode. However, compared to normal sense on ‘Operating System’ and other material about writing OS on x86 platform, I found that there’s little text on how to implement these things on ARM.

How to output to real ‘screen’?

Writing a graphical interface is really hard work and related to many topics. But in x86 we have BIOS interrupt calls to output characters to screen. I use QEMU versatile to simulate an ARM device. Now the only thing I can do is output or input to or from serial port (UART) and interact with it by terminal of my own computer. Is there any way to do this?

How to accept input from devices?

A common ARM board has USB ports which can be connected to a keyboard. I know a keyboard event will raise an interruption. How do I accomplish this through USB in ARM platform?

How to make a filesystem?

Since almost no one uses real ‘harddisk’ on ARM devices, so I’d like to choose SD card (MMC) as storage item on the OS. I’ve written a simple filesystem simulator using file as disk. So I know the concepts in filesystem. But is there any difference between SD cards’ filesystem and normal disks’ filesystem?

How to boot?

I use QEMU, which just launches using a specific executable filename. It seems that it just ‘loads’ the entire executable into memory and start executing the instructions. But in real world booting is a complicated process. I searched the internet and know a bootloader named uBoot. But where I feel confused is that the bootloader also need to find a kernel image from files, so it should have ability to access filesystems?

How to make a program?

If I finished all things above. Now my OS can be used as a toy. But can I write code in it and compile them? I use a cross compiler in my computer. But there’s no compiler available to the new system. Even I have put more programs into it, how can I ‘load’ them into memory just as what unix call exec does?

These questions are really confusing to me now and I cannot find good answer or material on these topics. So is my current thinking direction wrong? Or writing one based on x86 is better if just for learning?

Thanks.

Advertisement

Answer

How to output to real ‘screen’?

Depends what kind of screen you have connected, if you have some kind of graphical card, then you need documentation for that card (for anything market competitive those are usually available from card manufacturer under signed NDA), and write your own driver according to it. To create fully fledged graphic driver supporting also some complex API like OpenGL and similar expect the effort of writing own driver to be in man- years.

If you have some simple LED display, or some chip capable to operate in similar fashion as VGA, then you can get away probably with few control registers settings, mapping device video memory in CPU memory address space, and then writing bits/ASCII into that mapped memory.

The x86 BIOS is legacy of old PC XT/AT graphic cards, when few standards did exist, like CGA -> EGA -> VGA, and manufacturers were obeying the standards quite reasonably to use universal drivers. Since the windows era it’s easier for manufacturers to provide their own closed source drivers and create their own HW in any way they wish (but keeping VGA-like basic functionality available for legacy/boot-up reasons = not a huge problem today with how transistors are cheap, so adding few thousands of them to emulate VGA is possible).

How to accept input from devices?

Again you need to write first USB driver, which will handle the USB bus on the ARM device side, and then the particular USB device needs it’s own driver, with common family of devices like keyboards being universal to a point where single driver can handle ~all of them.

How to make a filesystem?

Again there’s some card reader, you need docs for that reader and see how to operate it, it will have very likely some block-device-like API to access the card, from there it should be reasonably similar to any other block-device operation (if you are *NIX familiar with what I mean by “block device”, data blocks like sectors).

But is there any difference between SD cards’ filesystem and normal disks’ filesystem?

As OS creator you can decide yourself, how much you will divert from common schemes of things, but the cards usually have logical sectors (blocks) just like old HDD, so with good driver design hiding any details behind “blocks” API it will be the same thing for FS code. The major difference in flash disk drivers is, that they usually allow in cooperation with some file systems for additional extras, like trimming of free space to save on writes when deleting blocks.

How to boot?

In real world it depends on the board and it’s chipset, how it does initialize the ARM CPU, and whether some firmware is started and from where. Probably every board will have some kind of “BIOS” in some kind of ROM memory, which will do something to search for further user code (bootloader) at defined places (usually some disk-like devices or having net-boot feature).

How to make a program?

Even I have put more programs into it, how can I ‘load’ them into memory just as what unix call exec does?

Well, that’s responsibility of your OS, to provide all that process launch management, and providing defined API to the applications. Unless you want to write your own compiler, you can use some open source one like gcc/clang, but that means that you will have to implement most of the *NIX OS API services. Don’t worry, that’s not that hard, for example the GNU kernel “Hurd” has been in the work only for 27 years, and it’s shaping up nicely…


Seriously, as one-man show you can create just that, a “toy OS” (unless you want to spend decades on your project). If you want just to learn some new things about OS architecture and computers, it looks to me like you are in the point where studying sources of linux, and reading few books on the topic, may give you lot more in lot shorter time.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement