OS development 101 - How to make a bootloader part 1 - Hello World

แชร์
ฝัง

ความคิดเห็น • 135

  • @screeck
    @screeck  3 หลายเดือนก่อน +13

    Part 2:
    th-cam.com/video/BQGbBCqUGCc/w-d-xo.html

  • @thermiusthermius
    @thermiusthermius 10 วันที่ผ่านมา

    Hi, I'm from Brazil and I was amazed by your content. I study operating systems, assembly, C/C++ and your video helped me understand how the boot process occurs.

  • @Hideko12
    @Hideko12 3 หลายเดือนก่อน +24

    Hi 👋 just wanted to let you know that your content is very special. Tech Content Creators focus a lot on Hacking and Defense but Malware Analysis and Reverse Engineering need a little bit of attention so thanks !

  • @Lulxec
    @Lulxec 3 หลายเดือนก่อน +5

    your content is awesome , been wanting to learn assembly for a while and you've just gave me the motive to do so

    • @maxmuster7003
      @maxmuster7003 3 หลายเดือนก่อน +2

      x86 assembly is easy to learn. I began on C64 with 8 bit CPU only 3 register, no FPU, no mul and no div instructlons, but most routines need 16 bit calculation. x86 is much easier to use. Documentation: Intel developer manual for 16 bit and from AMD in pdf files.

    • @Lulxec
      @Lulxec 3 หลายเดือนก่อน +1

      @@maxmuster7003 thank you , friend , i started learning it that day and yes it's easy for making simple stuff(also super fun), but I wonder if making complex stuff with it will require a in-depth knowledge of the x86 architecture

  • @Bestfriend-q1s
    @Bestfriend-q1s 3 หลายเดือนก่อน +7

    The POST is performed by the BIOS/UEFI. Good job. Keep going.

  • @sonne83494
    @sonne83494 3 หลายเดือนก่อน +128

    please increase font size next time

    • @maxmuster7003
      @maxmuster7003 3 หลายเดือนก่อน +8

      I need a microscope on Android tablet.😂

    • @patates1165
      @patates1165 3 หลายเดือนก่อน +3

      font size is fine

    • @CarlosMartinezTech
      @CarlosMartinezTech 3 หลายเดือนก่อน

      @MurderByProxy no campestre mejor

    • @CristiNeagu
      @CristiNeagu 2 หลายเดือนก่อน +4

      Please watch this on a normal screen.

    • @twenty-fifth420
      @twenty-fifth420 2 หลายเดือนก่อน +1

      >Homemade solution:
      >Fullscreen
      >Pinch and zoom
      There, now let the man teach you 😂

  • @NoMore12345-z
    @NoMore12345-z หลายเดือนก่อน +1

    This is very cool. I recognized some of the opcodes from my experimenting on and off a few years ago. Great work. Subbed.

  • @maxmuster7003
    @maxmuster7003 3 หลายเดือนก่อน +5

    I like to switch from the 16 bit Real Address Mode with 64 kb segment size for all segment register, into the 16 bit "Big" Real Mode with a segment size of 64 kb for CS and SS segment, but for DS, ES, FS and GS segment size of 4 gb with A20 address line on. This Mode is compatible to the 16 bit BIOS function of the mainboard and graphic BIOS and additional alows to write/draw into the linear framebuffer (located in the 4th gb) of VBE 2 or VBE 3 videomodes for high resolutions. Example 1920x1200x32 with 16: 10 aspect ratio for 28" LCD monitor using Radion 9750 PCIe with intel Core2quad CPU 2700mhz.

  • @kevinmccallister7647
    @kevinmccallister7647 3 หลายเดือนก่อน +14

    I love this! can we have a full series where you build a simple OS?

    • @screeck
      @screeck  3 หลายเดือนก่อน +12

      Thanks! I don't think I'll do something like this very soon. This videos are sort of a by-product of me learning something. And its gonna be quite a long time until I learn how to make a simple OS.

    • @LuaanTi
      @LuaanTi 2 หลายเดือนก่อน

      What would count as "simple OS"? :)

    • @DanielMiulet-jo9ko
      @DanielMiulet-jo9ko 2 หลายเดือนก่อน +2

      @@LuaanTilinux from scratch would be a “simple os”. If you really want it… from scratch, you can write your own programs and your own kernel

    • @LuaanTi
      @LuaanTi 2 หลายเดือนก่อน +2

      @@DanielMiulet-jo9ko Well, the first public version of Linux was less than 10k lines of code; of course, that didn't include even a file system :) And quite a few of those lines were just the definitions and boilerplate.
      One of the tricky things with following Linux development is that whole GNU (and friends) thing. The kernel is just the kernel, after all.
      DOS allowed you to run programs and navigate files; back in the day, that was enough to count as a simple OS (heck, microcomputer Basic was really an OS :D ). But I expect people aren't going to be satisfied with anything that doesn't have at least memory protection, asynchronous I/O and pre-emptive multi-tasking nowadays :D

    • @jaiyadav5934
      @jaiyadav5934 2 หลายเดือนก่อน

      @@screeck I am also trying to learn how to make a simple OS , would love to get some tips and resources from you

  • @jannikwinkler3544
    @jannikwinkler3544 หลายเดือนก่อน +1

    Thank you soo much i am searching for this for years❤❤

  • @小张同学-v6i
    @小张同学-v6i 2 หลายเดือนก่อน +3

    you can also code in C and let the compiler create the assembly for you.

  • @insanelydigitalvids
    @insanelydigitalvids 2 หลายเดือนก่อน +1

    A very good video. Great content and easy to understand. Thank you!

  • @jordanarnould9056
    @jordanarnould9056 หลายเดือนก่อน +2

    3:04 "This is the compiler for our assembly" that's called an assembler

  • @JMichaelBreitenbach
    @JMichaelBreitenbach 28 วันที่ผ่านมา +1

    The content is good but unless you want to make everyone pinch and zoom or expect us to have 80" tvs you might consider upping the font size in the terminal and vscode.
    When you opened vscode I thought "dang I can almost read that compared to the terminal commands"....then you promptly shrunk the font like 2-3 sizes
    All this monitor and you're using like the left 10% :)

  • @thienmr7930
    @thienmr7930 2 หลายเดือนก่อน +3

    Finally found you! Thanks a lot! !

  • @maxmuster7003
    @maxmuster7003 3 หลายเดือนก่อน +1

    I made some open source projects for DosBox using batch files and x86 assembly. Have fun.😊

  • @tech-german1806
    @tech-german1806 3 หลายเดือนก่อน +4

    nice, waiting for next episode. Please post video for ARM64 also

  • @maxmuster7003
    @maxmuster7003 3 หลายเดือนก่อน +2

    We can write our string directly into the screen memory without using a bios function.
    vga text screen default 80x25 with 16 colors and 8x16 character size and 8 text pages
    mov ax, 0b800h
    mov es, ax
    mov di, Location
    cld
    mov si, OFFSET string ; ds:si
    mov ah, color
    mov cl, len
    L1:
    lodsb
    stosw
    dec cl
    jnz L1
    ....
    string DB "Hello World"
    len = ($ - string)
    Location = (Y * 160) + (X * 2)

  • @LunaticEdit
    @LunaticEdit 2 หลายเดือนก่อน +2

    To be clear, this is more for how retro computers used to boot up (legacy BIOS boot). These days you use EUFI and boot from an .efi file (typically with digital signature requirements). I mean it's great to learn how things used to work, but if you're looking for a modern method this is not it.

    • @eldorado3523
      @eldorado3523 หลายเดือนก่อน +3

      still applicable to myriad situations in embedded systems and microcontrollers

  • @the-real-random-person
    @the-real-random-person 3 หลายเดือนก่อน +1

    Can't wait for the next episode!

  • @Eevee8858
    @Eevee8858 3 หลายเดือนก่อน +13

    Damn bro this is gold hidden beneath shit i am glad i could discover this

    • @CallousCoder
      @CallousCoder หลายเดือนก่อน

      There's nothing new here :D It's been explained letter for letter in documents and on dozens of youtube videos

  • @devkumar9889
    @devkumar9889 2 หลายเดือนก่อน

    Theory :
    Power Supply gives power to all devices and does POST test
    Then Bios is loaded into Memory from disk
    Bios then finds Bootloader to execute it,
    It sees Boot sequence in Bios setting to find Boot device
    Then inside Boot device first 512 bytes are reserved for Bootloader called Master Boot record or Boot sector
    Then it loads Bootloader into memory and executes it

  • @southernflatland
    @southernflatland 2 หลายเดือนก่อน +6

    Bruh, mov ax, 0x00?
    xor ax, ax
    Faster to manipulate CPU registers than load from RAM. And yes, that instruction clears the ax register.

    • @screeck
      @screeck  2 หลายเดือนก่อน +4

      Thanks, will use that next time

    • @Slowly_Going_Mad
      @Slowly_Going_Mad 2 หลายเดือนก่อน +1

      Not only is It faster it's also a smaller instruction for x86 if I'm not mistaken. Don't quote me on that though because it's been a long minute since I've done some assembly prog.

    • @peekachugaming3231
      @peekachugaming3231 2 หลายเดือนก่อน +2

      xor ax, ax would do the same as mov ax, 0, but with additional capability of setting the flag to zero and clearing carry according to the logic of xor. And xor consumes less clocks than mov does in some old architectures.

  • @explore5845
    @explore5845 หลายเดือนก่อน

    Great! Out of curiosity, what sources did you use to learn these concepts?

  • @imperia777
    @imperia777 2 หลายเดือนก่อน

    insta like for the posters, going to watch the video now :)

    • @screeck
      @screeck  2 หลายเดือนก่อน

      Thanks haha

  • @unglaubichuberlieber8048
    @unglaubichuberlieber8048 3 หลายเดือนก่อน +3

    einfach gut gemacht !!!

  • @ferroalloys594
    @ferroalloys594 26 วันที่ผ่านมา

    On a PDP8 there was no need to do so, just flip the switches correctly and press the load button each time, and viola, the absolute loader (paper) tape was invoked! Blimey, those were the days, Lanchester Polytechnic, circa. 1978... So Simples... (:-)

  • @OneAndOnlyMe
    @OneAndOnlyMe หลายเดือนก่อน

    This is very cool.

  • @hildanku
    @hildanku 2 หลายเดือนก่อน

    amazing, I'm very interested in ur content

  • @maxmuster7003
    @maxmuster7003 3 หลายเดือนก่อน

    cli and sti are needed if we want to change an interrupt vector address offset/segment in memory like the timer interrupt 8 at the address 0:0020 = 4 bytes. If we don’t stop the timer interrupt and we try to override the old vector the interrupt can occur between changing the offset and changing the segment address and accidently jumping to a wrong address with no valid interrupt service routine(ISR). We have to prevent this.

  • @Nabaz-coding
    @Nabaz-coding 2 หลายเดือนก่อน

    awesome, keep going 🎉

  • @lezbriddon
    @lezbriddon หลายเดือนก่อน

    So much easier to understand than python...

  • @comosaycomosah
    @comosaycomosah 2 หลายเดือนก่อน

    this was really cool

  • @Dandelionq
    @Dandelionq 3 หลายเดือนก่อน

    I like your accent cos i can understand everything ❤

  • @omdevs
    @omdevs 3 หลายเดือนก่อน

    Great video! Thanks

  • @loiphin
    @loiphin หลายเดือนก่อน

    Hmm... looks like babysteps to me ;)

  • @lesnavevericka7093
    @lesnavevericka7093 2 หลายเดือนก่อน +1

    thank you, so 510-0 times is 510 and two addresses are 2*8bits? is 512 as MBR? ;) I'm just beginner in ASM. You're my first teacher :)

  • @alexsurguy
    @alexsurguy 2 หลายเดือนก่อน +1

    Would be nice to be able to figure out how to flash a bootloader to xbox series to boot on brand new SSD

  • @prezlamen
    @prezlamen 20 วันที่ผ่านมา

    Only if I have microscope to see your videos.Use big fonts for TH-cam, just look how Laith Harb did or Explaning Computers.

  • @edwardmacnab354
    @edwardmacnab354 28 วันที่ผ่านมา

    it all starts with the cpu . When the cpu receives power it has the address of the bios and begins executing bios code

  • @Rsparing
    @Rsparing 3 หลายเดือนก่อน +1

    please don't stop 3 video's in

  • @sorasuzuki671
    @sorasuzuki671 2 หลายเดือนก่อน

    Well, this video is in a format "this video is for beginner"
    The amount of knowledge required to event understand the video is massive.

  • @chiangyen-v8l
    @chiangyen-v8l 3 หลายเดือนก่อน

    wow MASM havnt see that for 30 years

    • @pvc988
      @pvc988 2 หลายเดือนก่อน +1

      It's NASM.

  • @pranaypallavtripathi2460
    @pranaypallavtripathi2460 3 หลายเดือนก่อน +1

    could you make the font size in your terminal/code editor a bit bigger because it is very difficult to see especially on mobile

    • @screeck
      @screeck  3 หลายเดือนก่อน +3

      Thanks for feedback, I'll make it bigger in the next video.

  • @solotron7390
    @solotron7390 3 หลายเดือนก่อน

    It worked well.

  • @JNET_Reloaded
    @JNET_Reloaded 2 หลายเดือนก่อน

    can you re do the serease again but on arm processor like rpi 5 :P

  • @VioletGiraffe
    @VioletGiraffe 2 หลายเดือนก่อน +1

    Why MBR mode and not UEFI?

  • @ValidatingUsername
    @ValidatingUsername 3 หลายเดือนก่อน

    You could technically write a bootloader in JavaScript like a personal version of virtual box?

  • @Chathumina-wl9dq
    @Chathumina-wl9dq 10 วันที่ผ่านมา

    hey, can you please increase the coding font size

  • @we-are-electric1445
    @we-are-electric1445 3 หลายเดือนก่อน

    Very good video but one question - if the program overwrites what is in the bootloader then how does the system boot after the program has finished executing ?

    • @LuaanTi
      @LuaanTi 2 หลายเดือนก่อน

      The program would overwrite what's in RAM, not what's on the hard drive. When you reboot, the whole thing gets loaded from hard drive again.
      However, there's no modification of the program in RAM here either. The program and the bootloader are the same - or rather, the sample program here is just made to run when the computer starts (and tries to boot from the drive). It doesn't actually do any "bootloading", it just prints a message and stops the CPU (without any way of waking it up again, so your only option is a reboot).
      The demonstration is just an almost-minimal setup on running code when booting from a hard drive. That's it. It just prints a message to make it obvious that it actually works. The whole mechanism is the same as in the very first IBM PC (hooray for compatibility; UEFI is a completely new and incompatible system, but old-school BIOS boot is still there), which is also why it's all so tiny and simple - the computer reads a single 512 byte block of data from the boot drive, loads it into _physical_ memory at address 0x7c00, checks that it has the "signature" (AA55) at the end, and points the CPU's instruction pointer to 0x7c00. That's it. No file systems, no processes, just a 512 B slab of code and data you can work with to actually proceed with the boot (or in this case, print a message and stop).
      This is _not_ a bootloader - not yet. It's just a tutorial on how to run a basic program from a bootsector on computer startup. But hey, it's "part 1" for a reason - we have to start somewhere :) An actual bootloader would prepare a few things, load the actual program/system (presumably from the same drive, which is why you get the drive number as one of the "inputs" here) and run it. There's a limit to what you can do with ~510 bytes of code and data :D

    • @we-are-electric1445
      @we-are-electric1445 2 หลายเดือนก่อน

      @@LuaanTi Thanks for the response. I will watch the remaining two videos before I ask any more questions !

  • @qandak
    @qandak 2 หลายเดือนก่อน

    Writing bootloader in VS Code (technically in a browser)... that's what we achieved so far 😕

    • @antoniopala8135
      @antoniopala8135 2 หลายเดือนก่อน

      Editors and IDEs have always been "bloated". Back in the 80s, programmers joked that EMACS actually meant "Eight Megabytes And Constantly Swapping"...

  • @bhupendrasinghsuri496
    @bhupendrasinghsuri496 หลายเดือนก่อน

    how to execute this on RHEL 9?

  • @milasudril
    @milasudril หลายเดือนก่อน

    Shouldn't there be an infinite loop at the end to prevent the system from continuing?

    • @jlewwis1995
      @jlewwis1995 หลายเดือนก่อน

      Thats what the hlt is there for, it freezes the cpu

  • @richardappow6770
    @richardappow6770 3 หลายเดือนก่อน +4

    please zoom in on the text editor

    • @CristiNeagu
      @CristiNeagu 2 หลายเดือนก่อน

      You know you can zoom in on the text editor yourself, right? Have you tried it?

    • @JulianGaming007
      @JulianGaming007 2 หลายเดือนก่อน

      ​@CristiNeagu true but I don't think you can do that on desktop

  • @goatedFool
    @goatedFool 3 หลายเดือนก่อน

    Nice 👍

  • @AnnatarTheMaia
    @AnnatarTheMaia 3 หลายเดือนก่อน

    Screw this, write a bootloader for SPARC!

  • @ryancabaneles
    @ryancabaneles 2 หลายเดือนก่อน

    do u have a github for that sir?

  • @HoSza1
    @HoSza1 2 หลายเดือนก่อน

    3 seconds into the video... hm he will use a VM indeed😂

  • @talha_coding_tutor
    @talha_coding_tutor หลายเดือนก่อน

    can you teach me assembly.... ?

  • @Karnikhil91
    @Karnikhil91 3 หลายเดือนก่อน

    Can u also tell for Embedded system? like Arduino , ESP......

    • @LuaanTi
      @LuaanTi 2 หลายเดือนก่อน +1

      Microcontrollers are usually programmed through flashing/burning. E.g. the Arduino Uno has an ATMega 328 microcontroller with integrated memory (both persistent and temporary). You put the program into that memory, and that's it.
      In contrast, the IBM PC was designed with extensibility in mind, so there's a "protocol" of how everything gets initialized, because it needs to work with a wide variety of software and hardware - that was the whole point of the PC (though of course IBM expected that the actual PC would only be made by them; instead, competitors quickly sprung up with compatible PCs and the rest is history :)). There's a little dance when the computer starts to make sure those basics are satisfied - the BIOS discovers memory, a boot disk, loads the boot sector from that disk to memory and sets the CPU to execute from there. That's what Part 1 here is all about - getting the BIOS to execute _our_ code from the boot drive.
      Of course, you _can_ have bootloaders with Arduino - but the bootloader is just flashed like any other program. The main point here is to make it faster to test new stuff - instead of having to flash the Arduino every time you need to test a change, the bootloader will e.g. load the program over a serial link. Arduino boards have a built-in bootloader that does just that. You usually don't deal with things like "loading programs from a hard drive" or "understanding a filesystem" in a microcontroller; though it's certainly possible, of course, the main draw of microcontrollers is that they're really simple and small.
      Of course, there are tons of notable "embedded" systems that work pretty much the same way as a PC, like your router or that Windows Embedded kiosk. That has little to do with practical programming of Arduinos, though :P

  • @Apathyy322
    @Apathyy322 3 หลายเดือนก่อน

    hi, nice video. but could you tell me how do you make your vm look so smooth?

    • @screeck
      @screeck  3 หลายเดือนก่อน +1

      I gave it 8GB ram and max video memory.

    • @Apathyy322
      @Apathyy322 3 หลายเดือนก่อน

      @@screeck i give mine 16 process, 256mb videomemory and 16gb ram and it lags so bad

    • @nguyenmanh466
      @nguyenmanh466 3 หลายเดือนก่อน

      @@Apathyy322 I think it depends more on how strong your CPU is

  • @Kunal-k-u-m-a-r
    @Kunal-k-u-m-a-r 2 หลายเดือนก่อน +1

    ACPI

  • @petrikko
    @petrikko 23 วันที่ผ่านมา

    are you from poland.? :-)

  • @Real-Name..Maqavoy
    @Real-Name..Maqavoy 2 หลายเดือนก่อน +2

    Not in this manner; *No*

  • @print-Ch1
    @print-Ch1 2 หลายเดือนก่อน

    make a video where you write a bootloader for arduino 😆

  • @rapaduraman3543
    @rapaduraman3543 3 หลายเดือนก่อน

    Hello my friend, make more vídeos please

  • @mbahmarijan789
    @mbahmarijan789 3 หลายเดือนก่อน

    I like your accent

  • @jacobswiney9977
    @jacobswiney9977 3 หลายเดือนก่อน

    Where is the last Jedi poster?

    • @screeck
      @screeck  3 หลายเดือนก่อน

      I don't like sequels :/

  • @atabac
    @atabac 3 หลายเดือนก่อน

    is osdev your only resource for learning this?

    • @screeck
      @screeck  3 หลายเดือนก่อน

      No, I just like it because it has all you need to start. I'm sure there is plenty more resources, blogs, books but I didn't check yet. There are also udemy courses, but they are paid of course

    • @atabac
      @atabac 3 หลายเดือนก่อน

      @@screeck can you recommend some?

    • @screeck
      @screeck  3 หลายเดือนก่อน +1

      I've heard that this book is very good: "Operating Systems: Three Easy Pieces"
      There is also www.viralpatel[.]net They have some OS related tutorials

    • @atabac
      @atabac 3 หลายเดือนก่อน

      @@screeck tnx man

    • @maxmuster7003
      @maxmuster7003 3 หลายเดือนก่อน +1

      Intel developer manual for 80286 CPU

  • @mbnqpl
    @mbnqpl 23 วันที่ผ่านมา

    I'm almost sure you're polish xD

  • @TerryBecker-bw1vx
    @TerryBecker-bw1vx 3 หลายเดือนก่อน

    Interested in fixing booting?
    No boot flag, and no MBR or sectors.
    All drives & comm. dev. boot.
    Set or search file: boot.lst

  • @ferroalloys594
    @ferroalloys594 หลายเดือนก่อน

    Didn't need three videos in 1978 to learn/understand, just a paper tape, a paper tape punch and a PDP8! Mega simples... ):-)

  • @TechTalk870
    @TechTalk870 3 หลายเดือนก่อน

    I just got booting from hard disk

  • @franciszek5831
    @franciszek5831 3 หลายเดือนก่อน +2

    Now, just do the tests on real hardware. FD/HDD/USB 🤭

    • @maxmuster7003
      @maxmuster7003 3 หลายเดือนก่อน +2

      bootable CD-ROM el torito format floppy emulation on Drive: A

    • @franciszek5831
      @franciszek5831 3 หลายเดือนก่อน +1

      @@maxmuster7003 Yes, booting PC from CDROM is probably the best solution these days.

  • @szymoniak75
    @szymoniak75 2 หลายเดือนก่อน

    siema

    • @screeck
      @screeck  2 หลายเดือนก่อน

      siema

  • @id1568
    @id1568 3 หลายเดือนก่อน

    wave more w/ you hands 0:32 off

  • @saultube44
    @saultube44 3 หลายเดือนก่อน

    I could be your dad, WTF?

    • @screeck
      @screeck  3 หลายเดือนก่อน

      😂

  • @esra_erimez
    @esra_erimez 3 หลายเดือนก่อน

    Do you realize that your posters are backwards?
    Laugh, I'm joking.

    • @screeck
      @screeck  3 หลายเดือนก่อน

      You almost made me check it lol

  • @CallousCoder
    @CallousCoder หลายเดือนก่อน

    And this is why Intel sucks! The amount of crap you need to do to get it into protected mode with linear addressing is idiotic. All other CPUs is just trivial. "If you have never used Makefile...." than you shouldn't be let near bare metal systems :)
    In bootloader size matters so you are better off doing xor ax,ax saves a byte ;)
    and cli clears the interrupt enable flag and sti sets the interrupt enable flag and depending on that flag interrupts are handled or not

  • @Nisha.B2
    @Nisha.B2 20 วันที่ผ่านมา

    #qution mume supari nikal ke bat karo 🚩🚩🚩🚩

  • @batvanio
    @batvanio 2 หลายเดือนก่อน

    Pretty useless and full of inaccuracies. To begin with, the first thing is not just two bits, but a transition instruction (JMP 003E or JMP 7C3E), because each boot sector has a table that you completely lack. For disks it is one type, for floppies another. I know from experience that what works on a virtual bow tie does not always work on a real one. I've tried making my own OS, not to replace one, but just out of curiosity if someone with poor assembly knowledge like me could make a working, albeit rudimentary, OS. In the end, I never finished it. It was in my native language, not English. Here it is from the link below.
    th-cam.com/video/y3e8ImJUoiE/w-d-xo.html

  • @paul-philippRosenjart
    @paul-philippRosenjart หลายเดือนก่อน

    Tired amateur writes a bootloader.

  • @roz1
    @roz1 3 หลายเดือนก่อน

    Don't leave the series in the middle

  • @ko._.0176
    @ko._.0176 3 หลายเดือนก่อน +1

    u deserve millions of subs for this , i wanna be your friend may I ask if you have discord?

    • @screeck
      @screeck  3 หลายเดือนก่อน

      Thanks bro